blob: 82d28ce4c1a24faf31c75f8d0f5872d57d8a8395 [file] [log] [blame]
b.liu1c1c7212023-12-22 16:35:27 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <fcntl.h>
5#include <errno.h>
b.liu9e8584b2024-11-06 19:21:28 +08006#include <cutils/str_parms.h>
b.liu1c1c7212023-12-22 16:35:27 +08007
8#include "mbtk_log.h"
9#include "mbtk_audio_internal.h"
luojianfee10dc2024-07-25 11:34:35 +080010#include "audio_if_audio_hw_mrvl.h"
b.liu1c1c7212023-12-22 16:35:27 +080011
12#define LOCK_FILE "/var/run/mbtk_audio.lock"
13#define AUDIO_DEBUG 0
14
15#define AUDIO_LOG(fmt, args ...) \
16 do{ \
17 if(AUDIO_DEBUG) {LOGD(fmt, ##args);} \
18 } while(0)
19
20extern void* audio_hal_install(void);
21extern void audio_hal_uninstall(void);
22extern void configure_vcm(unsigned int data[]);
23
24static audio_inter_info_t *audio_info = NULL;
25static pthread_t recorder_thread_play;
b.liud0ea5642024-10-17 10:28:51 +080026static mbtk_audio_pa_switch_func audio_pa_switch_func = NULL;
27static mbtk_audio_volume_set_func audio_volume_set_func = NULL;
28static int audio_pcm_write_count = 0;
b.liu1c1c7212023-12-22 16:35:27 +080029
30static int lock_get() {
b.liub3b923a2024-06-06 15:15:49 +080031 int fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0666);
b.liu1c1c7212023-12-22 16:35:27 +080032 if (fd == -1) {
33 LOGE("Open(%s) fail:%d", LOCK_FILE, errno);
34 return -1;
35 }
36 // 尝试对文件进行加锁
37 struct flock fl;
38 fl.l_type = F_WRLCK;
39 fl.l_whence = SEEK_SET;
40 fl.l_start = 0;
41 fl.l_len = 1;
42 int ret = fcntl(fd, F_SETLK, &fl);
43 if (ret == -1) {
44 LOGE("Another instance is running, exiting...");
45 close(fd);
46 return -1;
47 }
48 close(fd);
49 LOGD("Get file lock.");
50 return 0;
51}
52
53static int lock_free() {
b.liub3b923a2024-06-06 15:15:49 +080054 int fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0666);
b.liu1c1c7212023-12-22 16:35:27 +080055 if (fd == -1) {
56 LOGE("Open(%s) fail:%d", LOCK_FILE, errno);
57 return -1;
58 }
59 // 释放文件锁
60 struct flock fl;
61 fl.l_type = F_UNLCK;
62 fl.l_whence = SEEK_SET;
63 fl.l_start = 0;
64 fl.l_len = 1;
65 int ret = fcntl(fd, F_SETLK, &fl);
66 if (ret == -1) {
67 LOGE("Another instance is running, exiting...");
68 close(fd);
69 return -1;
70 }
71
72 LOGD("Free file lock.");
73 return 0;
74}
75
76static void audio_recorder_thread(void *arg)
77{
b.liu9e8584b2024-11-06 19:21:28 +080078 int len, frames = 0;
b.liu1c1c7212023-12-22 16:35:27 +080079 char buff[MBTK_PCM_WB_BUF_SIZE];
80
81 audio_info->info.recorder.state = AUDIO_RECORDER_STATE_RUNNING;
82 pthread_mutex_init(&audio_info->info.recorder.mutex, NULL);
83 pthread_cond_init(&audio_info->info.recorder.cond, NULL);
84
85 while (TRUE) {
86 /* Playback loop */
87 pthread_mutex_lock(&audio_info->info.recorder.mutex);
88 if(audio_info->info.recorder.state == AUDIO_RECORDER_STATE_STOP) {
89 LOGD("Stop recorder...");
90 pthread_mutex_unlock(&audio_info->info.recorder.mutex);
91 break;
92 } else if(audio_info->info.recorder.state == AUDIO_RECORDER_STATE_PAUSE) {
93 pthread_cond_wait(&audio_info->info.recorder.cond, &audio_info->info.recorder.mutex);
94 pthread_mutex_unlock(&audio_info->info.recorder.mutex);
95 continue;
96 } else {
97 pthread_mutex_unlock(&audio_info->info.recorder.mutex);
98 }
99
100 //record the needed format stream from the device.
101 //only read pcm stream, no send command.
102 len = audio_info->info.recorder.stream_in->read(audio_info->info.recorder.stream_in, buff,
103 audio_info->playback_size);
104 if (len <= 0) {
105 LOGE("%s: error reading!", __FUNCTION__);
106 goto thread_end;
107 }
108
109 AUDIO_LOG("Recorder data : len - %d", len);
110
111 if(audio_info->info.recorder.recorder_cb) {
112 audio_info->info.recorder.recorder_cb(buff, len);
113 }
114
115 LOGD("%s: No.%d frame playback.", __FUNCTION__, ++frames);
116 }
117
118
119thread_end:
120 pthread_mutex_destroy(&audio_info->info.recorder.mutex);
121 pthread_cond_destroy(&audio_info->info.recorder.cond);
122
123 audio_info->info.recorder.stream_in->common.standby(&audio_info->info.recorder.stream_in->common);
124 audio_info->audio_ahw_dev_ubus->close_input_stream(audio_info->audio_ahw_dev_ubus, audio_info->info.recorder.stream_in);
125 VCMDeinit();//close the fd of audiostub_ctl when exit the thread.
126 audio_info->info.recorder.stream_in = NULL;
127 LOGD("%s: finished pcm playback.", __FUNCTION__);
128
129 // Notify audio recorder data end.
130 if(audio_info->info.recorder.recorder_cb) {
131 audio_info->info.recorder.recorder_cb(NULL, 0);
132 }
133 return;
134}
135
136
137static int config_parameters(mbtk_audio_direction_enum direction, mbtk_audio_sample_rate_enum NBWB)
138{
139 unsigned int srcdst, priority, dest;
140 char kvpair[128];
141 struct str_parms *param = NULL;
142 int data[5];
143 const char *key = NULL;
144 bool update_vcm = false;
145
146 srcdst = 1;/* 0-None, 1-Near end, 2-Far end, 3-Both ends */
147 priority = 1;/* 0-Do not combine(override), 1-Combine */
148 dest = 1;/* 0-Near codec, 1-Near Vocoder */
149
150 if(direction == MBTK_AUDIO_DIRECTION_OUTPUT){//output
151 if(NBWB == MBTK_AUDIO_SAMPLE_RATE_8000)
152 audio_info->playback_size = MBTK_PCM_NB_BUF_SIZE;
153 else
154 audio_info->playback_size = MBTK_PCM_WB_BUF_SIZE;
155
156 LOGD("config playback parameters.");
157 }
158 else if(direction == MBTK_AUDIO_DIRECTION_INPUT){//input
159 if(NBWB == MBTK_AUDIO_SAMPLE_RATE_8000)
160 audio_info->playback_size = MBTK_PCM_NB_BUF_SIZE;
161 else
162 audio_info->playback_size = MBTK_PCM_WB_BUF_SIZE;
163
164 LOGD("config record parameters.");
165 }
166
167 memset(kvpair, 0x00, sizeof(kvpair));
168 sprintf(kvpair, "%s=%d;%s=%d;%s=%d;%s=%d;%s=%d", VCM_CONFIG_DIRECTION, direction,
169 VCM_CONFIG_TYPE, NBWB, VCM_CONFIG_SRC_DST, srcdst,
170 VCM_CONFIG_PRIORITY, priority, VCM_CONFIG_DEST, dest);
171
172 LOGD("%s: config information kvpair is %s.\n", __FUNCTION__, kvpair);
173
174 //extract the parameter and config from string
175 param = str_parms_create_str(kvpair);
176 if (!param) {
177 LOGE("%s: param create str is null!", __FUNCTION__);
178 return -1;
179 }
180
181 //set vcm configurations
182 key = VCM_CONFIG_DIRECTION;
183 if (str_parms_get_int(param, key, &data[0]) == 0) {
184 update_vcm = true;
185 str_parms_del(param, key);
186 }
187 key = VCM_CONFIG_TYPE;
188 if (str_parms_get_int(param, key, &data[1]) == 0) {
189 update_vcm = true;
190 str_parms_del(param, key);
191 }
192 key = VCM_CONFIG_SRC_DST;
193 if (str_parms_get_int(param, key, &data[2]) == 0) {
194 update_vcm = true;
195 str_parms_del(param, key);
196 }
197 key = VCM_CONFIG_PRIORITY;
198 if (str_parms_get_int(param, key, &data[3]) == 0) {
199 update_vcm = true;
200 str_parms_del(param, key);
201 }
202 key = VCM_CONFIG_DEST;
203 if (str_parms_get_int(param, key, &data[4]) == 0) {
204 update_vcm = true;
205 str_parms_del(param, key);
206 }
207
208 //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]);
209
210 if (update_vcm) {
b.liu9e8584b2024-11-06 19:21:28 +0800211 configure_vcm((unsigned int*)data); /*TODO check if all inputs got all values successfully*/
b.liu1c1c7212023-12-22 16:35:27 +0800212 }
213
214 return 0;
215}
216
217int mbtk_audio_pcm_init()
218{
219 //mbtk_log_init("radio", "MBTK_AUDIO");
220 // Audio is running...
221 if(lock_get()) {
222 return -1;
223 }
224
225 if(audio_info) {
226 return 0;
227 }
228
229 audio_info = (audio_inter_info_t*)malloc(sizeof(audio_inter_info_t));
230 if(audio_info == NULL) {
231 LOGE("malloc() fail:%d", errno);
232 return -1;
233 }
234 memset(audio_info, 0x00, sizeof(audio_inter_info_t));
235
236 // Set default audio parameter.
237 audio_info->channel = 1;
238 audio_info->sample_rate = MBTK_AUDIO_SAMPLE_RATE_8000;
239 audio_info->playback_size = MBTK_PCM_NB_BUF_SIZE;
240
241 audio_info->audio_ahw_dev_ubus = audio_hal_install();
242 if (audio_info->audio_ahw_dev_ubus == NULL) {
243 LOGE("audio_hal_install() failed!");
244 goto init_fail;
245 }
246 return 0;
247init_fail:
248 free(audio_info);
249 audio_info = NULL;
250 return -1;
251}
252
b.liud0ea5642024-10-17 10:28:51 +0800253void mbtk_audio_pa_func_set(mbtk_audio_pa_switch_func pa_switch_func)
254{
255 audio_pa_switch_func = pa_switch_func;
256}
257
258void mbtk_audio_volume_set_func_set(mbtk_audio_volume_set_func volume_set_func)
259{
260 audio_volume_set_func = volume_set_func;
261}
262
b.liu1c1c7212023-12-22 16:35:27 +0800263int mbtk_audio_pcm_sample_rate_set(mbtk_audio_sample_rate_enum sample_rate)
264{
265 if(!audio_info) {
266 LOGE("Not inited.");
267 return -1;
268 }
269
270 audio_info->sample_rate = sample_rate;
271
272 return 0;
273}
274
275int mbtk_audio_pcm_play_start()
276{
277 if(!audio_info) {
278 LOGE("Not inited.");
279 return -1;
280 }
281
282 if(!audio_info->audio_ahw_dev_ubus) {
283 LOGE("audio_info->audio_ahw_dev_ubus is NULL.");
284 return -1;
285 }
286
287 config_parameters(MBTK_AUDIO_DIRECTION_OUTPUT, audio_info->sample_rate);
288
289 int rc = audio_info->audio_ahw_dev_ubus->open_output_stream(audio_info->audio_ahw_dev_ubus, 0,
290 audio_info->audio_ahw_dev_ubus->get_supported_devices(audio_info->audio_ahw_dev_ubus),
291 AUDIO_OUTPUT_FLAG_DIRECT, NULL, &(audio_info->info.play.stream_out), 0);
292 if (rc < 0) {
293 LOGE("Open output device fail:%d", rc);
294 goto play_start_fail;
295 }
296
297 audio_info->direction = MBTK_AUDIO_DIRECTION_OUTPUT;
298 audio_info->info.play.buff_remain_len = 0;
b.liud0ea5642024-10-17 10:28:51 +0800299 audio_pcm_write_count = 0;
b.liu1c1c7212023-12-22 16:35:27 +0800300
301 return 0;
302play_start_fail:
303
304 return -1;
305}
306
307int mbtk_audio_pcm_play_data_send(const void* data,uint32 data_len)
308{
309 UNUSED(data);
310 UNUSED(data_len);
311
312 if(!audio_info) {
313 LOGE("Not inited.");
314 return -1;
315 }
316
317 if(!audio_info->info.play.stream_out) {
318 LOGE("Output device not open.");
319 return -1;
320 }
321
322 uint32 index = 0;
323 // There are remaining data from the previous package。
324 if(audio_info->info.play.buff_remain_len > 0) {
325 // Too less for one package.
326 if(data_len + audio_info->info.play.buff_remain_len < audio_info->playback_size) {
327 AUDIO_LOG("Save remain data : len - %d", data_len);
328 memcpy(audio_info->info.play.buff_remain + audio_info->info.play.buff_remain_len, data, data_len);
329 audio_info->info.play.buff_remain_len += data_len;
330 return data_len;
331 } else {
332 AUDIO_LOG("Write remain data : %d + %d", audio_info->info.play.buff_remain_len, audio_info->playback_size - audio_info->info.play.buff_remain_len);
333 memcpy(audio_info->info.play.buff_remain + audio_info->info.play.buff_remain_len, data, audio_info->playback_size - audio_info->info.play.buff_remain_len);
334
335 int rc = audio_info->info.play.stream_out->write(audio_info->info.play.stream_out, audio_info->info.play.buff_remain, audio_info->playback_size);
336 if (rc < 0) {
337 LOGE("%s: error writing (child).", __FUNCTION__);
338 goto send_fail;
339 } else if (rc < (signed int)audio_info->playback_size) {
340 LOGW("%s: wrote less than buffer size, rc=%d.", __FUNCTION__, rc);
341 index += rc;
342 goto send_fail;
343 }
344
b.liud0ea5642024-10-17 10:28:51 +0800345 if(audio_pcm_write_count < 3) {
346 audio_pcm_write_count++;
347 if(audio_pcm_write_count == 3) {
348 // Set audio volume.
349 if(audio_volume_set_func) {
350 audio_volume_set_func();
351 }
352
353 // Open PA
354 if(audio_pa_switch_func) {
355 audio_pa_switch_func(TRUE);
356 }
357 }
358 }
359
b.liu1c1c7212023-12-22 16:35:27 +0800360 index += (audio_info->playback_size - audio_info->info.play.buff_remain_len);
361 audio_info->info.play.buff_remain_len = 0;
362 }
363 }
364
365 while(data_len - index >= audio_info->playback_size) {
366 AUDIO_LOG("Package : %d -> %d", index, index + audio_info->playback_size - 1);
367 int rc = audio_info->info.play.stream_out->write(audio_info->info.play.stream_out, (const char*)data + index, audio_info->playback_size);
368 if (rc < 0) {
369 LOGE("%s: error writing (child).", __FUNCTION__);
370 goto send_fail;
371 } else if (rc < (signed int)audio_info->playback_size) {
372 LOGW("%s: wrote less than buffer size, rc=%d.", __FUNCTION__, rc);
373 goto send_fail;
374 }
375
376 index += rc;
377 }
378
379 // Last package.( less then audio_info->playback_size)
380 // Save to buffer audio_info->play_buff_remain
381 if(data_len - index > 0) {
382 AUDIO_LOG("Save remain data : len - %d", data_len - index);
383 memcpy(audio_info->info.play.buff_remain, data + index, data_len - index);
384 audio_info->info.play.buff_remain_len = data_len - index;
385 }
386
387 return data_len;
388send_fail:
389 return -1;
390}
391
392int mbtk_audio_pcm_play_stop()
393{
394 if(!audio_info) {
395 LOGE("Not inited.");
396 return -1;
397 }
398
399 if(!audio_info->info.play.stream_out) {
400 LOGE("Output device not open.");
401 return -1;
402 }
403
404 // Write last package.
405 if(audio_info->info.play.buff_remain_len > 0) {
406 char buf[MBTK_PCM_WB_BUF_SIZE];
407 memset(buf, 0x00, sizeof(buf));
408 memcpy(buf, audio_info->info.play.buff_remain, audio_info->info.play.buff_remain_len);
409
410 LOGD("len %d is smaller than needed %d, so fill the buffer with 0.", audio_info->info.play.buff_remain_len, audio_info->playback_size);
411
412 int rc = audio_info->info.play.stream_out->write(audio_info->info.play.stream_out, buf, audio_info->playback_size);
413 if (rc < 0) {
414 LOGE("%s: error writing (child).", __FUNCTION__);
415 //goto send_fail;
416 } else if (rc < (signed int)audio_info->playback_size) {
417 LOGW("%s: wrote less than buffer size, rc=%d.", __FUNCTION__, rc);
418 //goto send_fail;
419 }
420 audio_info->info.play.buff_remain_len = 0;
421 }
422
b.liud0ea5642024-10-17 10:28:51 +0800423 // Close PA
424 if(audio_pa_switch_func) {
425 audio_pa_switch_func(FALSE);
426 }
427
428 vcm_playback_drain(80);//wait for drain the AP audiostub queue.
b.liu1c1c7212023-12-22 16:35:27 +0800429 usleep(80000);//delay 80ms until DSP play out its buffered data.
430 audio_info->info.play.stream_out->common.standby(&(audio_info->info.play.stream_out->common));
431 audio_info->audio_ahw_dev_ubus->close_output_stream(audio_info->audio_ahw_dev_ubus, audio_info->info.play.stream_out);
432
433 audio_info->info.play.stream_out = NULL;
434 return 0;
435}
436
437
438int mbtk_audio_pcm_recorder_start(mbtk_recorder_callback_func recorder_cb)
439{
440 if(!audio_info) {
441 LOGE("Not inited.");
442 return -1;
443 }
444
445 if(!audio_info->audio_ahw_dev_ubus) {
446 LOGE("audio_info->audio_ahw_dev_ubus is NULL.");
447 return -1;
448 }
449
450 if(audio_info->info.recorder.state != AUDIO_RECORDER_STATE_STOP) {
451 LOGW("Audio is recorder...");
452 return -1;
453 }
454
455 config_parameters(MBTK_AUDIO_DIRECTION_INPUT, audio_info->sample_rate);
456
457 VCMInit();
458
459 int rc = audio_info->audio_ahw_dev_ubus->open_input_stream(audio_info->audio_ahw_dev_ubus, 0,
460 audio_info->audio_ahw_dev_ubus->get_supported_devices(audio_info->audio_ahw_dev_ubus),
461 NULL, &(audio_info->info.recorder.stream_in), 0, 0, AUDIO_SOURCE_VOICE_CALL);
462 if (rc < 0) {
463 LOGE("Open input device fail:%d", rc);
464 goto recorder_start_fail;
465 }
466
467 audio_info->direction = MBTK_AUDIO_DIRECTION_INPUT;
468 audio_info->info.recorder.recorder_cb = recorder_cb;
469
470 pthread_attr_t thread_attr;
471 pthread_attr_init(&thread_attr);
472 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
473 {
474 LOGE("pthread_attr_setdetachstate() fail.");
475 return -1;
476 }
477
478 if (pthread_create(&recorder_thread_play, NULL, (void *)&audio_recorder_thread, NULL) < 0) {
479 LOGE("%s: error creating thread_recorder!", __FUNCTION__);
480 return -1;
481 }
482
483 return 0;
484recorder_start_fail:
485
486 return -1;
487}
488
489int mbtk_audio_pcm_recorder_pause()
490{
491 int result = 0;
492 pthread_mutex_lock(&audio_info->info.recorder.mutex);
493 if(audio_info->info.recorder.state == AUDIO_RECORDER_STATE_RUNNING) {
494 audio_info->info.recorder.state = AUDIO_RECORDER_STATE_PAUSE;
495 } else {
496 result = -1;
497 LOGW("Audio state : %d", audio_info->info.recorder.state);
498 }
499 pthread_mutex_unlock(&audio_info->info.recorder.mutex);
500 return result;
501}
502
503int mbtk_audio_pcm_recorder_resume()
504{
505 int result = 0;
506 pthread_mutex_lock(&audio_info->info.recorder.mutex);
507 if(audio_info->info.recorder.state == AUDIO_RECORDER_STATE_PAUSE) {
508 audio_info->info.recorder.state = AUDIO_RECORDER_STATE_RUNNING;
509 pthread_cond_signal(&audio_info->info.recorder.cond);
510 } else {
511 result = -1;
512 LOGW("Audio state : %d", audio_info->info.recorder.state);
513 }
514 pthread_mutex_unlock(&audio_info->info.recorder.mutex);
515 return result;
516}
517
518
519int mbtk_audio_pcm_recorder_stop()
520{
521 int result = 0;
522 pthread_mutex_lock(&audio_info->info.recorder.mutex);
523 if(audio_info->info.recorder.state == AUDIO_RECORDER_STATE_PAUSE || audio_info->info.recorder.state == AUDIO_RECORDER_STATE_RUNNING) {
524 if(audio_info->info.recorder.state == AUDIO_RECORDER_STATE_PAUSE) {
525 pthread_cond_signal(&audio_info->info.recorder.cond);
526 }
527 audio_info->info.recorder.state = AUDIO_RECORDER_STATE_STOP;
528 pthread_mutex_unlock(&audio_info->info.recorder.mutex);
529
530 LOGD("Waitting recorder thread exit...");
531 if (pthread_join(recorder_thread_play, NULL)) {
532 LOGE("error join thread_recorder!");
533 // abort();
534 }
535 LOGD("Recorder thread exit success.");
536 } else {
537 pthread_mutex_unlock(&audio_info->info.recorder.mutex);
538 result = -1;
539 LOGW("Audio state : %d", audio_info->info.recorder.state);
540 }
541
542 return result;
543}
544
545int mbtk_audio_pcm_deinit()
546{
547 if(!audio_info) {
548 LOGE("Not inited.");
549 return -1;
550 }
551
552 audio_hal_uninstall();
553
554 if(lock_free()) {
555 return -1;
556 }
557
558 free(audio_info);
559 audio_info = NULL;
560 return 0;
561}
562
luojianfee10dc2024-07-25 11:34:35 +0800563
564typedef enum {
565 AUD_PLAYER_ERROR = -1,
566 AUD_PLAYER_START = 0,
567 AUD_PLAYER_PAUSE,
568 AUD_PLAYER_RESUME,
569 AUD_PLAYER_NODATA, //Buff no data and play tread will sleep
570 AUD_PLAYER_LESSDATA, //Buff has less data
571 AUD_PLAYER_FINISHED,
572} Enum_AudPlayer_State;
573
574struct mopen_audio_t
575{
576 int device;
577 audio_hw_device_t *audio_ahw_dev_ubus;
578 struct audio_stream_in *stream_in;
579 struct audio_stream_out *stream_out;
580 int pcm_packet_size; //320:NB, 640:WB
581 int pipe_data;
582 int fd[2];
583 pthread_t pid;
584 mbtk_audio_state_enum state;
585 pthread_mutex_t _cond_mutex;
586 pthread_mutex_t _stream_mutex;
587 void *usrData;
588};
589
590static struct mopen_audio_t *internal_hdl = NULL;
b.liu9e8584b2024-11-06 19:21:28 +0800591typedef int (*_play_callback)(void *hdl, int result);
luojianfee10dc2024-07-25 11:34:35 +0800592
593
594static int config_parameters_new(int in_out, int NBWB)
595{
596 unsigned int direction = 0xFF, type, srcdst, priority, dest;
597 char kvpair[128];
598 struct str_parms *param = NULL;
599 int data[5];
600 const char *key = NULL;
601 bool update_vcm = false;
602
603 direction = in_out;/* 0-play, 1-record */
604 type = NBWB; /* 0:PCM_NB_BUF_SIZE, 1:PCM_WB_BUF_SIZE */
605 srcdst = 1;/* 0-None, 1-Near end, 2-Far end, 3-Both ends */
606 priority = 1;/* 0-Do not combine(override), 1-Combine */
607 dest = 1;/* 0-Near codec, 1-Near Vocoder */
608
609 memset(kvpair, 0x00, sizeof(kvpair));
610 sprintf(kvpair, "%s=%d;%s=%d;%s=%d;%s=%d;%s=%d", VCM_CONFIG_DIRECTION, direction,
611 VCM_CONFIG_TYPE, type, VCM_CONFIG_SRC_DST, srcdst,
612 VCM_CONFIG_PRIORITY, priority, VCM_CONFIG_DEST, dest);
613
614 LOGD("%s: config information kvpair is %s.\n", __FUNCTION__, kvpair);
615
616 //extract the parameter and config from string
617 param = str_parms_create_str(kvpair);
618 if (!param) {
619 printf("%s: param create str is null!", __FUNCTION__);
620 return -1;
621 }
622
623 //set vcm configurations
624 key = VCM_CONFIG_DIRECTION;
625 if (str_parms_get_int(param, key, &data[0]) == 0) {
626 update_vcm = true;
627 str_parms_del(param, key);
628 }
629 key = VCM_CONFIG_TYPE;
630 if (str_parms_get_int(param, key, &data[1]) == 0) {
631 update_vcm = true;
632 str_parms_del(param, key);
633 }
634 key = VCM_CONFIG_SRC_DST;
635 if (str_parms_get_int(param, key, &data[2]) == 0) {
636 update_vcm = true;
637 str_parms_del(param, key);
638 }
639 key = VCM_CONFIG_PRIORITY;
640 if (str_parms_get_int(param, key, &data[3]) == 0) {
641 update_vcm = true;
642 str_parms_del(param, key);
643 }
644 key = VCM_CONFIG_DEST;
645 if (str_parms_get_int(param, key, &data[4]) == 0) {
646 update_vcm = true;
647 str_parms_del(param, key);
648 }
649
650 //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]);
651
652 if (update_vcm) {
b.liu9e8584b2024-11-06 19:21:28 +0800653 configure_vcm((unsigned int*)data); /*TODO check if all inputs got all values successfully*/
luojianfee10dc2024-07-25 11:34:35 +0800654 }
655
656 return 0;
657}
658
659static int audio_open_pcm_new(void *dev_hdl, int num_channels, int rate, int in_out)
660{
661 struct mopen_audio_t *pcxt = (struct mopen_audio_t *)dev_hdl;
662 int nb_wb;
663
664 //Support 8k/16k & mono wave file
665 if (((rate != 8000) && (rate != 16000))
666 || (num_channels != 1) ) {
667 LOGD("%s: error wave file:rate = %d, num_channels = %d!! \n",
668 __FUNCTION__,rate, num_channels);
669 return -1;
670 }
671
672 LOGD("%s: success open, rate = %d, num_channels = %d.\n",
673 __FUNCTION__, rate, num_channels);
674
675 if ((8000 == rate) && (1 == num_channels)) {
676 nb_wb = 0;//NB
677 pcxt->pcm_packet_size = 320;
678 } else if ((16000 == rate) && (1 == num_channels)) {
679 nb_wb = 1;//WB
680 pcxt->pcm_packet_size = 640;
b.liu9e8584b2024-11-06 19:21:28 +0800681 } else {
682 return -1;
luojianfee10dc2024-07-25 11:34:35 +0800683 }
684
685 //config playback parameters.
686 config_parameters_new(in_out, nb_wb);
687 pcxt->device = in_out;
688 return 0;
689}
690
691static void mbtk_audio_set_status_new(void* hdl, mbtk_audio_state_enum _status)
692{
693 struct mopen_audio_t *pcxt = (struct mopen_audio_t *)hdl;
694 if (NULL == hdl || NULL == internal_hdl)
b.liu9e8584b2024-11-06 19:21:28 +0800695 return;
luojianfee10dc2024-07-25 11:34:35 +0800696 pthread_mutex_lock(&pcxt->_cond_mutex);
697 pcxt->state = _status;
698 pthread_mutex_unlock(&pcxt->_cond_mutex);
699}
700
701mbtk_audio_handle mbtk_audio_open_new(mbtk_audio_dev_enum dev, int flag, int rate, void *usrData)
702{
luojianfee10dc2024-07-25 11:34:35 +0800703 struct mopen_audio_t *aud_hdl = NULL;
704 int ret;
b.liubcf86c92024-08-19 19:48:28 +0800705
luojianfee10dc2024-07-25 11:34:35 +0800706 if(internal_hdl)
707 {
708 printf("Audio device inited\n");
709 return internal_hdl;
710 }
711
712 aud_hdl = (struct mopen_audio_t *) calloc(1, sizeof(struct mopen_audio_t));
713 if (!aud_hdl)
714 {
luojiande236232024-07-27 10:51:57 +0800715 LOGD("\n%s:Failed to allocate audio hdl!, errno=%d\n", __FUNCTION__, errno);
luojianfee10dc2024-07-25 11:34:35 +0800716 return NULL;
717 }
718 memset(aud_hdl, 0, sizeof(struct mopen_audio_t));
luojiande236232024-07-27 10:51:57 +0800719 LOGD("mbtk_audio_open() success aud_hdl:%p\n", aud_hdl);
luojianfee10dc2024-07-25 11:34:35 +0800720
721 //init global variables
722 aud_hdl->audio_ahw_dev_ubus = audio_hal_install();
723 if (aud_hdl->audio_ahw_dev_ubus == NULL) {
724 LOGD("%s: audio_hal_install failed!\n", __FUNCTION__);
725 goto error;
726 }
727
728 ret = audio_open_pcm_new(aud_hdl, flag, rate, dev);
729 if (ret)
730 {
731 LOGD("\n%s: pcm open error, errno=%d\n", __FUNCTION__, errno);
732 goto error;
733 }
734
735 ret = aud_hdl->audio_ahw_dev_ubus->open_output_stream(aud_hdl->audio_ahw_dev_ubus, 0,
736 aud_hdl->audio_ahw_dev_ubus->get_supported_devices(aud_hdl->audio_ahw_dev_ubus),
737 AUDIO_OUTPUT_FLAG_DIRECT, NULL, &aud_hdl->stream_out, 0);
738
739 if (ret < 0) {
740 LOGD("%s: error opening output device. rc = %d\n", __FUNCTION__, ret);
741 goto error;
742 }
743
744 pthread_mutex_init(&aud_hdl->_cond_mutex, NULL);
745 aud_hdl->usrData = usrData;
746 aud_hdl->state = AUDIO_OPEN;
747 /* printf("Mbtk_Audio_Open aud_hdl[%x][%x][%x]\n", aud_hdl, aud_hdl->_mixer_ctl, aud_hdl->_pcm); */
748 internal_hdl = aud_hdl;
749
luojiande236232024-07-27 10:51:57 +0800750 LOGD("mbtk_audio_open() success aud_hdl:%p\n", aud_hdl);
luojianfee10dc2024-07-25 11:34:35 +0800751 return (void *)aud_hdl;
752
753error:
luojianfee10dc2024-07-25 11:34:35 +0800754 free(aud_hdl);
755 return NULL;
756}
757
yu.dongbe938702024-11-01 04:11:35 -0700758int mbtk_audio_playback_set_block_flag(mbtk_audio_handle handle, int flags)
759{
760 if (handle == NULL) {
761 LOGE("Invalid handle: NULL");
762 return -1;
763 }
764
765 if (flags < 0) {
766 LOGE("Invalid flags: %d", flags);
767 return -1;
768 }
769
770 LOGD("Setting block flag: %d", flags);
771
772 return 0;
773}
774
luojianfee10dc2024-07-25 11:34:35 +0800775int mbtk_audio_play_file_new(void *dev_hdl, int file_fd, int offset)
776{
777 unsigned bufsize = 0;
778 char *data = NULL;
779 int first_set = 0;
780 int file_data_sz = 0;
781 int res = 0;
782 int ret;
783
luojianfee10dc2024-07-25 11:34:35 +0800784 struct mopen_audio_t *pcxt = (struct mopen_audio_t *)dev_hdl;
785 _play_callback audio_play_cb = (_play_callback)pcxt->usrData;
786 if (NULL == dev_hdl || NULL == internal_hdl)
787 return -1;
788
b.liubcf86c92024-08-19 19:48:28 +0800789
luojiande236232024-07-27 10:51:57 +0800790 LOGD("mbtk_audio_play_file_new() dev_hdl:%p\n", dev_hdl);
luojianfee10dc2024-07-25 11:34:35 +0800791
792 if(AUDIO_RUNNING == pcxt->state)
793 return -2;
794
795 // file_data_sz = mbtk_wav_pcm16Le_check(file_fd);
796 bufsize = pcxt->pcm_packet_size;
797 data = calloc(1, bufsize);
798 if (!data) {
799 fprintf(stderr, "\n%s:could not allocate %d bytes\n",__FUNCTION__,bufsize);
800 pthread_exit(NULL);
801 }
802 if(offset)
803 {
804 lseek(file_fd, offset, SEEK_SET);
805 }
806
807 mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
808 int all_size = 0;
809
luojian82fd38a2024-07-25 14:20:51 +0800810 // system("echo 1 >/sys/class/gpio/gpio19/value");
luojianfee10dc2024-07-25 11:34:35 +0800811 while (pcxt->state != AUDIO_STOP)
812 {
813 res = read(file_fd, data, bufsize);
814 // printf("%s:read : %d bytes\n", __FUNCTION__, res);
815 if(res == 0 || res < 0)
816 {
b.liubcf86c92024-08-19 19:48:28 +0800817 LOGD("read:[%d]", res);
luojianfee10dc2024-07-25 11:34:35 +0800818 break;
819 }
820
821 all_size += res;
822// if (file_data_sz < all_size || file_data_sz == all_size) {
823// printf("aplay size :%d - %d\n", file_data_sz, all_size);
824 // break;
825 // }
826
827 while(AUDIO_PAUSE == pcxt->state)
828 {
829 usleep(80000);
830 audio_play_cb(pcxt, AUD_PLAYER_PAUSE);
831 }
832
833 if ((0 == first_set || AUDIO_RESUME == pcxt->state))
834 {
835 first_set = 1;
836 mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
837 audio_play_cb(pcxt, AUD_PLAYER_RESUME);
838 }
839
840 ret = pcxt->stream_out->write(pcxt->stream_out, data, bufsize);
841 if (ret < 0) {
842 LOGD("%s: error writing (child).\n", __FUNCTION__);
843 audio_play_cb(pcxt, AUD_PLAYER_ERROR);
844 break;
845 } else if (ret < (signed int)pcxt->pcm_packet_size) {
846 LOGD("%s: wrote less than buffer size, rc=%d.\n", __FUNCTION__, ret);
847 audio_play_cb(pcxt, AUD_PLAYER_LESSDATA);
848 break;
849 }
850
851 }
852 if (audio_play_cb)
853 audio_play_cb(pcxt, AUD_PLAYER_FINISHED);
854
855 LOGD("file_data_sz :%d - all_size: %d\n", file_data_sz, all_size);
856 mbtk_audio_set_status_new(dev_hdl, AUDIO_OPEN);
857 free(data);
luojian82fd38a2024-07-25 14:20:51 +0800858// system("echo 0 >/sys/class/gpio/gpio19/value");
luojianfee10dc2024-07-25 11:34:35 +0800859
860 return 0;
861}
862
863int mbtk_audio_play_stream_new(void *dev_hdl, const void *pData, int len, int gain )
864{
865 unsigned bufsize = 0;
866 char *data = NULL;
867 int first_set = 0;
luojianfee10dc2024-07-25 11:34:35 +0800868 int ret = 0;
869 int read_size = 0;
870 char *p = (char *)pData;
871
872 char cmd[128] = {0};
873 bool flay_flag = TRUE;
874 int i = 0;
875
876 struct mopen_audio_t *pcxt = (struct mopen_audio_t *)dev_hdl;
877
878 if (NULL == dev_hdl || NULL == internal_hdl || pData == NULL)
879 return -1;
880
luojiande236232024-07-27 10:51:57 +0800881 LOGD("mbtk_audio_play_stream_new() dev_hdl:%p\n", dev_hdl);
882
luojianfee10dc2024-07-25 11:34:35 +0800883 if(AUDIO_RUNNING == pcxt->state)
884 return -2;
885
886 bufsize = pcxt->pcm_packet_size;
887 data = calloc(1, bufsize);
888 if (!data) {
889 fprintf(stderr, "\n%s:could not allocate %d bytes\n",__FUNCTION__,bufsize);
890 pthread_exit(NULL);
891 }
892
893 if(pcxt->state == AUDIO_OPEN)
894 {
895 mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
896
897 }
898
899 // system("echo 1 >/sys/class/gpio/gpio19/value");
900 while (pcxt->state != AUDIO_STOP)
901 {
902
903 memcpy(data,p+read_size, bufsize );
904 read_size += bufsize;
905
906 if(read_size > len)
907 {
b.liubcf86c92024-08-19 19:48:28 +0800908 // printf(">[%d]\n", read_size);
luojianfee10dc2024-07-25 11:34:35 +0800909 break;
910 }
911
912 while(AUDIO_PAUSE == pcxt->state)
913 {
914 usleep(80000);
915 }
916
917 if ((0 == first_set || AUDIO_RESUME == pcxt->state))
918 {
919 first_set = 1;
920 mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
921 }
922
923 ret = pcxt->stream_out->write(pcxt->stream_out, data, bufsize);
924 if (ret < 0) {
925 LOGD("%s: error writing (child).\n", __FUNCTION__);
926 break;
927 } else if (ret < (signed int)pcxt->pcm_packet_size) {
928 LOGD("%s: wrote less than buffer size, rc=%d.\n", __FUNCTION__, ret);
929 break;
930 }
931
932 if(read_size == len)
933 {
b.liubcf86c92024-08-19 19:48:28 +0800934 // printf("=[%d]", read_size);
luojianfee10dc2024-07-25 11:34:35 +0800935 break;
936 }
937
938 i++;
939 if(i == 3) // 该值可以自行调节
940 {
941 if(flay_flag && gain != 50)
942 {
943 sprintf(cmd, "ubus call audio_if config_dspgain \"{\'type\':1, \'gain\':%d}\"", gain);
b.liu9e8584b2024-11-06 19:21:28 +0800944 ret = system(cmd);
945 if(ret != -1 && ret != 127) {
946 flay_flag = FALSE;
947 usleep(80000);
948 }
luojianfee10dc2024-07-25 11:34:35 +0800949 }
950 }
951
952 }
b.liubcf86c92024-08-19 19:48:28 +0800953
luojianfee10dc2024-07-25 11:34:35 +0800954 if(pcxt->state != AUDIO_STOP)
955 {
956 mbtk_audio_set_status_new(dev_hdl, AUDIO_OPEN);
957 }
958 // system("echo 0 >/sys/class/gpio/gpio19/value");
959 free(data);
960 return 0;
961}
962
963int mbtk_audio_close_new(void *dev_hdl)
964{
luojiande236232024-07-27 10:51:57 +0800965 LOGD("mbtk_audio_close()\n");
luojianfee10dc2024-07-25 11:34:35 +0800966 struct mopen_audio_t *_hdl = (struct mopen_audio_t *)dev_hdl;
967
968 if (NULL == _hdl || NULL == internal_hdl )
969 {
luojiande236232024-07-27 10:51:57 +0800970 LOGD("mbtk_audio_close() fail dev_hdl is NULL\n");
luojianfee10dc2024-07-25 11:34:35 +0800971 return -1;
972 }
973
974 mbtk_audio_set_status_new(_hdl, AUDIO_STOP);
975
976 vcm_playback_drain(0);//wait for drain the AP audiostub queue.
977 usleep(80000);//delay 80ms until DSP play out its buffered data.
978 _hdl->stream_out->common.standby(&_hdl->stream_out->common);
979 _hdl->audio_ahw_dev_ubus->close_output_stream(_hdl->audio_ahw_dev_ubus, _hdl->stream_out);
980
981 audio_hal_uninstall();
982 pthread_mutex_destroy(&_hdl->_cond_mutex);
983 free(_hdl);
984 _hdl = NULL;
985 internal_hdl = NULL;
986
987 return 0;
988}
989
b.liubcf86c92024-08-19 19:48:28 +0800990void mbtk_audio_lib_info_print()
991{
992 MBTK_SOURCE_INFO_PRINT("mbtk_audio_lib");
993}
luojianfee10dc2024-07-25 11:34:35 +0800994