1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4 #ifdef HAAS_AUDIO_DEMO
5 #include <posix/pthread.h>
6 #else
7 #include <pthread.h>
8 #endif
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdint.h>
12 #include <string.h>
13 #include "sound_pcm.h"
14 #include "audio_drv.h"
15 #include "ulog/ulog.h"
16
17 #define LOG_TAG "[sound_example_lb]"
18 #define AUDIO_PLAYER_HIGH_STACKSIZE 8192
19 #define AUDIO_PLAYER_DEFAULT_PRIORITY 33
20
21 static char *param = NULL;
22 static pthread_cond_t g_play_cond;
23 static pthread_mutex_t g_play_mutex;
24 static pthread_t g_play_thread;
25 static bool bCreateAudioThreadFlag = false;
26
sound_loopback_thread(void * arg)27 static void sound_loopback_thread(void *arg)
28 {
29 aos_pcm_t *pb_pcm = NULL, *cap_pcm = NULL;
30 unsigned char * dataBuf = NULL;
31 unsigned int buf_size = 0;
32 //int freq = 22050, channels = 1;
33 int freq = 16000, channels = 1;
34 int ret = -1;
35
36 LOGD(LOG_TAG, "%s:%d: sound_loopback_thread entry!!", __func__, __LINE__);
37 buf_size = freq * channels * 2 / 5;
38 dataBuf = (unsigned char *)malloc(buf_size);
39 if(!dataBuf) {
40 LOGE(LOG_TAG, "%s:%d: malloc %d failed. ", __func__, __LINE__, buf_size);
41 return 0;
42 }
43 while(1) {
44 if(!strcmp(param, "start")) {
45 if(!pb_pcm) {
46 LOGD(LOG_TAG, "%s:%d: open capture & playback stream!!", __func__, __LINE__);
47 /* open playback stream */
48 ret = aos_pcm_open(&pb_pcm, "default", AOS_PCM_STREAM_PLAYBACK, 0);
49 if(!ret) {
50 aos_pcm_hw_params_alloca(&pb_pcm->hw_params);
51 aos_pcm_sw_params_alloca(&pb_pcm->sw_params);
52 aos_pcm_sw_params_any(pb_pcm->sw_params);
53 aos_pcm_set_params(pb_pcm, AOSRV_PCM_FORMAT_S16_LE, AOS_PCM_ACCESS_RW_INTERLEAVED, channels, freq, 0, 0);
54 aos_pcm_prepare(pb_pcm);
55 aos_pcm_start(pb_pcm);
56 } else {
57 LOGE(LOG_TAG, "%s:%d: open playback stream failed. ", __func__, __LINE__);
58 }
59 }
60 if(!cap_pcm) {
61 /* open capture stream */
62 ret = aos_pcm_open(&cap_pcm, "default", AOS_PCM_STREAM_CAPTURE, 0);
63 if(!ret) {
64 aos_pcm_hw_params_alloca(&cap_pcm->hw_params);
65 aos_pcm_sw_params_alloca(&cap_pcm->sw_params);
66 aos_pcm_sw_params_any(cap_pcm->sw_params);
67 aos_pcm_set_params(cap_pcm, AOSRV_PCM_FORMAT_S16_LE, AOS_PCM_ACCESS_RW_INTERLEAVED, channels, freq, 0, 0);
68 aos_pcm_prepare(cap_pcm);
69 aos_pcm_start(cap_pcm);
70 } else {
71 LOGE(LOG_TAG, "%s:%d: open capture stream failed. ", __func__, __LINE__);
72 }
73 }
74 ret = aos_pcm_readi(cap_pcm, dataBuf, aos_pcm_bytes_to_frames(cap_pcm, buf_size));
75 if(ret > 0) {
76 //LOGD(LOG_TAG, "%s:%d: readi frames(%d) bytes(%d) successfully. ", __func__, __LINE__, ret, aos_pcm_frames_to_bytes(cap_pcm, ret));
77 ret = aos_pcm_writei(pb_pcm, dataBuf, aos_pcm_bytes_to_frames(pb_pcm, aos_pcm_frames_to_bytes(cap_pcm, ret)));
78 }
79 } else {
80 if(pb_pcm) {
81 LOGD(LOG_TAG, "%s:%d: close capture & playback stream!!", __func__, __LINE__);
82 //aos_pcm_drain(pb_pcm);
83 aos_pcm_stop(pb_pcm);
84 aos_pcm_close(pb_pcm);
85 pb_pcm = NULL;
86 }
87 if(cap_pcm) {
88 aos_pcm_stop(cap_pcm);
89 aos_pcm_close(cap_pcm);
90 cap_pcm = NULL;
91 }
92 usleep(200*1000);
93 }
94 }
95
96 return 0;
97 }
98
sound_example_loopback_init(void)99 static void sound_example_loopback_init(void)
100 {
101 if(bCreateAudioThreadFlag) {
102 return;
103 }
104 LOGD(LOG_TAG, "%s:%d, -->>", __func__, __LINE__);
105
106 pthread_attr_t attr;
107 struct sched_param sched;
108
109 pthread_cond_init(&g_play_cond, NULL);
110 pthread_mutex_init(&g_play_mutex, NULL);
111
112 pthread_attr_init(&attr);
113 pthread_attr_setstacksize(&attr, AUDIO_PLAYER_HIGH_STACKSIZE);
114 sched.sched_priority = AUDIO_PLAYER_DEFAULT_PRIORITY;
115 pthread_attr_setschedparam(&attr, &sched);
116
117 pthread_create(&g_play_thread, &attr, sound_loopback_thread, NULL);
118 pthread_setname_np(g_play_thread, "soundplaythread");
119
120 pthread_attr_destroy(&attr);
121 bCreateAudioThreadFlag = true;
122 }
123
sound_example_loopback_entry(int argc,char ** argv)124 void sound_example_loopback_entry(int argc, char **argv)
125 {
126 if (argc < 2) {
127 LOGD(LOG_TAG, "%s:%d: Usage: %s start/stop ", __func__, __LINE__, argv[0]);
128 return;
129 }
130 param = strdup(argv[1]);
131 if(param && !strcmp(param, "start"))
132 {
133 printf("sound loopback test begin ...\r\n");
134 } else {
135 printf("sound loopback test end !!!\r\n");
136 }
137 sound_example_loopback_init();
138 }