summaryrefslogtreecommitdiff
path: root/amadec/dsp/audiodsp-ctl.c (plain)
blob: 8d0a05c295179d698f75ba951305c8a0e0de2038
1/**
2 * \file audiodsp-ctl.c
3 * \brief Functions of Auduodsp control
4 * \version 1.0.0
5 * \date 2011-03-08
6 */
7/* Copyright (C) 2007-2011, Amlogic Inc.
8 * All right reserved
9 *
10 */
11#include <stdio.h>
12#include <stdlib.h>
13#include <fcntl.h>
14#include <string.h>
15#include <syslog.h>
16#include <unistd.h>
17#include <errno.h>
18#include <sys/ioctl.h>
19#include <sys/mman.h>
20
21#include <audio-dec.h>
22#include <audiodsp.h>
23#include <log-print.h>
24#include <cutils/properties.h>
25#include <amthreadpool.h>
26#include "Amsysfsutils.h"
27#include "amconfigutils.h"
28
29firmware_s_t firmware_list[] = {
30 {0, MCODEC_FMT_MPEG123, "audiodsp_codec_mad.bin"},
31 {1, MCODEC_FMT_AAC, "audiodsp_codec_aac_helix.bin"},
32 {2, MCODEC_FMT_AC3 | MCODEC_FMT_EAC3, "audiodsp_codec_ddp_dcv.bin"},
33 {3, MCODEC_FMT_DTS, "audiodsp_codec_dtshd.bin"},
34 {4, MCODEC_FMT_FLAC, "audiodsp_codec_flac.bin"},
35 {5, MCODEC_FMT_COOK, "audiodsp_codec_cook.bin"},
36 {6, MCODEC_FMT_AMR, "audiodsp_codec_amr.bin"},
37 {7, MCODEC_FMT_RAAC, "audiodsp_codec_raac.bin"},
38 {8, MCODEC_FMT_ADPCM, "audiodsp_codec_adpcm.bin"},
39 {9, MCODEC_FMT_WMA, "audiodsp_codec_wma.bin"},
40 {10, MCODEC_FMT_PCM, "audiodsp_codec_pcm.bin"},
41 {11, MCODEC_FMT_WMAPRO, "audiodsp_codec_wmapro.bin"},
42 {12, MCODEC_FMT_ALAC, "audiodsp_codec_alac.bin"},
43 {13, MCODEC_FMT_VORBIS, "audiodsp_codec_vorbis.bin"},
44 {14, MCODEC_FMT_AAC_LATM, "audiodsp_codec_aac.bin"},
45 {15, MCODEC_FMT_APE, "audiodsp_codec_ape.bin"},
46
47};
48
49/**
50 * \brief register audio firmware
51 * \param fd dsp handle
52 * \param fmt audio format
53 * \param name audio firmware name
54 * \return 0 on success otherwise negative error code
55 */
56static int register_firmware(int fd, int fmt, char *name)
57{
58 int ret;
59 audiodsp_cmd_t cmd;
60
61 cmd.cmd = AUDIODSP_REGISTER_FIRMWARE;
62 cmd.fmt = fmt;
63 cmd.data = name;
64 cmd.data_len = strlen(name);
65
66 ret = ioctl(fd, AUDIODSP_REGISTER_FIRMWARE, &cmd);
67
68 return ret;
69}
70
71/**
72 * \brief switch audio format
73 * \param fmt audio format
74 * \return new format on success otherwise zero
75 */
76static int switch_audiodsp(adec_audio_format_t fmt)
77{
78 switch (fmt) {
79 case ADEC_AUDIO_FORMAT_MPEG:
80 return MCODEC_FMT_MPEG123;
81
82 case ADEC_AUDIO_FORMAT_AAC_LATM:
83 return MCODEC_FMT_AAC_LATM;
84
85 case ADEC_AUDIO_FORMAT_AAC:
86 return MCODEC_FMT_AAC;
87
88 case ADEC_AUDIO_FORMAT_AC3:
89 return MCODEC_FMT_AC3;
90 case ADEC_AUDIO_FORMAT_EAC3:
91 return MCODEC_FMT_EAC3;
92
93 case ADEC_AUDIO_FORMAT_DTS:
94 return MCODEC_FMT_DTS;
95
96 case ADEC_AUDIO_FORMAT_FLAC:
97 return MCODEC_FMT_FLAC;
98
99 case ADEC_AUDIO_FORMAT_COOK:
100 return MCODEC_FMT_COOK;
101
102 case ADEC_AUDIO_FORMAT_AMR:
103 return MCODEC_FMT_AMR;
104
105 case ADEC_AUDIO_FORMAT_RAAC:
106 return MCODEC_FMT_RAAC;
107
108 case ADEC_AUDIO_FORMAT_ADPCM:
109 return MCODEC_FMT_ADPCM;
110
111 case ADEC_AUDIO_FORMAT_PCM_S16BE:
112 case ADEC_AUDIO_FORMAT_PCM_S16LE:
113 case ADEC_AUDIO_FORMAT_PCM_U8:
114 case ADEC_AUDIO_AFORMAT_PCM_BLURAY:
115 case ADEC_AUDIO_FORMAT_PCM_WIFIDISPLAY:
116 return MCODEC_FMT_PCM;
117
118 case ADEC_AUDIO_FORMAT_WMA:
119 return MCODEC_FMT_WMA;
120
121 case ADEC_AUDIO_FORMAT_WMAPRO:
122 return MCODEC_FMT_WMAPRO;
123 case ADEC_AUDIO_AFORMAT_ALAC:
124 return MCODEC_FMT_ALAC;
125 case ADEC_AUDIO_AFORMAT_VORBIS:
126 return MCODEC_FMT_VORBIS;
127 case ADEC_AUDIO_FORMAT_APE:
128 return MCODEC_FMT_APE;
129 default:
130 return 0;
131 }
132}
133
134/**
135 * \brief find audio firmware through audio format
136 * \param fmt audio format
137 * \return firmware_s struct otherwise null
138 */
139static firmware_s_t * find_firmware_by_fmt(int m_fmt)
140{
141 int i;
142 int num;
143 firmware_s_t *f;
144
145 num = ARRAY_SIZE(firmware_list);
146
147 for (i = 0; i < num; i++) {
148 f = &firmware_list[i];
149 if (f->fmt & m_fmt) {
150 return f;
151 }
152 }
153
154 return NULL;
155}
156
157
158/**
159 * \brief init audiodsp
160 * \param dsp_ops pointer to dsp operation struct
161 * \return 0 on success otherwise -1 if an error occurred
162 */
163int audiodsp_init(dsp_operations_t *dsp_ops)
164{
165 int i;
166 int fd = -1;
167 int num;
168 int ret;
169 firmware_s_t *f;
170
171 num = ARRAY_SIZE(firmware_list);
172
173 if (dsp_ops->dsp_file_fd < 0) {
174 fd = open(DSP_DEV_NOD, O_RDONLY, 0644);
175 }
176
177 if (fd < 0) {
178 adec_print("unable to open audio dsp %s,err: %s", DSP_DEV_NOD, strerror(errno));
179 return -1;
180 }
181 ioctl(fd, AUDIODSP_UNREGISTER_ALLFIRMWARE, 0);
182 for (i = 0; i < num; i++) {
183 f = &firmware_list[i];
184 ret = register_firmware(fd, f->fmt, f->name);
185 if (ret != 0) {
186 adec_print("register firmware error=%d,fmt:%d,name:%s\n", ret, f->fmt, f->name);
187 }
188 }
189 if (i > 0) {
190 ret = 0; //ignore the some fmt register error,for compatible some old kernel.can't support muti filename,
191 }
192 if (ret != 0) {
193 close(fd);
194
195 }
196
197 dsp_ops->dsp_file_fd = fd;
198
199 return ret;
200}
201
202/**
203 * \brief start audiodsp
204 * \param dsp_ops pointer to dsp operation struct
205 * \return 0 on success otherwise negative code error
206 */
207static err_count = 0;
208
209#define PARSER_WAIT_MAX 100
210int audiodsp_start(aml_audio_dec_t *audec)
211{
212 int m_fmt;
213 int ret = -1;
214 unsigned long val;
215 dsp_operations_t *dsp_ops = &audec->adsp_ops;
216
217 if (dsp_ops->dsp_file_fd < 0) {
218 return -1;
219 }
220
221 if (am_getconfig_bool("media.libplayer.wfd")) {
222 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_SET_PCM_BUF_SIZE, 8 * 1024);
223 } else {
224 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_SET_PCM_BUF_SIZE, 32 * 1024);
225 }
226
227 m_fmt = switch_audiodsp(audec->format);
228 adec_print("[%s:%d] audio_fmt=%d\n", __FUNCTION__, __LINE__, m_fmt);
229
230 if (find_firmware_by_fmt(m_fmt) == NULL) {
231 return -2;
232 }
233
234 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_SET_FMT, m_fmt);
235
236 ret = ioctl(dsp_ops->dsp_file_fd, AUDIODSP_START, 0);
237 if (ret != 0) {
238 return -3;
239 }
240
241 if (audec->need_stop) { //in case stop command comes now
242 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_STOP, 0);
243 return -5;
244 }
245
246 ret = ioctl(dsp_ops->dsp_file_fd, AUDIODSP_DECODE_START, 0);
247 err_count = 0;
248 if (ret == 0) {
249 do {
250 ret = ioctl(dsp_ops->dsp_file_fd, AUDIODSP_WAIT_FORMAT, 0);
251 if (ret != 0 && !audec->need_stop) {
252 err_count++;
253 amthreadpool_thread_usleep(1000 * 20);
254 if (err_count > PARSER_WAIT_MAX) {
255 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_STOP, 0);//audiodsp_start failed,should stop audiodsp
256 adec_print("[%s:%d] audio dsp not ready for decode PCM in 2s\n", __FUNCTION__, __LINE__);
257 return -4;
258 }
259 }
260 } while (!audec->need_stop && (ret != 0));
261 }
262
263 if (ret != 0) {
264 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_STOP, 0);//audiodsp_start failed,should stop audiodsp
265 return -4;
266 }
267
268 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_CHANNELS_NUM, &val);
269 if (val != (unsigned long) - 1) {
270 audec->channels = val;
271 }
272
273 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_SAMPLERATE, &val);
274 if (val != (unsigned long) - 1) {
275 audec->samplerate = val;
276 }
277
278 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_BITS_PER_SAMPLE, &val);
279 if (val != (unsigned long) - 1) {
280 audec->data_width = val;
281 }
282 adec_print("channels == %d, samplerate == %d\n", audec->channels, audec->samplerate);
283 return ret;
284}
285
286/**
287 * \brief stop audiodsp
288 * \param dsp_ops pointer to dsp operation struct
289 * \return 0 on success otherwise -1 if an error occurred
290 */
291int audiodsp_stop(dsp_operations_t *dsp_ops)
292{
293 int ret;
294
295 if (dsp_ops->dsp_file_fd < 0) {
296 return -1;
297 }
298
299 ret = ioctl(dsp_ops->dsp_file_fd, AUDIODSP_STOP, 0);
300
301 return ret;
302}
303
304/**
305 * \brief release audiodsp
306 * \param dsp_ops pointer to dsp operation struct
307 * \return 0 on success otherwise -1 if an error occurred
308 */
309int audiodsp_release(dsp_operations_t *dsp_ops)
310{
311 if (dsp_ops->dsp_file_fd < 0) {
312 return -1;
313 }
314
315 close(dsp_ops->dsp_file_fd);
316
317 dsp_ops->dsp_file_fd = -1;
318
319 return 0;
320}
321
322/**
323 * \brief read pcm data from audiodsp
324 * \param dsp_ops pointer to dsp operation struct
325 * \param buffer point to buffer where storing pcm data
326 * \param size read data length
327 * \return the number of bytes read
328 */
329int audiodsp_stream_read(dsp_operations_t *dsp_ops, char *buffer, int size)
330{
331 if (dsp_ops->dsp_file_fd < 0) {
332 adec_print("read error!! audiodsp have not opened\n");
333 return 0;
334 }
335
336 return read(dsp_ops->dsp_file_fd, buffer, size);
337}
338
339/**
340 * \brief get current audio pts
341 * \param dsp_ops pointer to dsp operation struct
342 * \return current audio pts otherwise -1 if an error occurred
343 */
344unsigned long audiodsp_get_pts(dsp_operations_t *dsp_ops)
345{
346 unsigned long val;
347
348 if (dsp_ops->dsp_file_fd < 0) {
349 adec_print("read error!! audiodsp have not opened\n");
350 return -1;
351 }
352
353 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_PTS, &val);
354
355 return val;
356}
357
358/**
359 * \brief get current audio pcrscr
360 * \param dsp_ops pointer to dsp operation struct
361 * \return current audio pcrscr otherwise -1 if an error occurred
362 */
363unsigned long audiodsp_get_pcrscr(dsp_operations_t *dsp_ops)
364{
365 unsigned long val;
366
367 if (dsp_ops->dsp_file_fd < 0) {
368 adec_print("read error!! audiodsp have not opened\n");
369 return -1;
370 }
371
372 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_SYNC_GET_PCRSCR, &val);
373
374 return val;
375}
376/**
377 * \brief set current audio pts
378 * \param dsp_ops pointer to dsp operation struct
379 * \return 0 on success otherwise -1 if an error occurred
380 */
381int audiodsp_set_apts(dsp_operations_t *dsp_ops, unsigned long apts)
382{
383
384 if (dsp_ops->dsp_file_fd < 0) {
385 adec_print("read error!! audiodsp have not opened\n");
386 return -1;
387 }
388
389 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_SYNC_SET_APTS, &apts);
390
391 return 0;
392}
393/**
394 * \brief get decoded audio frame number
395 * \param dsp_ops pointer to dsp operation struct
396 * \return audiodsp decoded frame number, -1 if an error occurred
397 */
398int audiodsp_get_decoded_nb_frames(dsp_operations_t *dsp_ops)
399{
400 int val = -1;
401 if (dsp_ops && dsp_ops->dsp_file_fd) {
402 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_DECODED_NB_FRAMES, &val);
403 }
404 //adec_print("get audio decoded frame number==%d\n",val);
405 return val;
406}
407
408int audiodsp_get_first_pts_flag(dsp_operations_t *dsp_ops)
409{
410 int val;
411
412 if (dsp_ops->dsp_file_fd < 0) {
413 adec_print("read error!! audiodsp have not opened\n");
414 return -1;
415 }
416
417 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_FIRST_PTS_FLAG, &val);
418
419 return val;
420}
421
422int audiodsp_automute_on(dsp_operations_t *dsp_ops)
423{
424 int ret;
425
426 if (dsp_ops->dsp_file_fd < 0) {
427 adec_print("read error!! audiodsp have not opened\n");
428 return -1;
429 }
430
431 ret = ioctl(dsp_ops->dsp_file_fd, AUDIODSP_AUTOMUTE_ON, 0);
432
433 return ret;
434}
435
436int audiodsp_automute_off(dsp_operations_t *dsp_ops)
437{
438 int ret;
439
440 if (dsp_ops->dsp_file_fd < 0) {
441 adec_print("read error!! audiodsp have not opened\n");
442 return -1;
443 }
444
445 ret = ioctl(dsp_ops->dsp_file_fd, AUDIODSP_AUTOMUTE_OFF, 0);
446
447 return ret;
448}
449
450
451int audiodsp_get_pcm_level(dsp_operations_t* dsp_ops)
452{
453 int val = 0;
454 if (dsp_ops->dsp_file_fd < 0) {
455 adec_print("read error !! audiodsp have not opened\n");
456 return -1;
457 }
458
459 ioctl(dsp_ops->dsp_file_fd, AUDIODSP_GET_PCM_LEVEL, &val);
460 return val;
461}
462
463int audiodsp_set_skip_bytes(dsp_operations_t* dsp_ops, unsigned int bytes)
464{
465 if (dsp_ops->dsp_file_fd < 0) {
466 adec_print("read error !! audiodsp have not opened\n");
467 return -1;
468 }
469
470 return ioctl(dsp_ops->dsp_file_fd, AUDIODSP_SKIP_BYTES, bytes);
471}
472