blob: c811a9a5b01310fb6f2baedf170991a37c719e87 [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{
666 int value = 1;
667 struct mopen_audio_t *aud_hdl = NULL;
668 int ret;
669
670 if(internal_hdl)
671 {
672 printf("Audio device inited\n");
673 return internal_hdl;
674 }
675
676 aud_hdl = (struct mopen_audio_t *) calloc(1, sizeof(struct mopen_audio_t));
677 if (!aud_hdl)
678 {
679 fprintf(stderr, "\n%s:Failed to allocate audio hdl!, errno=%d\n", __FUNCTION__, errno);
680 return NULL;
681 }
682 memset(aud_hdl, 0, sizeof(struct mopen_audio_t));
683
684 //init global variables
685 aud_hdl->audio_ahw_dev_ubus = audio_hal_install();
686 if (aud_hdl->audio_ahw_dev_ubus == NULL) {
687 LOGD("%s: audio_hal_install failed!\n", __FUNCTION__);
688 goto error;
689 }
690
691 ret = audio_open_pcm_new(aud_hdl, flag, rate, dev);
692 if (ret)
693 {
694 LOGD("\n%s: pcm open error, errno=%d\n", __FUNCTION__, errno);
695 goto error;
696 }
697
698 ret = aud_hdl->audio_ahw_dev_ubus->open_output_stream(aud_hdl->audio_ahw_dev_ubus, 0,
699 aud_hdl->audio_ahw_dev_ubus->get_supported_devices(aud_hdl->audio_ahw_dev_ubus),
700 AUDIO_OUTPUT_FLAG_DIRECT, NULL, &aud_hdl->stream_out, 0);
701
702 if (ret < 0) {
703 LOGD("%s: error opening output device. rc = %d\n", __FUNCTION__, ret);
704 goto error;
705 }
706
707 pthread_mutex_init(&aud_hdl->_cond_mutex, NULL);
708 aud_hdl->usrData = usrData;
709 aud_hdl->state = AUDIO_OPEN;
710 /* printf("Mbtk_Audio_Open aud_hdl[%x][%x][%x]\n", aud_hdl, aud_hdl->_mixer_ctl, aud_hdl->_pcm); */
711 internal_hdl = aud_hdl;
712
713 return (void *)aud_hdl;
714
715error:
716 value = 0;
717 free(aud_hdl);
718 return NULL;
719}
720
721int mbtk_audio_play_file_new(void *dev_hdl, int file_fd, int offset)
722{
723 unsigned bufsize = 0;
724 char *data = NULL;
725 int first_set = 0;
726 int file_data_sz = 0;
727 int res = 0;
728 int ret;
729
730 char cmd[128] = {0};
731 bool flay_flag = TRUE;
732 int i = 0;
733
734
735 struct mopen_audio_t *pcxt = (struct mopen_audio_t *)dev_hdl;
736 _play_callback audio_play_cb = (_play_callback)pcxt->usrData;
737 if (NULL == dev_hdl || NULL == internal_hdl)
738 return -1;
739
740
741 if(AUDIO_RUNNING == pcxt->state)
742 return -2;
743
744 // file_data_sz = mbtk_wav_pcm16Le_check(file_fd);
745 bufsize = pcxt->pcm_packet_size;
746 data = calloc(1, bufsize);
747 if (!data) {
748 fprintf(stderr, "\n%s:could not allocate %d bytes\n",__FUNCTION__,bufsize);
749 pthread_exit(NULL);
750 }
751 if(offset)
752 {
753 lseek(file_fd, offset, SEEK_SET);
754 }
755
756 mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
757 int all_size = 0;
758
759 system("echo 1 >/sys/class/gpio/gpio19/value");
760 while (pcxt->state != AUDIO_STOP)
761 {
762 res = read(file_fd, data, bufsize);
763 // printf("%s:read : %d bytes\n", __FUNCTION__, res);
764 if(res == 0 || res < 0)
765 {
766 LOGD("read:[%d]", res);
767 break;
768 }
769
770 all_size += res;
771// if (file_data_sz < all_size || file_data_sz == all_size) {
772// printf("aplay size :%d - %d\n", file_data_sz, all_size);
773 // break;
774 // }
775
776 while(AUDIO_PAUSE == pcxt->state)
777 {
778 usleep(80000);
779 audio_play_cb(pcxt, AUD_PLAYER_PAUSE);
780 }
781
782 if ((0 == first_set || AUDIO_RESUME == pcxt->state))
783 {
784 first_set = 1;
785 mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
786 audio_play_cb(pcxt, AUD_PLAYER_RESUME);
787 }
788
789 ret = pcxt->stream_out->write(pcxt->stream_out, data, bufsize);
790 if (ret < 0) {
791 LOGD("%s: error writing (child).\n", __FUNCTION__);
792 audio_play_cb(pcxt, AUD_PLAYER_ERROR);
793 break;
794 } else if (ret < (signed int)pcxt->pcm_packet_size) {
795 LOGD("%s: wrote less than buffer size, rc=%d.\n", __FUNCTION__, ret);
796 audio_play_cb(pcxt, AUD_PLAYER_LESSDATA);
797 break;
798 }
799
800 }
801 if (audio_play_cb)
802 audio_play_cb(pcxt, AUD_PLAYER_FINISHED);
803
804 LOGD("file_data_sz :%d - all_size: %d\n", file_data_sz, all_size);
805 mbtk_audio_set_status_new(dev_hdl, AUDIO_OPEN);
806 free(data);
807 system("echo 0 >/sys/class/gpio/gpio19/value");
808
809 return 0;
810}
811
812int mbtk_audio_play_stream_new(void *dev_hdl, const void *pData, int len, int gain )
813{
814 unsigned bufsize = 0;
815 char *data = NULL;
816 int first_set = 0;
817 int res = 0;
818 int ret = 0;
819 int read_size = 0;
820 char *p = (char *)pData;
821
822 char cmd[128] = {0};
823 bool flay_flag = TRUE;
824 int i = 0;
825
826 struct mopen_audio_t *pcxt = (struct mopen_audio_t *)dev_hdl;
827
828 if (NULL == dev_hdl || NULL == internal_hdl || pData == NULL)
829 return -1;
830
831 if(AUDIO_RUNNING == pcxt->state)
832 return -2;
833
834 bufsize = pcxt->pcm_packet_size;
835 data = calloc(1, bufsize);
836 if (!data) {
837 fprintf(stderr, "\n%s:could not allocate %d bytes\n",__FUNCTION__,bufsize);
838 pthread_exit(NULL);
839 }
840
841 if(pcxt->state == AUDIO_OPEN)
842 {
843 mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
844
845 }
846
847 // system("echo 1 >/sys/class/gpio/gpio19/value");
848 while (pcxt->state != AUDIO_STOP)
849 {
850
851 memcpy(data,p+read_size, bufsize );
852 read_size += bufsize;
853
854 if(read_size > len)
855 {
856 // printf(">[%d]\n", read_size);
857 break;
858 }
859
860 while(AUDIO_PAUSE == pcxt->state)
861 {
862 usleep(80000);
863 }
864
865 if ((0 == first_set || AUDIO_RESUME == pcxt->state))
866 {
867 first_set = 1;
868 mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
869 }
870
871 ret = pcxt->stream_out->write(pcxt->stream_out, data, bufsize);
872 if (ret < 0) {
873 LOGD("%s: error writing (child).\n", __FUNCTION__);
874 break;
875 } else if (ret < (signed int)pcxt->pcm_packet_size) {
876 LOGD("%s: wrote less than buffer size, rc=%d.\n", __FUNCTION__, ret);
877 break;
878 }
879
880 if(read_size == len)
881 {
882 // printf("=[%d]", read_size);
883 break;
884 }
885
886 i++;
887 if(i == 3) // 该值可以自行调节
888 {
889 if(flay_flag && gain != 50)
890 {
891 sprintf(cmd, "ubus call audio_if config_dspgain \"{\'type\':1, \'gain\':%d}\"", gain);
892 system(cmd);
893
894 flay_flag = FALSE;
895 usleep(80000);
896 }
897 }
898
899 }
900
901 if(pcxt->state != AUDIO_STOP)
902 {
903 mbtk_audio_set_status_new(dev_hdl, AUDIO_OPEN);
904 }
905 // system("echo 0 >/sys/class/gpio/gpio19/value");
906 free(data);
907 return 0;
908}
909
910int mbtk_audio_close_new(void *dev_hdl)
911{
912 printf("mbtk_audio_close()\n");
913 int value = 0;
914 struct mopen_audio_t *_hdl = (struct mopen_audio_t *)dev_hdl;
915
916 if (NULL == _hdl || NULL == internal_hdl )
917 {
918 printf("mbtk_audio_close() fail dev_hdl is NULL\n");
919 return -1;
920 }
921
922 mbtk_audio_set_status_new(_hdl, AUDIO_STOP);
923
924 vcm_playback_drain(0);//wait for drain the AP audiostub queue.
925 usleep(80000);//delay 80ms until DSP play out its buffered data.
926 _hdl->stream_out->common.standby(&_hdl->stream_out->common);
927 _hdl->audio_ahw_dev_ubus->close_output_stream(_hdl->audio_ahw_dev_ubus, _hdl->stream_out);
928
929 audio_hal_uninstall();
930 pthread_mutex_destroy(&_hdl->_cond_mutex);
931 free(_hdl);
932 _hdl = NULL;
933 internal_hdl = NULL;
934
935 return 0;
936}
937
938