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