1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 *
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <stdarg.h>
11
12 #include "uvoice_types.h"
13 #include "uvoice_event.h"
14 #include "uvoice_audio.h"
15 #include "uvoice_common.h"
16
17 #include "uvoice_os.h"
18 #include "uvoice_pcm.h"
19 #include "audio_common.h"
20 #include "audio_mixer.h"
21 #include "audio_vad.h"
22 #include "audio_stream.h"
23 #include "audio_process.h"
24
25
26 #ifdef XR871_BOARD_V02
27 #define OUT_DEVICE_DEFAULT SND_DEVICE_OUT_SPEAKER_AND_HEADPHONE
28 #else
29 #define OUT_DEVICE_DEFAULT SND_DEVICE_OUT_SPEAKER
30 #endif
31 #define IN_DEVICE_DEFAULT SND_DEVICE_IN_PRIMARY_MIC
32
33 #define OUT_VOLUME_DEFAULT 4
34
35 #ifdef __os_linux__
36 #define OUT_PCM_DUMP_PATH "hal_pcm_out.dump"
37 #else
38 #define OUT_PCM_DUMP_PATH "/sdcard/hal_pcm_out.dump"
39 #endif
40
41
42 static struct audio_device *g_adev;
43
out_volume_set(int volume)44 int out_volume_set(int volume)
45 {
46 struct audio_device *adev = g_adev;
47 static bool first_set = true;
48
49 if (!adev) {
50 snd_err("adev null !\n");
51 return -1;
52 }
53
54 if (volume < VOLUME_LEVEL_MIN || volume > VOLUME_LEVEL_MAX) {
55 snd_err("volume level %d invalid !\n", volume);
56 return -1;
57 }
58
59 if (adev->out_volume != volume || first_set) {
60 adev->out_volume = volume;
61 first_set = false;
62 snd_info("set volume %d\n", adev->out_volume);
63 volume_set(adev->out_device, adev->out_volume);
64 }
65 return 0;
66 }
67
out_volume_get(void)68 int out_volume_get(void)
69 {
70 struct audio_device *adev = g_adev;
71 if (!adev) {
72 snd_err("adev null !\n");
73 return -1;
74 }
75 return adev->out_volume;
76 }
77
out_volume_range(int * max,int * min)78 int out_volume_range(int *max, int *min)
79 {
80 if (min)
81 *min = VOLUME_LEVEL_MIN;
82 if (max)
83 *max = VOLUME_LEVEL_MAX;
84 return 0;
85 }
86
out_device_set(snd_device_t device)87 int out_device_set(snd_device_t device)
88 {
89 struct audio_device *adev = g_adev;
90
91 if (!adev) {
92 snd_err("adev null !\n");
93 return -1;
94 }
95
96 if (device < SND_DEVICE_OUT_BEGIN || device > SND_DEVICE_IN_END) {
97 snd_err("invalid device %d !\n", device);
98 return -1;
99 }
100
101 adev->fixed_out_device = device;
102 return 0;
103 }
104
out_extpa_set(audio_extpa_info_t * info)105 int out_extpa_set(audio_extpa_info_t *info)
106 {
107 struct external_pa_info pa_info;
108 pa_info.used = info->used;
109 pa_info.active_high = info->active_high;
110 pa_info.delay_ms = info->delay_ms;
111 pa_info.pin = info->pin;
112 return uvoice_extpa_config(&pa_info);
113 }
114
out_stream_reset(struct out_stream * out)115 int out_stream_reset(struct out_stream *out)
116 {
117 if (!out) {
118 snd_err("stream null !\n");
119 return -1;
120 }
121
122 snd_info("stream reset\n");
123 out_stream_stop(out);
124 return 0;
125 }
126
out_stream_mute(struct out_stream * out,int mute)127 int out_stream_mute(struct out_stream *out, int mute)
128 {
129 struct audio_device *adev = g_adev;
130
131 if (!adev) {
132 snd_err("adev null !\n");
133 return -1;
134 }
135
136 if (!out) {
137 snd_err("stream null !\n");
138 return -1;
139 }
140
141 os_mutex_lock(out->lock, OS_WAIT_FOREVER);
142 out->silent = mute;
143 uvoice_dev_mute(&out->pcm, adev->out_device, 1);
144 os_mutex_unlock(out->lock);
145 snd_debug("mute %d\n", out->silent);
146 return 0;
147 }
148
out_stream_period_duration(struct out_stream * out)149 int out_stream_period_duration(struct out_stream *out)
150 {
151 struct pcm_config *config;
152 int delay;
153
154 if (!out) {
155 snd_err("stream null !\n");
156 return -1;
157 }
158
159 config = &out->pcm.config;
160
161 if (!pcm_rate_valid(config->rate)) {
162 snd_err("sample rate invalid !\n");
163 return -1;
164 }
165
166 delay = config->period_size / (config->rate / 1000);
167
168 delay -= 5;
169
170 return delay > 0 ? delay : 1;
171 }
172
out_stream_configured(struct out_stream * out)173 bool out_stream_configured(struct out_stream *out)
174 {
175 if (out && out->state != STREAM_STOP)
176 return true;
177 return false;
178 }
179
out_stream_configure(struct out_stream * out,media_pcminfo_t * pcminfo)180 int out_stream_configure(struct out_stream *out, media_pcminfo_t *pcminfo)
181 {
182 struct audio_device *adev = g_adev;
183 struct pcm_device *pcm;
184 struct pcm_config *config;
185
186 if (!adev) {
187 snd_err("adev null !\n");
188 return -1;
189 }
190
191 if (!out) {
192 snd_err("stream null !\n");
193 return -1;
194 }
195
196 if (!pcminfo) {
197 snd_err("pcminfo null !\n");
198 return -1;
199 }
200
201 if (!pcm_rate_valid(pcminfo->rate)) {
202 snd_err("rate %d invalid !\n", pcminfo->rate);
203 return -1;
204 }
205
206 if (!pcm_channel_valid(pcminfo->channels) || pcminfo->channels > 2) {
207 snd_err("channels %d invalid !\n", pcminfo->channels);
208 return -1;
209 }
210
211 if (!pcm_bits_valid(pcminfo->bits)) {
212 snd_err("bits %d invalid !\n", pcminfo->bits);
213 return -1;
214 }
215
216 if (pcminfo->frames <= 0) {
217 snd_err("period_size %d invalid !\n", pcminfo->frames);
218 return -1;
219 }
220
221 os_mutex_lock(out->lock, OS_WAIT_FOREVER);
222 if (out->state != STREAM_STOP) {
223 snd_err("configure failed ! state %d\n",
224 out->state);
225 os_mutex_unlock(out->lock);
226 return -1;
227 }
228
229 pcm = &out->pcm;
230 config = &pcm->config;
231
232 pcm->dir = PCM_OUT;
233
234 config->rate = pcminfo->rate;
235 config->channels = pcminfo->channels;
236 config->period_size = pcminfo->frames >= 1024 ? 1024 : 640;
237 config->period_count = 4;
238 config->format = bits_to_pcm_format(pcminfo->bits);
239
240 if (uvoice_pcm_setup(pcm)) {
241 snd_err("pcm setup failed !\n");
242 os_mutex_unlock(out->lock);
243 return -1;
244 }
245
246 if (pcminfo->rate != config->rate)
247 pcminfo->rate = config->rate;
248 if (pcminfo->channels != config->channels)
249 pcminfo->channels = config->channels;
250 if (pcminfo->bits != pcm_format_to_bits(config->format))
251 pcminfo->bits = pcm_format_to_bits(config->format);
252
253 audio_out_process_init(adev, out);
254
255 out->state = STREAM_SETUP;
256 os_mutex_unlock(out->lock);
257 snd_debug("stream setup\n");
258 return 0;
259 }
260
out_stream_start(struct out_stream * out)261 static int out_stream_start(struct out_stream *out)
262 {
263 struct audio_device *adev = g_adev;
264
265 if (!adev) {
266 snd_err("adev null !\n");
267 return -1;
268 }
269
270 if (!out) {
271 snd_err("stream null !\n");
272 return -1;
273 }
274
275 uvoice_dev_mute(&out->pcm, adev->out_device, 0);
276
277 if (adev->fixed_out_device >= SND_DEVICE_OUT_BEGIN &&
278 adev->fixed_out_device <= SND_DEVICE_OUT_END)
279 device_select(adev, adev->fixed_out_device, true);
280 else
281 device_select(adev, adev->out_device, true);
282
283 if (uvoice_pcm_open(&out->pcm)) {
284 snd_err("pcm open failed !\n");
285 return -1;
286 }
287
288 #ifdef AUDIO_CACHE_ENABLE
289 out->buffer_size = period_samples_to_bytes(&out->pcm.config);
290 out->buffer = snd_zalloc(out->buffer_size, AFM_EXTN);
291 if (!out->buffer) {
292 snd_err("alloc buffer failed !\n");
293 uvoice_pcm_close(&out->pcm);
294 return -1;
295 }
296 snd_debug("alloc out buffer %d\n", out->buffer_size);
297 #endif
298
299 out->state = STREAM_START;
300 snd_info("stream start\n");
301 return 0;
302 }
303
out_stream_write(struct out_stream * out,uint8_t * buffer,int nbytes)304 int out_stream_write(struct out_stream *out, uint8_t *buffer,
305 int nbytes)
306 {
307 #ifdef AUDIO_CACHE_ENABLE
308 struct audio_device *adev = g_adev;
309 int remaining_size = nbytes;
310 int avail_size;
311 int copy_size;
312 int ret;
313
314 if (!adev) {
315 snd_err("adev null !\n");
316 return -1;
317 }
318
319 if (!out) {
320 snd_err("stream null !\n");
321 return -1;
322 }
323
324 os_mutex_lock(out->lock, OS_WAIT_FOREVER);
325
326 if (out->state == STREAM_STOP) {
327 snd_info("stream stop\n");
328 goto __exit;
329 }
330
331 avail_size = remaining_size + out->buffer_dirty_size;
332
333 if (avail_size < out->buffer_size) {
334 snd_memcpy(out->buffer + out->buffer_dirty_size,
335 buffer, remaining_size);
336 out->buffer_dirty_size += remaining_size;
337 goto __exit;
338 }
339
340 if (out->state == STREAM_SETUP) {
341 if (out_stream_start(out)) {
342 snd_err("start failed !\n");
343 os_mutex_unlock(out->lock);
344 return -1;
345 }
346 }
347
348 while (avail_size >= out->buffer_size) {
349 copy_size = MIN(remaining_size,
350 out->buffer_size - out->buffer_dirty_size);
351 snd_memcpy(out->buffer + out->buffer_dirty_size,
352 buffer + nbytes - remaining_size, copy_size);
353 remaining_size -= copy_size;
354
355 audio_out_process(out, out->buffer, out->buffer_size);
356
357 if (out->dump) {
358 fwrite(out->buffer, out->buffer_size, 1, out->dump);
359 if (ferror(out->dump)) {
360 snd_err("write dump failed %d!\n", ferror(out->dump));
361 os_mutex_unlock(out->lock);
362 return -1;
363 }
364 }
365
366 ret = uvoice_pcm_write(&out->pcm, out->buffer, out->buffer_size);
367 if (ret < 0) {
368 snd_err("write %d failed %d!\n", out->buffer_size, ret);
369 os_mutex_unlock(out->lock);
370 return -1;
371 }
372
373 #ifdef UVOICE_AEC_ENABLE
374 audio_out_conserve(adev, out->buffer, out->buffer_size);
375 #endif
376
377 out->buffer_dirty_size = 0;
378 avail_size -= out->buffer_size;
379 if (out->state == STREAM_START) {
380 out->state = STREAM_RUNNING;
381 snd_debug("stream running\n");
382 }
383 }
384
385 if (remaining_size > 0) {
386 snd_memcpy(out->buffer + out->buffer_dirty_size,
387 buffer + nbytes - remaining_size, remaining_size);
388 out->buffer_dirty_size += remaining_size;
389 }
390
391 __exit:
392 os_mutex_unlock(out->lock);
393 #else
394
395 struct audio_device *adev = g_adev;
396 int ret;
397
398 if (out->state == STREAM_STOP) {
399 snd_info("stream stop\n");
400 return 0;
401 }
402
403 if (out->state == STREAM_SETUP) {
404 if (out_stream_start(out)) {
405 snd_err("start failed !\n");
406 return -1;
407 }
408 }
409
410 ret = uvoice_pcm_write(&out->pcm, buffer, nbytes);
411 if (ret < 0) {
412 snd_err("write %d failed %d!\n", nbytes, ret);
413 return -1;
414 }
415 #endif
416 return 0;
417 }
418
out_stream_silent(struct out_stream * out)419 int out_stream_silent(struct out_stream *out)
420 {
421 #ifdef AUDIO_CACHE_ENABLE
422 if (!out) {
423 snd_err("stream null !\n");
424 return -1;
425 }
426
427 os_mutex_lock(out->lock, OS_WAIT_FOREVER);
428
429 if (out->state != STREAM_RUNNING &&
430 out->state != STREAM_START)
431 goto __exit;
432
433 if (out->buffer_dirty_size > 0) {
434 snd_debug("drain %d\n", out->buffer_dirty_size);
435 memset(out->buffer + out->buffer_dirty_size, 0,
436 out->buffer_size - out->buffer_dirty_size);
437 if (out->dump) {
438 fwrite(out->buffer, out->buffer_size, 1, out->dump);
439 if (ferror(out->dump)) {
440 snd_err("write dump failed %d!\n", ferror(out->dump));
441 os_mutex_unlock(out->lock);
442 return -1;
443 }
444 }
445 uvoice_pcm_write(&out->pcm, out->buffer, out->buffer_size);
446 out->buffer_dirty_size = 0;
447 } else {
448 memset(out->buffer, 0, out->buffer_size);
449 uvoice_pcm_write(&out->pcm, out->buffer, out->buffer_size);
450 }
451
452 __exit:
453 os_mutex_unlock(out->lock);
454 return 0;
455 #else
456 return uvoice_pcm_silence(&out->pcm);
457 #endif
458 }
459
out_stream_stop(struct out_stream * out)460 int out_stream_stop(struct out_stream *out)
461 {
462 struct audio_device *adev = g_adev;
463
464 if (!adev) {
465 snd_err("adev null !\n");
466 return -1;
467 }
468
469 if (!out) {
470 snd_err("stream null !\n");
471 return -1;
472 }
473
474 os_mutex_lock(out->lock, OS_WAIT_FOREVER);
475 if (out->state != STREAM_RUNNING &&
476 out->state != STREAM_START) {
477 snd_debug("stream not start\n");
478 goto __exit;
479 }
480
481 #ifdef AUDIO_CACHE_ENABLE
482 if (out->buffer_dirty_size > 0) {
483 uvoice_pcm_write(&out->pcm,
484 out->buffer, out->buffer_dirty_size);
485 out->buffer_dirty_size = 0;
486 }
487 #endif
488
489 if (!out->silent)
490 uvoice_pcm_flush(&out->pcm);
491
492 uvoice_dev_mute(&out->pcm, adev->out_device, 1);
493
494 uvoice_pcm_close(&out->pcm);
495
496 #ifdef AUDIO_CACHE_ENABLE
497 snd_free(out->buffer);
498 out->buffer = NULL;
499 out->buffer_size = 0;
500 #endif
501
502 __exit:
503 out->silent = 0;
504 out->state = STREAM_STOP;
505 os_mutex_unlock(out->lock);
506
507 snd_info("stream stop\n");
508 return 0;
509 }
510
out_stream_create(void)511 struct out_stream *out_stream_create(void)
512 {
513 struct audio_device *adev = g_adev;
514 struct out_stream *out;
515
516 if (!adev) {
517 snd_err("adev null !\n");
518 return NULL;
519 }
520
521 out = snd_zalloc(sizeof(struct out_stream), AFM_EXTN);
522 if (!out) {
523 snd_err("alloc out stream failed !\n");
524 return NULL;
525 }
526
527 if (adev->out_pcm_dump) {
528 snd_debug("open out dump\n");
529 out->dump = fopen(OUT_PCM_DUMP_PATH, "wb+");
530 if (!out->dump) {
531 snd_err("open out dump failed !\n");
532 snd_free(out);
533 return NULL;
534 }
535 }
536
537 out->lock = os_mutex_new();
538 out->state = STREAM_STOP;
539
540 adev->out = out;
541
542 snd_info("stream create\n");
543 return out;
544 }
545
out_stream_release(struct out_stream * out)546 int out_stream_release(struct out_stream *out)
547 {
548 struct audio_device *adev = g_adev;
549
550 if (!adev) {
551 snd_err("adev null !\n");
552 return -1;
553 }
554
555 if (!out) {
556 snd_err("stream null !\n");
557 return -1;
558 }
559
560 if (out->state != STREAM_STOP) {
561 snd_err("stream not stop !\n");
562 return -1;
563 }
564
565 if (out->dump) {
566 snd_debug("close out dump\n");
567 fclose(out->dump);
568 }
569
570 audio_out_process_deinit(out);
571
572 os_mutex_free(out->lock);
573 snd_free(out);
574 adev->out = NULL;
575
576 snd_info("stream release\n");
577 return 0;
578 }
579
in_stream_configured(struct in_stream * in)580 bool in_stream_configured(struct in_stream *in)
581 {
582 if (in && in->state != STREAM_STOP)
583 return true;
584 return false;
585 }
586
in_stream_configure(struct in_stream * in,media_pcminfo_t * pcminfo)587 int in_stream_configure(struct in_stream *in, media_pcminfo_t *pcminfo)
588 {
589 struct audio_device *adev = g_adev;
590 struct pcm_device *pcm;
591
592 if (!adev) {
593 snd_err("adev null !\n");
594 return -1;
595 }
596
597 if (!in) {
598 snd_err("stream null !\n");
599 return -1;
600 }
601
602 if (!pcminfo) {
603 snd_err("pcminfo null !\n");
604 return -1;
605 }
606
607 if (in->state != STREAM_STOP) {
608 snd_err("state %d, error !\n", in->state);
609 return -1;
610 }
611
612 if (!pcm_rate_valid(pcminfo->rate)) {
613 snd_err("rate %d invalid !\n", pcminfo->rate);
614 return -1;
615 }
616
617 if (!pcm_channel_valid(pcminfo->channels)) {
618 snd_err("channels %d invalid !\n", pcminfo->channels);
619 return -1;
620 }
621
622 if (!pcm_bits_valid(pcminfo->bits)) {
623 snd_err("bits %d invalid !\n", pcminfo->bits);
624 return -1;
625 }
626
627 if (pcminfo->frames <= 0) {
628 snd_err("frames %d invalid !\n", pcminfo->frames);
629 return -1;
630 }
631
632 os_mutex_lock(in->lock, OS_WAIT_FOREVER);
633
634 pcm = &in->pcm;
635 pcm->dir = PCM_IN;
636
637 pcm->config.rate = pcminfo->rate;
638 pcm->config.channels = pcminfo->channels;
639 pcm->config.period_size = pcminfo->frames;
640 pcm->config.format = bits_to_pcm_format(pcminfo->bits);
641
642 if (uvoice_pcm_setup(pcm)) {
643 snd_err("pcm setup failed !\n");
644 os_mutex_unlock(in->lock);
645 return -1;
646 }
647
648 if (pcminfo->rate != pcm->config.rate)
649 pcminfo->rate = pcm->config.rate;
650 if (pcminfo->channels != pcm->config.channels)
651 pcminfo->channels = pcm->config.channels;
652 if (pcminfo->bits != pcm_format_to_bits(pcm->config.format))
653 pcminfo->bits = pcm_format_to_bits(pcm->config.format);
654
655 if (audio_in_process_init(adev, in)) {
656 snd_err("audio process init failed !\n");
657 os_mutex_unlock(in->lock);
658 return -1;
659 }
660
661 #ifdef UVOICE_VAD_ENABLE
662 if (adev->vad_enable) {
663 in->vad = audio_vad_create(pcm->config.rate,
664 pcm->config.period_size);
665 if (!in->vad) {
666 snd_err("create vad failed !\n");
667 audio_in_process_deinit(in);
668 os_mutex_unlock(in->lock);
669 return -1;
670 }
671 }
672 #endif
673
674 in->state = STREAM_SETUP;
675 os_mutex_unlock(in->lock);
676 snd_debug("stream setup\n");
677 return 0;
678 }
679
680 static FILE *in_stream_dump;
681
in_stream_start(struct in_stream * in)682 static int in_stream_start(struct in_stream *in)
683 {
684 struct audio_device *adev = g_adev;
685 struct pcm_device *pcm;
686
687 if (!adev) {
688 snd_err("adev null !\n");
689 return -1;
690 }
691
692 if (!in) {
693 snd_err("stream null !\n");
694 return -1;
695 }
696
697 pcm = &in->pcm;
698 pcm->dir = PCM_IN;
699
700 if (uvoice_pcm_open(pcm)) {
701 snd_err("pcm open failed !\n");
702 return -1;
703 }
704
705 #if 0
706 if (in_stream_dump)
707 fclose(in_stream_dump);
708 in_stream_dump = fopen("/sdcard/in_dump_before_anc.pcm", "wb+");
709 if (!in_stream_dump) {
710 snd_err("open in stream dump fail !\n");
711 uvoice_pcm_close(pcm);
712 return -1;
713 }
714 snd_info("in stream dump open\n");
715 #endif
716
717 device_select(adev, adev->in_device, true);
718
719 in->state = STREAM_START;
720
721 adev->in = in;
722
723 snd_info("stream start\n");
724 return 0;
725 }
726
in_stream_read(struct in_stream * in,uint8_t * buffer,int nbytes)727 int in_stream_read(struct in_stream *in, uint8_t *buffer,
728 int nbytes)
729 {
730 int ret;
731
732 if (!in) {
733 snd_err("stream null !\n");
734 return -1;
735 }
736
737 os_mutex_lock(in->lock, OS_WAIT_FOREVER);
738 if (in->state == STREAM_STOP) {
739 snd_err("stream stop !\n");
740 os_mutex_unlock(in->lock);
741 return -1;
742 } else if (in->state == STREAM_SETUP) {
743 if (in_stream_start(in)) {
744 snd_err("start failed !\n");
745 os_mutex_unlock(in->lock);
746 return -1;
747 }
748 }
749
750 ret = uvoice_pcm_read(&in->pcm, buffer, nbytes);
751 if (ret < 0) {
752 snd_err("read %d failed %d!\n", nbytes, ret);
753 os_mutex_unlock(in->lock);
754 return -1;
755 }
756
757 if (in_stream_dump) {
758 fwrite(buffer, ret, 1, in_stream_dump);
759 if (ferror(in_stream_dump)) {
760 snd_err("write in stream dump fail %d!\n",
761 ferror(in_stream_dump));
762 }
763 }
764
765 if (audio_in_process(in, buffer, ret)) {
766 snd_err("audio process failed !\n");
767 os_mutex_unlock(in->lock);
768 return -1;
769 }
770
771 #ifdef UVOICE_VAD_ENABLE
772 if (in->vad) {
773 if (audio_vad_process(in->vad, buffer, ret)) {
774 snd_err("audio process failed !\n");
775 os_mutex_unlock(in->lock);
776 return -1;
777 }
778 }
779 #endif
780
781 if (in->state == STREAM_START)
782 in->state = STREAM_RUNNING;
783
784 os_mutex_unlock(in->lock);
785 return ret;
786 }
787
in_stream_stop(struct in_stream * in)788 int in_stream_stop(struct in_stream *in)
789 {
790 struct audio_device *adev = g_adev;
791
792 if (!adev) {
793 snd_err("adev null !\n");
794 return -1;
795 }
796
797 if (!in) {
798 snd_err("stream null !\n");
799 return -1;
800 }
801
802 os_mutex_lock(in->lock, OS_WAIT_FOREVER);
803
804 if (in->state != STREAM_RUNNING &&
805 in->state != STREAM_START) {
806 snd_err("stop failed ! state %d\n", in->state);
807 os_mutex_unlock(in->lock);
808 return -1;
809 }
810
811 if (in_stream_dump) {
812 fclose(in_stream_dump);
813 in_stream_dump = NULL;
814 snd_info("in stream dump close\n");
815 }
816
817 uvoice_pcm_close(&in->pcm);
818 in->state = STREAM_STOP;
819 snd_info("stream stop\n");
820 os_mutex_unlock(in->lock);
821 return 0;
822 }
823
in_stream_create(void)824 struct in_stream *in_stream_create(void)
825 {
826 struct audio_device *adev = g_adev;
827 struct in_stream *in;
828
829 if (!adev) {
830 snd_err("adev null !\n");
831 return NULL;
832 }
833
834 in = snd_zalloc(sizeof(struct in_stream), AFM_EXTN);
835 if (!in) {
836 snd_err("alloc in stream failed !\n");
837 return NULL;
838 }
839
840 in->lock = os_mutex_new();
841 in->state = STREAM_STOP;
842 adev->in = in;
843
844 snd_info("stream create\n");
845 return in;
846 }
847
in_stream_release(struct in_stream * in)848 int in_stream_release(struct in_stream *in)
849 {
850 struct audio_device *adev = g_adev;
851
852 if (!adev) {
853 snd_err("adev null !\n");
854 return -1;
855 }
856
857 if (!in) {
858 snd_err("stream null !\n");
859 return -1;
860 }
861
862 #ifdef UVOICE_VAD_ENABLE
863 audio_vad_release(in->vad);
864 #endif
865
866 audio_in_process_deinit(in);
867
868 os_mutex_free(in->lock);
869 snd_free(in);
870 adev->in = NULL;
871 snd_info("stream release\n");
872 return 0;
873 }
874
audio_param_set(int key,int value)875 int audio_param_set(int key, int value)
876 {
877 struct audio_device *adev = g_adev;
878
879 if (!adev) {
880 snd_err("adev null !\n");
881 return -1;
882 }
883
884 switch (key) {
885 case PARAM_KEY_NOISE_SUPPRESSION:
886 if (value == PARAM_VAL_ENABLE)
887 adev->noise_suppression = 1;
888 else if (value == PARAM_VAL_DISABLE)
889 adev->noise_suppression = 0;
890 break;
891 case PARAM_KEY_ECHO_CANCELLATION:
892 if (value == PARAM_VAL_ENABLE)
893 adev->echo_cancellation = 1;
894 else if (value == PARAM_VAL_DISABLE)
895 adev->echo_cancellation = 0;
896 break;
897 case PARAM_KEY_AUTO_GAIN_CONTROL:
898 if (value == PARAM_VAL_ENABLE)
899 adev->auto_gain_control = 1;
900 else if (value == PARAM_VAL_DISABLE)
901 adev->auto_gain_control = 0;
902 break;
903 case PARAM_KEY_VOICE_ACTIVE_DETECT:
904 if (value == PARAM_VAL_ENABLE)
905 adev->vad_enable = 1;
906 else if (value == PARAM_VAL_DISABLE)
907 adev->vad_enable = 0;
908 break;
909 case PARAM_KEY_EFFECT_EQUALIZER:
910 if (value == PARAM_VAL_ENABLE)
911 adev->equalizer_enable = 1;
912 else if (value == PARAM_VAL_DISABLE)
913 adev->equalizer_enable = 0;
914 break;
915 case PARAM_KEY_OUT_PCM_DUMP:
916 if (value == PARAM_VAL_ENABLE)
917 adev->out_pcm_dump = 1;
918 else if (value == PARAM_VAL_DISABLE)
919 adev->out_pcm_dump = 0;
920 break;
921 default:
922 break;
923 }
924
925 return 0;
926 }
927
audio_pcm_notify(pcm_message_t msg)928 int audio_pcm_notify(pcm_message_t msg)
929 {
930 switch (msg) {
931 case PCM_MSG_TX_WAITING:
932 break;
933 case PCM_MSG_TX_UNDERRUN:
934 snd_warn("tx underrun\n");
935 break;
936 case PCM_MSG_TX_OVERRUN:
937 snd_warn("tx overrun\n");
938 break;
939 case PCM_MSG_RX_UNDERRUN:
940 snd_warn("rx underrun\n");
941 break;
942 case PCM_MSG_RX_OVERRUN:
943 snd_warn("rx overrun\n");
944 break;
945 default:
946 break;
947 }
948 return 0;
949 }
950
audio_sw_event_handle(uvoice_event_t * event,void * data)951 static void audio_sw_event_handle(uvoice_event_t *event, void *data)
952 {
953 struct audio_device *adev = (struct audio_device *)data;
954
955 if (!adev) {
956 snd_err("adev null !\n");
957 return;
958 }
959
960 if (event->type != UVOICE_EV_SW) {
961 snd_warn("event type not match\n");
962 return;
963 }
964
965 if (event->code == UVOICE_CODE_HEADPHONE) {
966 if (event->value == 1)
967 device_select(adev, SND_DEVICE_OUT_HEADPHONE, false);
968 else if (event->value == 0)
969 device_select(adev, SND_DEVICE_OUT_SPEAKER, false);
970
971 if (!adev->in_device_fix)
972 device_select(adev, SND_DEVICE_IN_PRIMARY_MIC, false);
973 } else if (event->code == UVOICE_CODE_HEADSET) {
974 if (event->value == 1) {
975 device_select(adev, SND_DEVICE_OUT_HEADSET, false);
976 if (!adev->in_device_fix)
977 device_select(adev, SND_DEVICE_IN_HEADSET_MIC, false);
978 } else if (event->value == 0) {
979 device_select(adev, SND_DEVICE_OUT_SPEAKER, false);
980 if (!adev->in_device_fix)
981 device_select(adev, SND_DEVICE_IN_PRIMARY_MIC, false);
982 }
983 }
984 }
985
audio_device_init(void)986 int audio_device_init(void)
987 {
988 struct audio_device *adev;
989 int ret;
990
991 adev = snd_zalloc(sizeof(struct audio_device), AFM_EXTN);
992 if (!adev) {
993 snd_err("alloc audio device failed !\n");
994 return -1;
995 }
996
997 adev->out_device = OUT_DEVICE_DEFAULT;
998 adev->in_device = IN_DEVICE_DEFAULT;
999 adev->in_device_fix = 1;
1000
1001 ret = volume_get(adev->out_device);
1002 if (ret < 0) {
1003 adev->out_volume = OUT_VOLUME_DEFAULT;
1004 snd_debug("default volume %d\n", adev->out_volume);
1005 } else {
1006 adev->out_volume = ret;
1007 }
1008
1009 g_adev = adev;
1010 uvoice_event_register(UVOICE_EV_SW, audio_sw_event_handle, adev);
1011
1012 uvoice_pcm_init();
1013 return 0;
1014 }
1015
audio_device_deinit(void)1016 int audio_device_deinit(void)
1017 {
1018 struct audio_device *adev = g_adev;
1019
1020 if (!adev) {
1021 snd_err("adev null !\n");
1022 return -1;
1023 }
1024
1025 uvoice_event_unregister(UVOICE_EV_SW, audio_sw_event_handle, NULL);
1026 snd_free(adev);
1027 g_adev = NULL;
1028
1029 return 0;
1030 }
1031
1032