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