1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4 #include "sound_pcm.h"
5 #include "ulog/ulog.h"
6
7 #define LOG_TAG "[sound_pcm]"
8 #define PCM_LOCK(pcm) aos_mutex_lock(&pcm->mutex, AOS_WAIT_FOREVER)
9 #define PCM_UNLOCK(pcm) aos_mutex_unlock(&pcm->mutex)
10 #define PCM_RETURN_ERR -1
11 #define PCM_RETURN_SUCCESS 0
12
13
aos_device_name_hint(int card,void * hints)14 int aos_device_name_hint(int card, void *hints)
15 {
16 int i = 0, j = 0, fd = -1;
17 char fn[256];
18 hint_list_t *node = NULL;
19
20 if(card == -1) {
21 for(i = 0; i < AOS_SNDCARD_NUM_MAX; i++) {
22 for(j = 0; j < AOS_SNDCARD_DEVICE_NUM_MAX; j++) {
23 memset(fn, 0, sizeof(fn));
24 snprintf(fn, sizeof(fn), "/dev/pcmC%uD%u%c", i, j, 'p');
25 fd = open(fn, O_RDWR|O_NONBLOCK);
26 if (fd > 0) {
27 node = (hint_list_t *)calloc(1, sizeof(hint_list_t));
28 if(!node) {
29 return -ENOMEM;
30 }
31 hints = (void *)node;
32 node->card = i;
33 node->device = j;
34 strncpy(node->name, fn, sizeof(node->name));
35 close(fd);
36 LOGD(LOG_TAG, "%s:%d, found sound card %d device %d %s", __func__, __LINE__, i, j, node->name);
37 return PCM_RETURN_SUCCESS;
38 }
39 }
40 }
41 } else {
42 for(j = 0; j < AOS_SNDCARD_DEVICE_NUM_MAX; j++) {
43 memset(fn, 0, sizeof(fn));
44 snprintf(fn, sizeof(fn), "/dev/pcmC%uD%u%c", card, j, 'p');
45 fd = open(fn, O_RDWR|O_NONBLOCK);
46 if (fd > 0) {
47 node = (hint_list_t *)calloc(1, sizeof(hint_list_t));
48 if(!node) {
49 return -ENOMEM;
50 }
51 hints = (void *)node;
52 node->card = card;
53 node->device = j;
54 strncpy(node->name, fn, sizeof(node->name));
55 close(fd);
56 LOGD(LOG_TAG, "%s:%d, found sound card %d device %d %s", __func__, __LINE__, card, j, node->name);
57 return PCM_RETURN_SUCCESS;
58 }
59 }
60 }
61 LOGE(LOG_TAG, "%s:%d, found no sound device ", __func__, __LINE__);
62 return PCM_RETURN_ERR;
63 }
64
aos_pcm_open(aos_pcm_t ** pcm,const char * name,aos_pcm_stream_t stream,int mode)65 int aos_pcm_open(aos_pcm_t **pcm, const char *name, aos_pcm_stream_t stream, int mode)
66 {
67 int card = 0, device = 0, fd = -1;
68 char fn[256];
69 if(!name) {
70 LOGE(LOG_TAG, "%s:%d, param name is null", __func__, __LINE__);
71 return PCM_RETURN_ERR;
72 }
73 *pcm = (aos_pcm_t *)calloc(1, sizeof(aos_pcm_t));
74 if(NULL == *pcm) {
75 LOGE(LOG_TAG, "%s:%d, calloc aos_pcm_t failed", __func__, __LINE__);
76 return -ENOMEM;
77 }
78 memset(*pcm, 0, sizeof(aos_pcm_t));
79 if(!strcmp(name, "default")) {
80 for(card = 0; card < AOS_SNDCARD_NUM_MAX; card++) {
81 for(device = 0; device < AOS_SNDCARD_DEVICE_NUM_MAX; device++) {
82 memset(fn, 0, sizeof(fn));
83 snprintf(fn, sizeof(fn), "/dev/pcmC%uD%u%c", card, device, (stream == AOS_PCM_STREAM_PLAYBACK) ? 'p' : 'c');
84 fd = open(fn, O_RDWR|O_NONBLOCK);
85 if (fd > 0) {
86 (*pcm)->fd = fd;
87 (*pcm)->card = card;
88 (*pcm)->device = device;
89 (*pcm)->name = strdup(fn);
90 (*pcm)->stream = stream;
91 (*pcm)->mode = mode;
92 (*pcm)->state = AOS_PCM_STATE_OPEN;
93 aos_mutex_new(&((*pcm)->mutex));
94 aos_event_new(&((*pcm)->evt), 0);
95 LOGD(LOG_TAG, "%s:%d, open card %d device %d successfully", __func__, __LINE__, card, device);
96 return PCM_RETURN_SUCCESS;
97 }
98 }
99 }
100 } else {
101 for(card = 0; card < AOS_SNDCARD_NUM_MAX; card++) {
102 for(device = 0; device < AOS_SNDCARD_DEVICE_NUM_MAX; device++) {
103 memset(fn, 0, sizeof(fn));
104 snprintf(fn, sizeof(fn), "/dev/pcmC%uD%u%c", card, device, (stream == AOS_PCM_STREAM_PLAYBACK) ? 'p' : 'c');
105 if(!strcmp(name, fn)) {
106 fd = open(fn, O_RDWR|O_NONBLOCK);
107 if (fd > 0) {
108 (*pcm)->fd = fd;
109 (*pcm)->card = card;
110 (*pcm)->device = device;
111 (*pcm)->name = strdup(fn);
112 (*pcm)->stream = stream;
113 (*pcm)->mode = mode;
114 (*pcm)->state = AOS_PCM_STATE_OPEN;
115 aos_mutex_new(&((*pcm)->mutex));
116 aos_event_new(&((*pcm)->evt), 0);
117 LOGD(LOG_TAG, "%s:%d, open card %d device %d successfully", __func__, __LINE__, card, device);
118 return PCM_RETURN_SUCCESS;
119 }
120 }
121 }
122 }
123 }
124 LOGE(LOG_TAG, "%s:%d, open %s device failed", __func__, __LINE__, (stream == AOS_PCM_STREAM_PLAYBACK) ? "playback" : "capture");
125 free(*pcm);
126 *pcm = NULL;
127 return PCM_RETURN_ERR;
128 }
129
aos_pcm_prepare(aos_pcm_t * pcm)130 int aos_pcm_prepare(aos_pcm_t *pcm)
131 {
132 int ret = PCM_RETURN_SUCCESS;
133 if(NULL == pcm) {
134 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
135 return PCM_RETURN_ERR;
136 }
137 if(pcm->fd < 0) {
138 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
139 return PCM_RETURN_ERR;
140 }
141 PCM_LOCK(pcm);
142 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_PREPARE)) {
143 LOGE(LOG_TAG, "%s:%d, ioctl prepare failed", __func__, __LINE__);
144 ret = PCM_RETURN_ERR;
145 } else {
146 pcm->state = AOS_PCM_STATE_PREPARED;
147 }
148 PCM_UNLOCK(pcm);
149 return ret;
150 }
151
aos_pcm_start(aos_pcm_t * pcm)152 int aos_pcm_start(aos_pcm_t *pcm)
153 {
154 int ret = PCM_RETURN_SUCCESS;
155 if(NULL == pcm) {
156 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
157 return PCM_RETURN_ERR;
158 }
159 if(pcm->fd < 0) {
160 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
161 return PCM_RETURN_ERR;
162 }
163 PCM_LOCK(pcm);
164 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_START)) {
165 LOGE(LOG_TAG, "%s:%d, ioctl start failed", __func__, __LINE__);
166 ret = PCM_RETURN_ERR;
167 } else {
168 pcm->state = AOS_PCM_STATE_RUNNING;
169 }
170 PCM_UNLOCK(pcm);
171 return ret;
172 }
173
aos_pcm_wait(aos_pcm_t * pcm,int timeout)174 int aos_pcm_wait(aos_pcm_t *pcm, int timeout)
175 {
176 int ret = PCM_RETURN_SUCCESS;
177 unsigned int actl_flags = 0;
178 if(NULL == pcm) {
179 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
180 return PCM_RETURN_ERR;
181 }
182 if(pcm->fd < 0) {
183 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
184 return PCM_RETURN_ERR;
185 }
186 PCM_LOCK(pcm);
187 aos_event_get(&pcm->evt, AOS_PCM_EVT_READ | AOS_PCM_EVT_XRUN, AOS_EVENT_OR_CLEAR, &actl_flags, timeout);
188 PCM_UNLOCK(pcm);
189
190 if (actl_flags & AOS_EVENT_OR_CLEAR) {
191 LOGE(LOG_TAG,"PCM_EVT_XRUN");
192 return -EPIPE;
193 }
194
195 return ret; // TBD 2x : ret value + evt to driver
196 }
197
aos_pcm_stop(aos_pcm_t * pcm)198 int aos_pcm_stop(aos_pcm_t *pcm)
199 {
200 int ret = PCM_RETURN_SUCCESS;
201 if(NULL == pcm) {
202 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
203 return PCM_RETURN_ERR;
204 }
205 if(pcm->fd < 0) {
206 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
207 return PCM_RETURN_ERR;
208 }
209 PCM_LOCK(pcm);
210 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_DROP)) {
211 LOGE(LOG_TAG, "%s:%d, ioctl drop failed", __func__, __LINE__);
212 ret = PCM_RETURN_ERR;
213 } else {
214 pcm->state = AOS_PCM_STATE_PAUSED;
215 }
216 PCM_UNLOCK(pcm);
217 return ret;
218 }
219
aos_pcm_drain(aos_pcm_t * pcm)220 int aos_pcm_drain(aos_pcm_t *pcm)
221 {
222 int ret = PCM_RETURN_SUCCESS;
223 if(NULL == pcm) {
224 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
225 return PCM_RETURN_ERR;
226 }
227 if(pcm->fd < 0) {
228 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
229 return PCM_RETURN_ERR;
230 }
231 PCM_LOCK(pcm);
232 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_DRAIN)) {
233 LOGE(LOG_TAG, "%s:%d, ioctl drain failed", __func__, __LINE__);
234 ret = PCM_RETURN_ERR;
235 }
236 PCM_UNLOCK(pcm);
237 return ret;
238 }
239
aos_pcm_pause(aos_pcm_t * pcm,int enable)240 int aos_pcm_pause(aos_pcm_t *pcm, int enable)
241 {
242 int ret = PCM_RETURN_SUCCESS;
243 if(NULL == pcm) {
244 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
245 return PCM_RETURN_ERR;
246 }
247 if(pcm->fd < 0) {
248 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
249 return PCM_RETURN_ERR;
250 }
251 PCM_LOCK(pcm);
252 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_PAUSE, enable)) {
253 LOGE(LOG_TAG, "%s:%d, ioctl pause failed", __func__, __LINE__);
254 ret = PCM_RETURN_ERR;
255 }
256 PCM_UNLOCK(pcm);
257 return ret;
258 }
259
aos_pcm_close(aos_pcm_t * pcm)260 int aos_pcm_close(aos_pcm_t *pcm)
261 {
262 int ret = PCM_RETURN_SUCCESS;
263 if(NULL == pcm) {
264 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
265 return PCM_RETURN_ERR;
266 }
267 if(pcm->fd < 0) {
268 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
269 return PCM_RETURN_ERR;
270 }
271 PCM_LOCK(pcm);
272 if(close(pcm->fd)) {
273 LOGE(LOG_TAG, "%s:%d, close pcm failed", __func__, __LINE__);
274 ret = PCM_RETURN_ERR;
275 }
276 if(pcm->name) {
277 free(pcm->name);
278 }
279 if(pcm->open_func) {
280 free(pcm->open_func);
281 }
282 if(pcm->private_data) {
283 free(pcm->private_data);
284 }
285 if(pcm->hw_params) {
286 free(pcm->hw_params);
287 }
288 if(pcm->sw_params) {
289 free(pcm->sw_params);
290 }
291 PCM_UNLOCK(pcm);
292 free(pcm);
293 return ret;
294 }
295
aos_pcm_recover(aos_pcm_t * pcm)296 int aos_pcm_recover(aos_pcm_t *pcm)
297 {
298 int ret = PCM_RETURN_SUCCESS;
299 if(NULL == pcm) {
300 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
301 return PCM_RETURN_ERR;
302 }
303 if(pcm->fd < 0) {
304 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
305 return PCM_RETURN_ERR;
306 }
307 PCM_LOCK(pcm);
308 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_RECOVER)) {
309 LOGE(LOG_TAG, "%s:%d, ioctl recover failed", __func__, __LINE__);
310 ret = PCM_RETURN_ERR;
311 }
312 PCM_UNLOCK(pcm);
313 return ret;
314 }
315
aos_pcm_suspend(aos_pcm_t * pcm)316 int aos_pcm_suspend(aos_pcm_t *pcm)
317 {
318 int ret = PCM_RETURN_SUCCESS;
319 if(NULL == pcm) {
320 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
321 return PCM_RETURN_ERR;
322 }
323 if(pcm->fd < 0) {
324 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
325 return PCM_RETURN_ERR;
326 }
327 PCM_LOCK(pcm);
328 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_SUSPEND)) {
329 LOGE(LOG_TAG, "%s:%d, ioctl suspend failed", __func__, __LINE__);
330 ret = PCM_RETURN_ERR;
331 }
332 PCM_UNLOCK(pcm);
333 return ret;
334 }
335
aos_pcm_resume(aos_pcm_t * pcm)336 int aos_pcm_resume(aos_pcm_t *pcm)
337 {
338 int ret = PCM_RETURN_SUCCESS;
339 if(NULL == pcm) {
340 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
341 return PCM_RETURN_ERR;
342 }
343 if(pcm->fd < 0) {
344 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
345 return PCM_RETURN_ERR;
346 }
347 PCM_LOCK(pcm);
348 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_RESUME)) {
349 LOGE(LOG_TAG, "%s:%d, ioctl resume failed", __func__, __LINE__);
350 ret = PCM_RETURN_ERR;
351 }
352 PCM_UNLOCK(pcm);
353 return ret;
354 }
355
aos_pcm_hw_params_alloca(aos_pcm_hw_params_t ** p)356 int aos_pcm_hw_params_alloca(aos_pcm_hw_params_t **p)
357 {
358 *p = (aos_pcm_hw_params_t *)calloc(1, sizeof(aos_pcm_hw_params_t));
359 if(NULL == *p) {
360 LOGE(LOG_TAG, "%s:%d, calloc aos_pcm_hw_params_t failed", __func__, __LINE__);
361 return -ENOMEM;
362 }
363 return PCM_RETURN_SUCCESS;
364 }
365
aos_pcm_hw_params_any(aos_pcm_hw_params_t * params)366 int aos_pcm_hw_params_any(aos_pcm_hw_params_t *params)
367 {
368 if(!params) {
369 return PCM_RETURN_ERR;
370 }
371 params->access = AOS_PCM_ACCESS_RW_INTERLEAVED;
372 params->format = AOSRV_PCM_FORMAT_S16_LE;
373 params->channels = 2;
374 params->rate = 16000;
375 params->sample_bits = (params->format * 8);
376 params->frame_bits = (params->format * params->channels * 8);
377 return PCM_RETURN_SUCCESS;
378 }
379
aos_pcm_hw_params(aos_pcm_t * pcm,aos_pcm_hw_params_t * p)380 int aos_pcm_hw_params(aos_pcm_t *pcm, aos_pcm_hw_params_t *p)
381 {
382 int ret = PCM_RETURN_SUCCESS;
383 audio_hw_params_t params;
384 if(NULL == pcm) {
385 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
386 return PCM_RETURN_ERR;
387 }
388 if(pcm->fd < 0) {
389 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
390 return PCM_RETURN_ERR;
391 }
392 if(p && pcm->hw_params) {
393 memcpy(pcm->hw_params, p, sizeof(aos_pcm_hw_params_t));
394 }
395 PCM_LOCK(pcm);
396 params.block = (pcm->mode & AOS_PCM_NONBLOCK) ? 0 : 1;
397 params.interleave = (p->access == AOS_PCM_ACCESS_RW_NONINTERLEAVED) ? 0 : 1;
398 params.channels = p->channels;
399 params.rate = p->rate;
400 params.sample_bits = p->format * 8;
401 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_HW_PARAMS, ¶ms)) {
402 LOGE(LOG_TAG, "%s:%d, cannot set hw params", __func__, __LINE__);
403 ret = PCM_RETURN_ERR;
404 }
405 PCM_UNLOCK(pcm);
406 LOGD(LOG_TAG, "%s:%d, block %d, interleave %d, rate %d channels %d bits %d", __func__, __LINE__, params.block,
407 params.interleave, params.rate, params.channels, params.sample_bits);
408 return ret;
409 }
410
aos_pcm_sw_params_any(aos_pcm_sw_params_t * params)411 int aos_pcm_sw_params_any(aos_pcm_sw_params_t *params)
412 {
413 if(!params) {
414 return PCM_RETURN_ERR;
415 }
416 params->period_step = 20; // 20ms period by default
417 return PCM_RETURN_SUCCESS;
418 }
419
aos_pcm_sw_params_alloca(aos_pcm_sw_params_t ** p)420 int aos_pcm_sw_params_alloca(aos_pcm_sw_params_t **p)
421 {
422 *p = (aos_pcm_sw_params_t *)calloc(1, sizeof(aos_pcm_sw_params_t));
423 if(NULL == *p) {
424 LOGE(LOG_TAG, "%s:%d, calloc aos_pcm_sw_params_t failed", __func__, __LINE__);
425 return -ENOMEM;
426 }
427 return PCM_RETURN_SUCCESS;
428 }
429
aos_pcm_sw_params(aos_pcm_t * pcm,aos_pcm_sw_params_t * p)430 int aos_pcm_sw_params(aos_pcm_t *pcm, aos_pcm_sw_params_t *p)
431 {
432 int ret = PCM_RETURN_SUCCESS;
433 audio_sw_params_t params;
434 if(NULL == pcm) {
435 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
436 return PCM_RETURN_ERR;
437 }
438 if(pcm->fd < 0) {
439 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
440 return PCM_RETURN_ERR;
441 }
442 if(pcm->sw_params && p) {
443 pcm->sw_params->period_step = p->period_step;
444 } else {
445 LOGE(LOG_TAG, "%s:%d, invalid pcm->sw_params or p", __func__, __LINE__);
446 return PCM_RETURN_ERR;
447 }
448 PCM_LOCK(pcm);
449 params.hdl = &pcm->evt;
450 params.period = p->period_step;
451 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_SW_PARAMS, ¶ms)) {
452 LOGE(LOG_TAG, "%s:%d, cannot set sw params", __func__, __LINE__);
453 ret = PCM_RETURN_ERR;
454 }
455 PCM_UNLOCK(pcm);
456 return ret;
457 }
458
aos_pcm_set_params(aos_pcm_t * pcm,aos_pcm_format_t format,aos_pcm_access_t access,unsigned int channels,unsigned int rate,int soft_resample,unsigned int latency)459 int aos_pcm_set_params(aos_pcm_t *pcm, aos_pcm_format_t format, aos_pcm_access_t access, unsigned int channels,
460 unsigned int rate, int soft_resample, unsigned int latency)
461 {
462 int ret = PCM_RETURN_SUCCESS;
463 audio_hw_params_t params;
464 if(NULL == pcm) {
465 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
466 return PCM_RETURN_ERR;
467 }
468 if(pcm->fd < 0) {
469 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
470 return PCM_RETURN_ERR;
471 }
472 if (!pcm->hw_params) {
473 pcm->hw_params = aos_zalloc(sizeof(aos_pcm_hw_params_t));
474
475 if (pcm->hw_params == NULL) {
476 return PCM_RETURN_ERR;
477 }
478 }
479 pcm->hw_params->access = access;
480 pcm->hw_params->channels = channels;
481 pcm->hw_params->format = format;
482 pcm->hw_params->rate = rate;
483 pcm->hw_params->sample_bits = format * 8;
484 pcm->hw_params->frame_bits = format * 8 * channels;
485
486 params.block = (pcm->mode & AOS_PCM_NONBLOCK) ? 0 : 1;
487 params.interleave = (access == AOS_PCM_ACCESS_RW_NONINTERLEAVED) ? 0 : 1;
488 params.channels = channels;
489 params.rate = rate;
490 switch(format) {
491 case AOSRV_PCM_FORMAT_S8:
492 params.sample_bits = 8;
493 break;
494 case AOSRV_PCM_FORMAT_S16_LE:
495 params.sample_bits = 16;
496 break;
497 case AOSRV_PCM_FORMAT_S24_LE:
498 params.sample_bits = 24;
499 break;
500 case AOSRV_PCM_FORMAT_S32_LE:
501 params.sample_bits = 32;
502 break;
503 default:
504 return PCM_RETURN_ERR;
505 }
506 PCM_LOCK(pcm);
507 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_HW_PARAMS, ¶ms)) {
508 LOGE(LOG_TAG, "%s:%d, cannot set hw params", __func__, __LINE__);
509 ret = PCM_RETURN_ERR;
510 }
511 PCM_UNLOCK(pcm);
512 LOGD(LOG_TAG, "%s:%d, block %d, interleave %d, rate %d channels %d bits %d", __func__, __LINE__, params.block,
513 params.interleave, params.rate, params.channels, params.sample_bits);
514 return ret;
515 }
516
aos_pcm_writei(aos_pcm_t * pcm,const void * buffer,aos_pcm_uframes_t size)517 aos_pcm_sframes_t aos_pcm_writei(aos_pcm_t *pcm, const void *buffer, aos_pcm_uframes_t size)
518 {
519 audio_xferi_t x;
520 if(NULL == pcm) {
521 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
522 return PCM_RETURN_ERR;
523 }
524 if(pcm->fd < 0) {
525 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
526 return PCM_RETURN_ERR;
527 }
528 if(pcm->state != AOS_PCM_STATE_RUNNING) {
529 LOGE(LOG_TAG, "%s:%d, unexpected pcm state %d", __func__, __LINE__, pcm->state);
530 return PCM_RETURN_ERR;
531 }
532 if(pcm->stream != AOS_PCM_STREAM_PLAYBACK) {
533 LOGE(LOG_TAG, "%s:%d, not playback device", __func__, __LINE__);
534 return PCM_RETURN_ERR;
535 }
536 PCM_LOCK(pcm);
537 x.buf = (void*)buffer;
538 x.frames = size;
539 x.result = 0;
540 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_WRITEI_FRAMES, &x)) {
541 LOGE(LOG_TAG, "%s:%d, ioctl writei failed", __func__, __LINE__);
542 }
543 PCM_UNLOCK(pcm);
544 //LOGE(LOG_TAG, "%s:%d, frames %d result %d", __func__, __LINE__, x.frames, x.result);
545 return x.result;
546 }
547
aos_pcm_writen(aos_pcm_t * pcm,void ** bufs,aos_pcm_uframes_t size)548 aos_pcm_sframes_t aos_pcm_writen(aos_pcm_t *pcm, void **bufs, aos_pcm_uframes_t size)
549 {
550 audio_xfern_t x;
551 if(NULL == pcm) {
552 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
553 return PCM_RETURN_ERR;
554 }
555 if(pcm->fd < 0) {
556 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
557 return PCM_RETURN_ERR;
558 }
559 if(pcm->state != AOS_PCM_STATE_RUNNING) {
560 LOGE(LOG_TAG, "%s:%d, unexpected pcm state %d", __func__, __LINE__, pcm->state);
561 return PCM_RETURN_ERR;
562 }
563 if(pcm->stream != AOS_PCM_STREAM_PLAYBACK) {
564 LOGE(LOG_TAG, "%s:%d, not playback device", __func__, __LINE__);
565 return PCM_RETURN_ERR;
566 }
567 PCM_LOCK(pcm);
568 x.bufs = bufs;
569 x.frames = size;
570 x.result = 0;
571 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_WRITEN_FRAMES, &x)) {
572 LOGE(LOG_TAG, "%s:%d, ioctl writen failed", __func__, __LINE__);
573 }
574 PCM_UNLOCK(pcm);
575 //LOGE(LOG_TAG, "%s:%d, frames %d result %d", __func__, __LINE__, x.frames, x.result);
576 return x.result;
577 }
578
aos_pcm_readi(aos_pcm_t * pcm,void * buffer,aos_pcm_uframes_t size)579 aos_pcm_sframes_t aos_pcm_readi(aos_pcm_t *pcm, void *buffer, aos_pcm_uframes_t size)
580 {
581 audio_xferi_t x;
582 if(NULL == pcm) {
583 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
584 return PCM_RETURN_ERR;
585 }
586 if(pcm->fd < 0) {
587 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
588 return PCM_RETURN_ERR;
589 }
590 if(pcm->state != AOS_PCM_STATE_RUNNING) {
591 LOGE(LOG_TAG, "%s:%d, unexpected pcm state %d", __func__, __LINE__, pcm->state);
592 return PCM_RETURN_ERR;
593 }
594 if(pcm->stream != AOS_PCM_STREAM_CAPTURE) {
595 LOGE(LOG_TAG, "%s:%d, not capture device", __func__, __LINE__);
596 return PCM_RETURN_ERR;
597 }
598 PCM_LOCK(pcm);
599 x.buf = (void*)buffer;
600 x.frames = size;
601 x.result = 0;
602 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_READI_FRAMES, &x)) {
603 LOGE(LOG_TAG, "%s:%d, ioctl readi failed", __func__, __LINE__);
604 }
605 PCM_UNLOCK(pcm);
606 return x.result;
607 }
608
aos_pcm_readn(aos_pcm_t * pcm,void ** bufs,aos_pcm_uframes_t size)609 aos_pcm_sframes_t aos_pcm_readn(aos_pcm_t *pcm, void **bufs, aos_pcm_uframes_t size)
610 {
611 audio_xfern_t x;
612 if(NULL == pcm) {
613 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
614 return PCM_RETURN_ERR;
615 }
616 if(pcm->fd < 0) {
617 LOGE(LOG_TAG, "%s:%d, param fd is not opened", __func__, __LINE__);
618 return PCM_RETURN_ERR;
619 }
620 if(pcm->state != AOS_PCM_STATE_RUNNING) {
621 LOGE(LOG_TAG, "%s:%d, unexpected pcm state %d", __func__, __LINE__, pcm->state);
622 return PCM_RETURN_ERR;
623 }
624 if(pcm->stream != AOS_PCM_STREAM_CAPTURE) {
625 LOGE(LOG_TAG, "%s:%d, not capture device", __func__, __LINE__);
626 return PCM_RETURN_ERR;
627 }
628 PCM_LOCK(pcm);
629 x.bufs = bufs;
630 x.frames = size;
631 x.result = 0;
632 if(ioctl(pcm->fd, AUDIO_PCM_IOCTL_READN_FRAMES, &x)) {
633 LOGE(LOG_TAG, "%s:%d, ioctl readn failed", __func__, __LINE__);
634 }
635 PCM_UNLOCK(pcm);
636 return x.result;
637 }
638
aos_pcm_bytes_to_frames(aos_pcm_t * pcm,int bytes)639 aos_pcm_sframes_t aos_pcm_bytes_to_frames(aos_pcm_t *pcm, int bytes)
640 {
641 if(!pcm) {
642 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
643 return PCM_RETURN_ERR;
644 }
645
646 return (bytes / (pcm->hw_params->frame_bits / 8));
647 }
648
aos_pcm_frames_to_bytes(aos_pcm_t * pcm,aos_pcm_sframes_t frames)649 int aos_pcm_frames_to_bytes(aos_pcm_t *pcm, aos_pcm_sframes_t frames)
650 {
651 if(!pcm) {
652 LOGE(LOG_TAG, "%s:%d, param pcm is null", __func__, __LINE__);
653 return PCM_RETURN_ERR;
654 }
655 return (frames * (pcm->hw_params->frame_bits / 8));
656 }