blob: 9e5f8ce8d2a6e2c24dd32f7e8c1e19f7c3f26bf6 [file] [log] [blame]
b.liuf191eb72024-12-12 10:45:23 +08001/*
2* mbtk_pcm_stream.c
3*
4* MBTK audio playback/record PCM source.
5*
6*/
7/******************************************************************************
8
9 EDIT HISTORY FOR FILE
10
11 WHEN WHO WHAT,WHERE,WHY
12-------- -------- -------------------------------------------------------
132024/03/23 LiuBin Initial version.
142024/10/15 LiuBin Add PA and volume control API.
152024/11/30 LiuBin Add get/send PCM from/to the end of voice(RTP).
16
17******************************************************************************/
18
b.liu1c1c7212023-12-22 16:35:27 +080019#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <fcntl.h>
23#include <errno.h>
b.liu9e8584b2024-11-06 19:21:28 +080024#include <cutils/str_parms.h>
b.liu1c1c7212023-12-22 16:35:27 +080025
26#include "mbtk_log.h"
27#include "mbtk_audio_internal.h"
luojianfee10dc2024-07-25 11:34:35 +080028#include "audio_if_audio_hw_mrvl.h"
b.liu1c1c7212023-12-22 16:35:27 +080029
30#define LOCK_FILE "/var/run/mbtk_audio.lock"
31#define AUDIO_DEBUG 0
32
33#define AUDIO_LOG(fmt, args ...) \
34 do{ \
35 if(AUDIO_DEBUG) {LOGD(fmt, ##args);} \
36 } while(0)
37
38extern void* audio_hal_install(void);
39extern void audio_hal_uninstall(void);
40extern void configure_vcm(unsigned int data[]);
41
42static audio_inter_info_t *audio_info = NULL;
43static pthread_t recorder_thread_play;
b.liud0ea5642024-10-17 10:28:51 +080044static mbtk_audio_pa_switch_func audio_pa_switch_func = NULL;
45static mbtk_audio_volume_set_func audio_volume_set_func = NULL;
46static int audio_pcm_write_count = 0;
b.liu1c1c7212023-12-22 16:35:27 +080047
48static int lock_get() {
b.liub3b923a2024-06-06 15:15:49 +080049 int fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0666);
b.liu1c1c7212023-12-22 16:35:27 +080050 if (fd == -1) {
51 LOGE("Open(%s) fail:%d", LOCK_FILE, errno);
52 return -1;
53 }
54 // 尝试对文件进行加锁
55 struct flock fl;
56 fl.l_type = F_WRLCK;
57 fl.l_whence = SEEK_SET;
58 fl.l_start = 0;
59 fl.l_len = 1;
60 int ret = fcntl(fd, F_SETLK, &fl);
61 if (ret == -1) {
62 LOGE("Another instance is running, exiting...");
63 close(fd);
64 return -1;
65 }
66 close(fd);
67 LOGD("Get file lock.");
68 return 0;
69}
70
71static int lock_free() {
b.liub3b923a2024-06-06 15:15:49 +080072 int fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0666);
b.liu1c1c7212023-12-22 16:35:27 +080073 if (fd == -1) {
74 LOGE("Open(%s) fail:%d", LOCK_FILE, errno);
75 return -1;
76 }
77 // 释放文件锁
78 struct flock fl;
79 fl.l_type = F_UNLCK;
80 fl.l_whence = SEEK_SET;
81 fl.l_start = 0;
82 fl.l_len = 1;
83 int ret = fcntl(fd, F_SETLK, &fl);
84 if (ret == -1) {
85 LOGE("Another instance is running, exiting...");
86 close(fd);
87 return -1;
88 }
89
90 LOGD("Free file lock.");
91 return 0;
92}
93
94static void audio_recorder_thread(void *arg)
95{
b.liu9e8584b2024-11-06 19:21:28 +080096 int len, frames = 0;
b.liu1c1c7212023-12-22 16:35:27 +080097 char buff[MBTK_PCM_WB_BUF_SIZE];
98
b.liuf191eb72024-12-12 10:45:23 +080099 audio_info->recorder.state = AUDIO_RECORDER_STATE_RUNNING;
100 pthread_mutex_init(&audio_info->recorder.mutex, NULL);
101 pthread_cond_init(&audio_info->recorder.cond, NULL);
b.liu1c1c7212023-12-22 16:35:27 +0800102
103 while (TRUE) {
104 /* Playback loop */
b.liuf191eb72024-12-12 10:45:23 +0800105 pthread_mutex_lock(&audio_info->recorder.mutex);
106 if(audio_info->recorder.state == AUDIO_RECORDER_STATE_STOP) {
b.liu1c1c7212023-12-22 16:35:27 +0800107 LOGD("Stop recorder...");
b.liuf191eb72024-12-12 10:45:23 +0800108 pthread_mutex_unlock(&audio_info->recorder.mutex);
b.liu1c1c7212023-12-22 16:35:27 +0800109 break;
b.liuf191eb72024-12-12 10:45:23 +0800110 } else if(audio_info->recorder.state == AUDIO_RECORDER_STATE_PAUSE) {
111 pthread_cond_wait(&audio_info->recorder.cond, &audio_info->recorder.mutex);
112 pthread_mutex_unlock(&audio_info->recorder.mutex);
b.liu1c1c7212023-12-22 16:35:27 +0800113 continue;
114 } else {
b.liuf191eb72024-12-12 10:45:23 +0800115 pthread_mutex_unlock(&audio_info->recorder.mutex);
b.liu1c1c7212023-12-22 16:35:27 +0800116 }
117
118 //record the needed format stream from the device.
119 //only read pcm stream, no send command.
b.liuf191eb72024-12-12 10:45:23 +0800120 len = audio_info->recorder.stream_in->read(audio_info->recorder.stream_in, buff,
b.liu1c1c7212023-12-22 16:35:27 +0800121 audio_info->playback_size);
122 if (len <= 0) {
123 LOGE("%s: error reading!", __FUNCTION__);
124 goto thread_end;
125 }
126
127 AUDIO_LOG("Recorder data : len - %d", len);
128
b.liuf191eb72024-12-12 10:45:23 +0800129 if(audio_info->recorder.recorder_cb) {
130 audio_info->recorder.recorder_cb(buff, len);
b.liu1c1c7212023-12-22 16:35:27 +0800131 }
132
b.liuf191eb72024-12-12 10:45:23 +0800133 AUDIO_LOG("%s: No.%d frame playback.", __FUNCTION__, ++frames);
b.liu1c1c7212023-12-22 16:35:27 +0800134 }
135
136
137thread_end:
b.liuf191eb72024-12-12 10:45:23 +0800138 pthread_mutex_destroy(&audio_info->recorder.mutex);
139 pthread_cond_destroy(&audio_info->recorder.cond);
b.liu1c1c7212023-12-22 16:35:27 +0800140
b.liuf191eb72024-12-12 10:45:23 +0800141 audio_info->recorder.stream_in->common.standby(&audio_info->recorder.stream_in->common);
142 audio_info->audio_ahw_dev_ubus->close_input_stream(audio_info->audio_ahw_dev_ubus, audio_info->recorder.stream_in);
b.liu1c1c7212023-12-22 16:35:27 +0800143 VCMDeinit();//close the fd of audiostub_ctl when exit the thread.
b.liuf191eb72024-12-12 10:45:23 +0800144 audio_info->recorder.stream_in = NULL;
b.liu1c1c7212023-12-22 16:35:27 +0800145 LOGD("%s: finished pcm playback.", __FUNCTION__);
146
147 // Notify audio recorder data end.
b.liuf191eb72024-12-12 10:45:23 +0800148 if(audio_info->recorder.recorder_cb) {
149 audio_info->recorder.recorder_cb(NULL, 0);
b.liu1c1c7212023-12-22 16:35:27 +0800150 }
151 return;
152}
153
154
b.liuf191eb72024-12-12 10:45:23 +0800155// srcdst = 1;/* 0-None, 1-Near end, 2-Far end, 3-Both ends */
156// priority = 1;/* 0-Do not combine(override), 1-Combine */
157// dest = 1;/* 0-Near codec, 1-Near Vocoder */
158static int config_parameters(mbtk_audio_direction_enum direction, mbtk_audio_sample_rate_enum NBWB,
159 unsigned int srcdst, unsigned int priority, unsigned int dest)
b.liu1c1c7212023-12-22 16:35:27 +0800160{
b.liu1c1c7212023-12-22 16:35:27 +0800161 char kvpair[128];
162 struct str_parms *param = NULL;
163 int data[5];
164 const char *key = NULL;
165 bool update_vcm = false;
166
b.liu1c1c7212023-12-22 16:35:27 +0800167 if(direction == MBTK_AUDIO_DIRECTION_OUTPUT){//output
168 if(NBWB == MBTK_AUDIO_SAMPLE_RATE_8000)
169 audio_info->playback_size = MBTK_PCM_NB_BUF_SIZE;
170 else
171 audio_info->playback_size = MBTK_PCM_WB_BUF_SIZE;
172
173 LOGD("config playback parameters.");
174 }
175 else if(direction == MBTK_AUDIO_DIRECTION_INPUT){//input
176 if(NBWB == MBTK_AUDIO_SAMPLE_RATE_8000)
177 audio_info->playback_size = MBTK_PCM_NB_BUF_SIZE;
178 else
179 audio_info->playback_size = MBTK_PCM_WB_BUF_SIZE;
180
181 LOGD("config record parameters.");
182 }
183
184 memset(kvpair, 0x00, sizeof(kvpair));
185 sprintf(kvpair, "%s=%d;%s=%d;%s=%d;%s=%d;%s=%d", VCM_CONFIG_DIRECTION, direction,
186 VCM_CONFIG_TYPE, NBWB, VCM_CONFIG_SRC_DST, srcdst,
187 VCM_CONFIG_PRIORITY, priority, VCM_CONFIG_DEST, dest);
188
189 LOGD("%s: config information kvpair is %s.\n", __FUNCTION__, kvpair);
190
191 //extract the parameter and config from string
192 param = str_parms_create_str(kvpair);
193 if (!param) {
194 LOGE("%s: param create str is null!", __FUNCTION__);
195 return -1;
196 }
197
198 //set vcm configurations
199 key = VCM_CONFIG_DIRECTION;
200 if (str_parms_get_int(param, key, &data[0]) == 0) {
201 update_vcm = true;
202 str_parms_del(param, key);
203 }
204 key = VCM_CONFIG_TYPE;
205 if (str_parms_get_int(param, key, &data[1]) == 0) {
206 update_vcm = true;
207 str_parms_del(param, key);
208 }
209 key = VCM_CONFIG_SRC_DST;
210 if (str_parms_get_int(param, key, &data[2]) == 0) {
211 update_vcm = true;
212 str_parms_del(param, key);
213 }
214 key = VCM_CONFIG_PRIORITY;
215 if (str_parms_get_int(param, key, &data[3]) == 0) {
216 update_vcm = true;
217 str_parms_del(param, key);
218 }
219 key = VCM_CONFIG_DEST;
220 if (str_parms_get_int(param, key, &data[4]) == 0) {
221 update_vcm = true;
222 str_parms_del(param, key);
223 }
224
225 //printf("Direction is %d, Type is %d, Src_Dst is %d, Priority is %d, Dest is %d. \n",data[0], data[1], data[2], data[3], data[4]);
226
227 if (update_vcm) {
b.liu9e8584b2024-11-06 19:21:28 +0800228 configure_vcm((unsigned int*)data); /*TODO check if all inputs got all values successfully*/
b.liu1c1c7212023-12-22 16:35:27 +0800229 }
230
231 return 0;
232}
233
234int mbtk_audio_pcm_init()
235{
236 //mbtk_log_init("radio", "MBTK_AUDIO");
237 // Audio is running...
238 if(lock_get()) {
239 return -1;
240 }
241
242 if(audio_info) {
243 return 0;
244 }
245
246 audio_info = (audio_inter_info_t*)malloc(sizeof(audio_inter_info_t));
247 if(audio_info == NULL) {
248 LOGE("malloc() fail:%d", errno);
249 return -1;
250 }
251 memset(audio_info, 0x00, sizeof(audio_inter_info_t));
252
253 // Set default audio parameter.
254 audio_info->channel = 1;
255 audio_info->sample_rate = MBTK_AUDIO_SAMPLE_RATE_8000;
256 audio_info->playback_size = MBTK_PCM_NB_BUF_SIZE;
257
258 audio_info->audio_ahw_dev_ubus = audio_hal_install();
259 if (audio_info->audio_ahw_dev_ubus == NULL) {
260 LOGE("audio_hal_install() failed!");
261 goto init_fail;
262 }
263 return 0;
264init_fail:
265 free(audio_info);
266 audio_info = NULL;
267 return -1;
268}
269
b.liud0ea5642024-10-17 10:28:51 +0800270void mbtk_audio_pa_func_set(mbtk_audio_pa_switch_func pa_switch_func)
271{
272 audio_pa_switch_func = pa_switch_func;
273}
274
275void mbtk_audio_volume_set_func_set(mbtk_audio_volume_set_func volume_set_func)
276{
277 audio_volume_set_func = volume_set_func;
278}
279
b.liu1c1c7212023-12-22 16:35:27 +0800280int mbtk_audio_pcm_sample_rate_set(mbtk_audio_sample_rate_enum sample_rate)
281{
282 if(!audio_info) {
283 LOGE("Not inited.");
284 return -1;
285 }
286
287 audio_info->sample_rate = sample_rate;
288
289 return 0;
290}
291
b.liuf191eb72024-12-12 10:45:23 +0800292int audio_pcm_play_start(unsigned int srcdst, unsigned int priority, unsigned int dest)
b.liu1c1c7212023-12-22 16:35:27 +0800293{
294 if(!audio_info) {
295 LOGE("Not inited.");
296 return -1;
297 }
298
299 if(!audio_info->audio_ahw_dev_ubus) {
300 LOGE("audio_info->audio_ahw_dev_ubus is NULL.");
301 return -1;
302 }
303
b.liuf191eb72024-12-12 10:45:23 +0800304 config_parameters(MBTK_AUDIO_DIRECTION_OUTPUT, audio_info->sample_rate, srcdst, priority, dest);
b.liu1c1c7212023-12-22 16:35:27 +0800305
306 int rc = audio_info->audio_ahw_dev_ubus->open_output_stream(audio_info->audio_ahw_dev_ubus, 0,
307 audio_info->audio_ahw_dev_ubus->get_supported_devices(audio_info->audio_ahw_dev_ubus),
b.liuf191eb72024-12-12 10:45:23 +0800308 AUDIO_OUTPUT_FLAG_DIRECT, NULL, &(audio_info->play.stream_out), 0);
b.liu1c1c7212023-12-22 16:35:27 +0800309 if (rc < 0) {
310 LOGE("Open output device fail:%d", rc);
311 goto play_start_fail;
312 }
313
314 audio_info->direction = MBTK_AUDIO_DIRECTION_OUTPUT;
b.liuf191eb72024-12-12 10:45:23 +0800315 audio_info->play.buff_remain_len = 0;
b.liud0ea5642024-10-17 10:28:51 +0800316 audio_pcm_write_count = 0;
b.liu1c1c7212023-12-22 16:35:27 +0800317
318 return 0;
319play_start_fail:
320
321 return -1;
322}
323
b.liuf191eb72024-12-12 10:45:23 +0800324// Send PCM to the other end of the voice.
325int mbtk_audio_voice_pcm_playback_start()
326{
327 // direction = 0;/* 0-play, 1-record */
328 // type = 0/1; /* 0:PCM_NB_BUF_SIZE, 1:PCM_WB_BUF_SIZE */
329 // srcdst = 2;/* 0-None, 1-Near end, 2-Far end, 3-Both ends */
330 // priority = 0;/* 0-Do not combine(override), 1-Combine */
331 // dest = 0;/* 0-Near codec, 1-Near Vocoder */
332 return audio_pcm_play_start(2, 0, 0);
333#if 0
334 if(!audio_info) {
335 LOGE("Not inited.");
336 return -1;
337 }
338
339 if(!audio_info->audio_ahw_dev_ubus) {
340 LOGE("audio_info->audio_ahw_dev_ubus is NULL.");
341 return -1;
342 }
343
344 config_parameters(MBTK_AUDIO_DIRECTION_OUTPUT, audio_info->sample_rate, 2, 0, 0);
345 audio_info->play.is_voip = TRUE;
346
347 return 0;
348#endif
349}
350
351// Send PCM to location SPK.
352int mbtk_audio_pcm_play_start()
353{
354 return audio_pcm_play_start(1, 1, 1);
355}
356
b.liu1c1c7212023-12-22 16:35:27 +0800357int mbtk_audio_pcm_play_data_send(const void* data,uint32 data_len)
358{
359 UNUSED(data);
360 UNUSED(data_len);
361
362 if(!audio_info) {
363 LOGE("Not inited.");
364 return -1;
365 }
366
b.liuf191eb72024-12-12 10:45:23 +0800367 if(!audio_info->play.stream_out) {
b.liu1c1c7212023-12-22 16:35:27 +0800368 LOGE("Output device not open.");
369 return -1;
370 }
371
372 uint32 index = 0;
373 // There are remaining data from the previous package。
b.liuf191eb72024-12-12 10:45:23 +0800374 if(audio_info->play.buff_remain_len > 0) {
b.liu1c1c7212023-12-22 16:35:27 +0800375 // Too less for one package.
b.liuf191eb72024-12-12 10:45:23 +0800376 if(data_len + audio_info->play.buff_remain_len < audio_info->playback_size) {
b.liu1c1c7212023-12-22 16:35:27 +0800377 AUDIO_LOG("Save remain data : len - %d", data_len);
b.liuf191eb72024-12-12 10:45:23 +0800378 memcpy(audio_info->play.buff_remain + audio_info->play.buff_remain_len, data, data_len);
379 audio_info->play.buff_remain_len += data_len;
b.liu1c1c7212023-12-22 16:35:27 +0800380 return data_len;
381 } else {
b.liuf191eb72024-12-12 10:45:23 +0800382 AUDIO_LOG("Write remain data : %d + %d", audio_info->play.buff_remain_len, audio_info->playback_size - audio_info->play.buff_remain_len);
383 memcpy(audio_info->play.buff_remain + audio_info->play.buff_remain_len, data, audio_info->playback_size - audio_info->play.buff_remain_len);
b.liu1c1c7212023-12-22 16:35:27 +0800384
b.liuf191eb72024-12-12 10:45:23 +0800385 int rc = audio_info->play.stream_out->write(audio_info->play.stream_out, audio_info->play.buff_remain, audio_info->playback_size);
b.liu1c1c7212023-12-22 16:35:27 +0800386 if (rc < 0) {
387 LOGE("%s: error writing (child).", __FUNCTION__);
388 goto send_fail;
389 } else if (rc < (signed int)audio_info->playback_size) {
390 LOGW("%s: wrote less than buffer size, rc=%d.", __FUNCTION__, rc);
391 index += rc;
392 goto send_fail;
393 }
394
b.liud0ea5642024-10-17 10:28:51 +0800395 if(audio_pcm_write_count < 3) {
396 audio_pcm_write_count++;
397 if(audio_pcm_write_count == 3) {
398 // Set audio volume.
399 if(audio_volume_set_func) {
400 audio_volume_set_func();
401 }
402
403 // Open PA
404 if(audio_pa_switch_func) {
405 audio_pa_switch_func(TRUE);
406 }
407 }
408 }
409
b.liuf191eb72024-12-12 10:45:23 +0800410 index += (audio_info->playback_size - audio_info->play.buff_remain_len);
411 audio_info->play.buff_remain_len = 0;
b.liu1c1c7212023-12-22 16:35:27 +0800412 }
413 }
414
415 while(data_len - index >= audio_info->playback_size) {
416 AUDIO_LOG("Package : %d -> %d", index, index + audio_info->playback_size - 1);
b.liuf191eb72024-12-12 10:45:23 +0800417 int rc = audio_info->play.stream_out->write(audio_info->play.stream_out, (const char*)data + index, audio_info->playback_size);
b.liu1c1c7212023-12-22 16:35:27 +0800418 if (rc < 0) {
419 LOGE("%s: error writing (child).", __FUNCTION__);
420 goto send_fail;
421 } else if (rc < (signed int)audio_info->playback_size) {
422 LOGW("%s: wrote less than buffer size, rc=%d.", __FUNCTION__, rc);
423 goto send_fail;
424 }
425
426 index += rc;
427 }
428
429 // Last package.( less then audio_info->playback_size)
430 // Save to buffer audio_info->play_buff_remain
431 if(data_len - index > 0) {
432 AUDIO_LOG("Save remain data : len - %d", data_len - index);
b.liuf191eb72024-12-12 10:45:23 +0800433 memcpy(audio_info->play.buff_remain, data + index, data_len - index);
434 audio_info->play.buff_remain_len = data_len - index;
b.liu1c1c7212023-12-22 16:35:27 +0800435 }
436
437 return data_len;
438send_fail:
439 return -1;
440}
441
442int mbtk_audio_pcm_play_stop()
443{
444 if(!audio_info) {
445 LOGE("Not inited.");
446 return -1;
447 }
448
b.liuf191eb72024-12-12 10:45:23 +0800449 if(!audio_info->play.stream_out) {
b.liu1c1c7212023-12-22 16:35:27 +0800450 LOGE("Output device not open.");
451 return -1;
452 }
453
454 // Write last package.
b.liuf191eb72024-12-12 10:45:23 +0800455 if(audio_info->play.buff_remain_len > 0) {
b.liu1c1c7212023-12-22 16:35:27 +0800456 char buf[MBTK_PCM_WB_BUF_SIZE];
457 memset(buf, 0x00, sizeof(buf));
b.liuf191eb72024-12-12 10:45:23 +0800458 memcpy(buf, audio_info->play.buff_remain, audio_info->play.buff_remain_len);
b.liu1c1c7212023-12-22 16:35:27 +0800459
b.liuf191eb72024-12-12 10:45:23 +0800460 LOGD("len %d is smaller than needed %d, so fill the buffer with 0.", audio_info->play.buff_remain_len, audio_info->playback_size);
b.liu1c1c7212023-12-22 16:35:27 +0800461
b.liuf191eb72024-12-12 10:45:23 +0800462 int rc = audio_info->play.stream_out->write(audio_info->play.stream_out, buf, audio_info->playback_size);
b.liu1c1c7212023-12-22 16:35:27 +0800463 if (rc < 0) {
464 LOGE("%s: error writing (child).", __FUNCTION__);
465 //goto send_fail;
466 } else if (rc < (signed int)audio_info->playback_size) {
467 LOGW("%s: wrote less than buffer size, rc=%d.", __FUNCTION__, rc);
468 //goto send_fail;
469 }
b.liuf191eb72024-12-12 10:45:23 +0800470 audio_info->play.buff_remain_len = 0;
b.liu1c1c7212023-12-22 16:35:27 +0800471 }
472
b.liud0ea5642024-10-17 10:28:51 +0800473 // Close PA
474 if(audio_pa_switch_func) {
475 audio_pa_switch_func(FALSE);
476 }
477
478 vcm_playback_drain(80);//wait for drain the AP audiostub queue.
b.liu1c1c7212023-12-22 16:35:27 +0800479 usleep(80000);//delay 80ms until DSP play out its buffered data.
b.liuf191eb72024-12-12 10:45:23 +0800480 audio_info->play.stream_out->common.standby(&(audio_info->play.stream_out->common));
481 audio_info->audio_ahw_dev_ubus->close_output_stream(audio_info->audio_ahw_dev_ubus, audio_info->play.stream_out);
b.liu1c1c7212023-12-22 16:35:27 +0800482
b.liuf191eb72024-12-12 10:45:23 +0800483 audio_info->play.stream_out = NULL;
b.liu1c1c7212023-12-22 16:35:27 +0800484 return 0;
485}
486
b.liuf191eb72024-12-12 10:45:23 +0800487static int audio_pcm_recorder_start(mbtk_recorder_callback_func recorder_cb,
488 unsigned int srcdst, unsigned int priority, unsigned int dest)
b.liu1c1c7212023-12-22 16:35:27 +0800489{
490 if(!audio_info) {
491 LOGE("Not inited.");
492 return -1;
493 }
494
495 if(!audio_info->audio_ahw_dev_ubus) {
496 LOGE("audio_info->audio_ahw_dev_ubus is NULL.");
497 return -1;
498 }
499
b.liuf191eb72024-12-12 10:45:23 +0800500 if(audio_info->recorder.state != AUDIO_RECORDER_STATE_STOP) {
b.liu1c1c7212023-12-22 16:35:27 +0800501 LOGW("Audio is recorder...");
502 return -1;
503 }
504
b.liuf191eb72024-12-12 10:45:23 +0800505 config_parameters(MBTK_AUDIO_DIRECTION_INPUT, audio_info->sample_rate, srcdst, priority, dest);
b.liu1c1c7212023-12-22 16:35:27 +0800506
507 VCMInit();
508
509 int rc = audio_info->audio_ahw_dev_ubus->open_input_stream(audio_info->audio_ahw_dev_ubus, 0,
510 audio_info->audio_ahw_dev_ubus->get_supported_devices(audio_info->audio_ahw_dev_ubus),
b.liuf191eb72024-12-12 10:45:23 +0800511 NULL, &(audio_info->recorder.stream_in), 0, 0, AUDIO_SOURCE_VOICE_CALL);
b.liu1c1c7212023-12-22 16:35:27 +0800512 if (rc < 0) {
513 LOGE("Open input device fail:%d", rc);
514 goto recorder_start_fail;
515 }
516
517 audio_info->direction = MBTK_AUDIO_DIRECTION_INPUT;
b.liuf191eb72024-12-12 10:45:23 +0800518 audio_info->recorder.recorder_cb = recorder_cb;
b.liu1c1c7212023-12-22 16:35:27 +0800519
520 pthread_attr_t thread_attr;
521 pthread_attr_init(&thread_attr);
522 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
523 {
524 LOGE("pthread_attr_setdetachstate() fail.");
525 return -1;
526 }
527
528 if (pthread_create(&recorder_thread_play, NULL, (void *)&audio_recorder_thread, NULL) < 0) {
529 LOGE("%s: error creating thread_recorder!", __FUNCTION__);
530 return -1;
531 }
532
533 return 0;
534recorder_start_fail:
535
536 return -1;
537}
538
b.liuf191eb72024-12-12 10:45:23 +0800539// Get PCM from the other end of the voice.
540int mbtk_audio_voice_pcm_record_start(mbtk_recorder_callback_func recorder_cb)
541{
542 // direction = 1;/* 0-play, 1-record */
543 // type = 0/1; /* 0:PCM_NB_BUF_SIZE, 1:PCM_WB_BUF_SIZE */
544 // srcdst = 2;/* 0-None, 1-Near end, 2-Far end, 3-Both ends */
545 // priority = 0;/* 0-Do not combine(override), 1-Combine */
546 // dest = 0;/* 0-Near codec, 1-Near Vocoder */
547 return audio_pcm_recorder_start(recorder_cb, 2, 0, 0);
548#if 0
549 if(!audio_info) {
550 LOGE("Not inited.");
551 return -1;
552 }
553
554 if(!audio_info->audio_ahw_dev_ubus) {
555 LOGE("audio_info->audio_ahw_dev_ubus is NULL.");
556 return -1;
557 }
558
559 if(audio_info->recorder.state != AUDIO_RECORDER_STATE_STOP) {
560 LOGW("Audio is recorder...");
561 return -1;
562 }
563
564 config_parameters(MBTK_AUDIO_DIRECTION_INPUT, audio_info->sample_rate, 2, 0, 0);
565 audio_info->recorder.is_voip = TRUE;
566
567 return 0;
568#endif
569}
570
571// Get PCM from location MIC.
572int mbtk_audio_pcm_recorder_start(mbtk_recorder_callback_func recorder_cb)
573{
574 return audio_pcm_recorder_start(recorder_cb, 1, 1, 1);
575}
576
b.liu1c1c7212023-12-22 16:35:27 +0800577int mbtk_audio_pcm_recorder_pause()
578{
579 int result = 0;
b.liuf191eb72024-12-12 10:45:23 +0800580 pthread_mutex_lock(&audio_info->recorder.mutex);
581 if(audio_info->recorder.state == AUDIO_RECORDER_STATE_RUNNING) {
582 audio_info->recorder.state = AUDIO_RECORDER_STATE_PAUSE;
b.liu1c1c7212023-12-22 16:35:27 +0800583 } else {
584 result = -1;
b.liuf191eb72024-12-12 10:45:23 +0800585 LOGW("Audio state : %d", audio_info->recorder.state);
b.liu1c1c7212023-12-22 16:35:27 +0800586 }
b.liuf191eb72024-12-12 10:45:23 +0800587 pthread_mutex_unlock(&audio_info->recorder.mutex);
b.liu1c1c7212023-12-22 16:35:27 +0800588 return result;
589}
590
591int mbtk_audio_pcm_recorder_resume()
592{
593 int result = 0;
b.liuf191eb72024-12-12 10:45:23 +0800594 pthread_mutex_lock(&audio_info->recorder.mutex);
595 if(audio_info->recorder.state == AUDIO_RECORDER_STATE_PAUSE) {
596 audio_info->recorder.state = AUDIO_RECORDER_STATE_RUNNING;
597 pthread_cond_signal(&audio_info->recorder.cond);
b.liu1c1c7212023-12-22 16:35:27 +0800598 } else {
599 result = -1;
b.liuf191eb72024-12-12 10:45:23 +0800600 LOGW("Audio state : %d", audio_info->recorder.state);
b.liu1c1c7212023-12-22 16:35:27 +0800601 }
b.liuf191eb72024-12-12 10:45:23 +0800602 pthread_mutex_unlock(&audio_info->recorder.mutex);
b.liu1c1c7212023-12-22 16:35:27 +0800603 return result;
604}
605
606
607int mbtk_audio_pcm_recorder_stop()
608{
609 int result = 0;
b.liuf191eb72024-12-12 10:45:23 +0800610 pthread_mutex_lock(&audio_info->recorder.mutex);
611 if(audio_info->recorder.state == AUDIO_RECORDER_STATE_PAUSE || audio_info->recorder.state == AUDIO_RECORDER_STATE_RUNNING) {
612 if(audio_info->recorder.state == AUDIO_RECORDER_STATE_PAUSE) {
613 pthread_cond_signal(&audio_info->recorder.cond);
b.liu1c1c7212023-12-22 16:35:27 +0800614 }
b.liuf191eb72024-12-12 10:45:23 +0800615 audio_info->recorder.state = AUDIO_RECORDER_STATE_STOP;
616 pthread_mutex_unlock(&audio_info->recorder.mutex);
b.liu1c1c7212023-12-22 16:35:27 +0800617
618 LOGD("Waitting recorder thread exit...");
619 if (pthread_join(recorder_thread_play, NULL)) {
620 LOGE("error join thread_recorder!");
621 // abort();
622 }
623 LOGD("Recorder thread exit success.");
624 } else {
b.liuf191eb72024-12-12 10:45:23 +0800625 pthread_mutex_unlock(&audio_info->recorder.mutex);
b.liu1c1c7212023-12-22 16:35:27 +0800626 result = -1;
b.liuf191eb72024-12-12 10:45:23 +0800627 LOGW("Audio state : %d", audio_info->recorder.state);
b.liu1c1c7212023-12-22 16:35:27 +0800628 }
629
630 return result;
631}
632
633int mbtk_audio_pcm_deinit()
634{
635 if(!audio_info) {
636 LOGE("Not inited.");
637 return -1;
638 }
639
640 audio_hal_uninstall();
641
642 if(lock_free()) {
643 return -1;
644 }
645
646 free(audio_info);
647 audio_info = NULL;
648 return 0;
649}
650