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