blob: c5449d38570023a9984a9eca98245241d1c8fdcc [file] [log] [blame]
luojiana6a47a92024-05-23 13:42:21 +08001
liubin281ac462023-07-19 14:22:54 +08002#include "ql/ql_audio.h"
3#include "mbtk_log.h"
luojiana6a47a92024-05-23 13:42:21 +08004#include "mbtk_audio2.h"
liubin281ac462023-07-19 14:22:54 +08005
b.liuc181beb2024-03-07 18:34:21 +08006typedef enum {
7 AUDIO_PLAY_STATE_STOP,
8 AUDIO_PLAY_STATE_RUNNING,
9 AUDIO_PLAY_STATE_PAUSE
10} audio_play_state_enum;
b.liu5fa9e772023-11-23 18:00:55 +080011
b.liuc181beb2024-03-07 18:34:21 +080012#define AUDIO_HANDLE 1
13#define WAV_PLAY_BUFF 1024
14
15static int sample_rate = 8000;
16static int play_handle = AUDIO_HANDLE;
17static _cb_onPlayer play_cb_func = NULL;
18static _cb_onRecorder recorder_cb_fun = NULL;
19static int is_running = 0;
20static audio_play_state_enum play_state = AUDIO_PLAY_STATE_STOP;
21static int play_exit = 1;
22
23static void recorder_cb_func(void *data, uint32 data_len)
24{
25 if(recorder_cb_fun) {
26 recorder_cb_fun(AUD_RECORDER_START, (unsigned char*)data, data_len);
27 }
28}
29
30static int play_stream(unsigned char* pData, unsigned int length)
31{
32 int rc, len, frames = 0;
33 int result = 0;
34
35 play_state = AUDIO_PLAY_STATE_RUNNING;
36 play_exit = 0;
37 int data_send = 0;
38
luojiana6a47a92024-05-23 13:42:21 +080039 if (mbtk_audio_pcm_play_start()) {
40 printf("%s: error opening output device.", __FUNCTION__);
41 return -1;
42 }
43
b.liuc181beb2024-03-07 18:34:21 +080044 if(pData && length > 0) {
45 while (play_state != AUDIO_PLAY_STATE_STOP) {
46 if(play_state == AUDIO_PLAY_STATE_RUNNING) {
47 if (data_send >= length) {
48 LOGE("%s: Read pcm stream end.", __FUNCTION__);
49 break;
50 }
51
52 if(length - data_send > WAV_PLAY_BUFF) {
53 len = WAV_PLAY_BUFF;
54 } else {
55 len = length - data_send;
56 }
57
58 if((rc = mbtk_audio_pcm_play_data_send(pData + data_send, len)) != len) {
59 LOGE("Send data %d/%d", rc, len);
60 result = -1;
61 goto thread_end;
62 }
63
64 data_send += len;
65
66 LOGD("%s: No.%d frame playback", __FUNCTION__, ++frames);
67 } else {
68 usleep(200000);
69 }
70 }
71 } else {
72 result = -1;
73 }
74
75 play_state = AUDIO_PLAY_STATE_STOP;
76
77thread_end:
78 mbtk_audio_pcm_play_stop();
79 play_exit = 1;
80 LOGD("%s: finished pcm playback.", __FUNCTION__);
81 return result;
82}
83
84static int play_by_fd(int fd, int offset)
85{
86 int rc, len, frames = 0;
87 int result = 0;
88 char buf[WAV_PLAY_BUFF];
89
90 play_state = AUDIO_PLAY_STATE_RUNNING;
91 play_exit = 0;
92 if(fd > 0) {
93 if(offset > 0) {
94 lseek(fd, offset, SEEK_SET);
95 }
luojiana6a47a92024-05-23 13:42:21 +080096
97 if (mbtk_audio_pcm_play_start()) {
98 printf("%s: error opening output device.", __FUNCTION__);
99 return -1;
100 }
101
102
b.liuc181beb2024-03-07 18:34:21 +0800103 while (play_state != AUDIO_PLAY_STATE_STOP) {
104 if(play_state == AUDIO_PLAY_STATE_RUNNING) {
105 memset(buf, 0x00, sizeof(buf));
106 len = read(fd, buf, WAV_PLAY_BUFF);
107 if (len == -1) {
108 LOGE("%s: error reading from file", __FUNCTION__);
109 result = -1;
110 goto thread_end;
111 }
112
113 if (len == 0) {
114 /* reached EOF */
115 LOGE("%s: Read wav file end.", __FUNCTION__);
116 break;
117 }
118
119 if((rc = mbtk_audio_pcm_play_data_send(buf, len)) < len) {
120 LOGE("Send data %d/%d", rc, len);
121 result = -1;
122 goto thread_end;
123 }
124
125 LOGD("%s: No.%d frame playback", __FUNCTION__, ++frames);
126 } else {
127 usleep(200000);
128 }
129 }
130 } else {
131 result = -1;
132 }
133
134 play_state = AUDIO_PLAY_STATE_STOP;
135
136thread_end:
137 mbtk_audio_pcm_play_stop();
138 play_exit = 1;
139 LOGD("%s: finished pcm playback.", __FUNCTION__);
140 return result;
141}
liubin281ac462023-07-19 14:22:54 +0800142
143/*****************************************************************
144* Function: Ql_AudPlayer_Open
145*
146* Description:
147* Open audio play device, and specify the callback function.
148* This function can be called twice to play different audio sources.
149*
150* Parameters:
151* device : a string that specifies the PCM device.
152* NULL, means the audio will be played on the default PCM device.
153*
154* If you want to mixedly play audio sources, you can call this
155* API twice with specifying different PCM device.
156* The string devices available:
157* "hw:0,0" (the default play device)
158* "hw:0,13" (this device can mix audio and TTS)
159* "hw:0,14"
160*
161* cb_func : callback function for audio player.
162* The results of all operations on audio player
163* are informed in callback function.
164*
165* Return:
166* pcm device handle on success
167* -1 for failure
168*****************************************************************/
169int Ql_AudPlayer_Open(char* device, _cb_onPlayer cb_func)
170{
b.liuc181beb2024-03-07 18:34:21 +0800171 if(is_running || mbtk_audio_pcm_init()) {
172 return -1;
173 } else {
174 play_cb_func = cb_func;
175 is_running = 1;
176 return play_handle;
177 }
liubin281ac462023-07-19 14:22:54 +0800178}
179
180/*========================================================================
181 FUNCTION: Ql_AudPlayer_Play
182=========================================================================*/
183/** @brief
184 This function writes pcm data to pcm device to play.
185
186 @param[in] hdl, the handle returned by Ql_AudPlayer_Open().
187 @param[in] pData, pointer to the start address of pcm data.
188 @param[in] length, the length of pcm data.
189
190 @return
191 on success, the return value is the number of bytes to play
192 on failure, the return value is -1;
193
194 @dependencies
195 Ql_AudPlayer_Open() must be first called successfully.
196*/
197/*=======================================================================*/
198int Ql_AudPlayer_Play(int hdl, unsigned char* pData, unsigned int length)
199{
b.liuc181beb2024-03-07 18:34:21 +0800200 if(!is_running || hdl != play_handle) {
201 LOGE("Handle error : %d", hdl);
202 return -1;
203 }
204
205 return play_stream(pData, length);
liubin281ac462023-07-19 14:22:54 +0800206}
207
208/*========================================================================
209 FUNCTION: Ql_AudPlayer_PlayFrmFile
210=========================================================================*/
211/** @brief
212 This function plays the pcm data from the specified file.
213
214 @param[in] hdl, the handle returned by Ql_AudPlayer_Open().
215 @param[in] fd, a file descriptor that contains pcm data.
216 Note:
217 the file offset should be set to the start position of pcm
218 data region, which means you should move the file offset
219 skipping the file header (such as wave header, amr header).
220 @param[in] offset, file offset. Please set it to -1 if no need to use.
221
222 @return
223 0 on success
224 -1 on failure
225
226 @dependencies
227 Ql_AudPlayer_Open() must be first called successfully.
228*/
229/*=======================================================================*/
zhangzh8711cea2023-10-20 10:47:43 +0800230
liubin281ac462023-07-19 14:22:54 +0800231int Ql_AudPlayer_PlayFrmFile(int hdl, int fd, int offset)
232{
b.liuc181beb2024-03-07 18:34:21 +0800233 if(!is_running || hdl != play_handle) {
234 LOGE("Handle error : %d", hdl);
235 return -1;
236 }
237
238 return play_by_fd(fd, offset);
liubin281ac462023-07-19 14:22:54 +0800239}
240
241//
242// Function: Ql_AudPlayer_Pause
243//
244// Description:
245// Pause playing.
246// @param hdl:
247// Handle received from Ql_AudPlayer_Open().
248int Ql_AudPlayer_Pause(int hdl)
249{
b.liuc181beb2024-03-07 18:34:21 +0800250 if(!is_running || hdl != play_handle) {
251 LOGE("Handle error : %d", hdl);
252 return -1;
253 }
254
255 play_state = AUDIO_PLAY_STATE_PAUSE;
256
257 while(!play_exit) {
258 usleep(10000);
259 }
260
b.liu5fa9e772023-11-23 18:00:55 +0800261 return 0;
liubin281ac462023-07-19 14:22:54 +0800262}
263
264//
265// Function: Ql_AudPlayer_Resume
266//
267// Description:
268// Resume playing.
269// @param hdl:
270// Handle received from Ql_AudPlayer_Open().
271int Ql_AudPlayer_Resume(int hdl)
272{
b.liuc181beb2024-03-07 18:34:21 +0800273 if(!is_running || hdl != play_handle) {
274 LOGE("Handle error : %d", hdl);
275 return -1;
276 }
277
278 play_state = AUDIO_PLAY_STATE_RUNNING;
279
280 while(!play_exit) {
281 usleep(10000);
282 }
b.liu5fa9e772023-11-23 18:00:55 +0800283 return 0;
liubin281ac462023-07-19 14:22:54 +0800284}
285
286//
287// Function: Ql_AudPlayer_Stop
288//
289// Description:
290// Stop playing audio
291// hdl:
292// Handle received from Ql_AudPlayer_Open().
293void Ql_AudPlayer_Stop(int hdl)
294{
b.liuc181beb2024-03-07 18:34:21 +0800295 if(!is_running || hdl != play_handle) {
296 LOGE("Handle error : %d", hdl);
297 return;
298 }
b.liu5fa9e772023-11-23 18:00:55 +0800299
b.liuc181beb2024-03-07 18:34:21 +0800300 play_state = AUDIO_PLAY_STATE_STOP;
301
302 while(!play_exit) {
303 usleep(10000);
304 }
liubin281ac462023-07-19 14:22:54 +0800305}
306
307//
308// Function: Ql_AudPlayer_Close
309//
310// Description:
311// Close player, and free the resource.
312// @param hdl:
313// Handle received from Ql_AudPlayer_Open().
314void Ql_AudPlayer_Close(int hdl)
315{
b.liuc181beb2024-03-07 18:34:21 +0800316 if(!is_running || hdl != play_handle) {
317 LOGE("Handle error : %d", hdl);
318 return;
319 }
320 play_state = AUDIO_PLAY_STATE_STOP;
b.liu5fa9e772023-11-23 18:00:55 +0800321
b.liuc181beb2024-03-07 18:34:21 +0800322 while(!play_exit) {
323 usleep(10000);
324 }
325
326 is_running = 0;
327 mbtk_audio_pcm_deinit();
liubin281ac462023-07-19 14:22:54 +0800328}
329
330
331int Ql_AudPlayer_set_LessDataThreshold(int hdl, unsigned short threshSize)
332{
333
334 return 0;
335}
336
337int Ql_AudPlayer_get_freeSpace(int hdl)
338{
339
340 return 0;
341}
342
343
344/*****************************************************************
345* Function: Ql_AudRecorder_Open
346*
347* Description:
348* Open audio record device, and specify the callback function.
349*
350* Parameters:
351* device : not used. MUST be NULL.
352*
353* cb_func : callback function for audio player.
354* The results of all operations on audio recorder
355* are informed in callback function.
356*
357* Return:
358* pcm device handle
359* -1 for failure
360*****************************************************************/
361int Ql_AudRecorder_Open(char* device, _cb_onRecorder cb_fun)
362{
b.liuc181beb2024-03-07 18:34:21 +0800363 if(is_running || mbtk_audio_pcm_init()) {
364 return -1;
365 } else {
366 is_running = 1;
367 recorder_cb_fun = cb_fun;
368 return play_handle;
369 }
liubin281ac462023-07-19 14:22:54 +0800370}
371
372//
373// Function: Ql_AudRecorder_StartRecord
374//
375// Description:
376// Start to record.
377// The record data is output in _cb_onRecorder.
378//
379// Return:
380// 0 on success
381// -1 on failure
382int Ql_AudRecorder_StartRecord(void)
383{
b.liuc181beb2024-03-07 18:34:21 +0800384 if(!is_running) {
385 LOGE("No open device.");
386 return -1;
387 }
b.liu5fa9e772023-11-23 18:00:55 +0800388
b.liuc181beb2024-03-07 18:34:21 +0800389 return mbtk_audio_pcm_recorder_start(recorder_cb_func);
liubin281ac462023-07-19 14:22:54 +0800390}
391
392//
393// Function: Ql_AudRecorder_Pause
394//
395// Description:
396// Pause recording
397int Ql_AudRecorder_Pause(void)
398{
b.liuc181beb2024-03-07 18:34:21 +0800399 if(!is_running) {
400 LOGE("No open device.");
401 return -1;
402 }
403
404 return mbtk_audio_pcm_recorder_pause();
liubin281ac462023-07-19 14:22:54 +0800405}
406
407//
408// Function: Ql_AudRecorder_Resume
409//
410// Description:
411// Resume recording
412int Ql_AudRecorder_Resume(void)
413{
b.liuc181beb2024-03-07 18:34:21 +0800414 if(!is_running) {
415 LOGE("No open device.");
416 return -1;
417 }
418
419 return mbtk_audio_pcm_recorder_resume();
liubin281ac462023-07-19 14:22:54 +0800420}
421
422//
423// Function: Ql_AudRecorder_Stop
424//
425// Description:
426// Stop recording
427void Ql_AudRecorder_Stop(void)
428{
b.liuc181beb2024-03-07 18:34:21 +0800429 if(!is_running) {
430 LOGE("No open device.");
431 return;
432 }
liubin281ac462023-07-19 14:22:54 +0800433
b.liuc181beb2024-03-07 18:34:21 +0800434 mbtk_audio_pcm_recorder_stop();
liubin281ac462023-07-19 14:22:54 +0800435}
436
437//
438// Function: Ql_AudRecorder_Close
439//
440// Description:
441// Close recorder, and free the resource
442void Ql_AudRecorder_Close(void)
443{
b.liuc181beb2024-03-07 18:34:21 +0800444 if(!is_running) {
445 LOGE("No open device.");
446 return;
447 }
b.liu5fa9e772023-11-23 18:00:55 +0800448
b.liuc181beb2024-03-07 18:34:21 +0800449 is_running = 0;
450 mbtk_audio_pcm_deinit();
liubin281ac462023-07-19 14:22:54 +0800451}
452
453//
454// Function: Ql_clt_set_mixer_value
455//
456// Description:
457// Close recorder, and free the resource
458boolean Ql_clt_set_mixer_value(const char *device, int count, const char *value)
459{
460
461 return FALSE;
462}
463
464
465int Ql_AudTone_Open(char* device, _cb_onPlayer cb)//cb not support now
466{
467 return 0;
468}
469
470int Ql_AudTone_Start(int hdl, struct Ql_TonePara *para)
471{
472 return 0;
473}
474
475void Ql_AudTone_Stop(int hdl)
476{
477
478}
479
480void Ql_AudTone_Close(int hdl)
481{
482
483}
484
485
486//****************QL Codec API************************//
487
488//
489// Function: Ql_AudCodec_Set_ALC5616_DRCAGC
490//
491// Description:
492// Set ALC5616 DRC/AGC configuration
493int Ql_AudCodec_Set_ALC5616_DRCAGC(const char *i2c, struct Ql_ALC5616_DRCAGC *cfg)
494{
495 return 0;
496}
497
498//
499// Function: Ql_Update_wav_size
500//
501// Description:
502// update wav format file size in the header
503// @param fd:
504// wav file discriptor
505// @param size:
506// wav file size to update
507int Ql_Update_wav_size(int fd, int size)
508{
509 return 0;
510}
511
512//add by grady, 2018-5-29
513/*
514 * describe : this function is use to open pcm device
515 * paras :
516 * device : this should be fix to hw:0,0
517 * flags ; pcm play flags
518 * rate: sample rate
519 * channels : audio channal 1 or 2
520 * format: format to play or record, 16bit line,MP3
521 * hostless: if there is no file it is true
522 * return :
523 * pcm : pcm handle, use can use this handle to read write data
524 */
525struct pcm *quec_pcm_open(char *device, unsigned flags, unsigned rate, unsigned channels, unsigned format, unsigned hostless)
526{
527 return NULL;
528}
529
530/*
531 * describe : this function is use to close pcm handle
532 * paras :
533 * pcm : pcm handle to close
534 * return :
535 */
536int quec_pcm_close(struct pcm *pcm )
537{
538 return 0;
539}
540
541/*
542 * describe : this function is use to read pcm buffer
543 * paras :
544 * pcm : pcm handle to write date
545 * buffer: data buffer
546 * lenth: data length
547 * return :
548 */
549int quec_read_pcm(struct pcm *pcm, void * buffer, int length)
550{
551
552 return 0;
553}
554
555/*
556 * describe : this function is use to get pcm buffer lenth
557 * paras :
558 * lenth: data length
559 * return
560 * buffer length
561 */
562int quec_get_pem_buffer_len(struct pcm *pcm)
563{
564
565 return 0;
566}
567
568void dtmf_cb1(char dtmf)
569{
570 printf("%s:%c\n", __FUNCTION__, dtmf);
571}
572
573/**
574 * @brief Set RX DSP Gain
575 * @details
576 * Gain support [-36,12] dB
577 *
578 * @param gain
579 * DSP gain
580 */
581
582int Ql_Rxgain_Set(int value)
583{
luojiana6a47a92024-05-23 13:42:21 +0800584 mbtk_dsp_gain_set(1, value);
b.liu5fa9e772023-11-23 18:00:55 +0800585 return 0;
liubin281ac462023-07-19 14:22:54 +0800586}
587
588
589/** Ql_Playback_Samprate_Set
590 * @brief Set Playback PCM Samprate
591 * @details
592 * 0 for NB 1 for WB
593 *
594 * @param samprate
595 * samprate for PCM playback,default value is PCM NB
596 */
597int Ql_Playback_Samprate_Set(int samprate)
598{
599 printf("samprate is %d \n",samprate);
600 if(samprate == 1)
601 {
b.liuc181beb2024-03-07 18:34:21 +0800602 sample_rate = 16000;
luojiana6a47a92024-05-23 13:42:21 +0800603 mbtk_audio_pcm_sample_rate_set(MBTK_AUDIO_SAMPLE_RATE_16000);
liubin281ac462023-07-19 14:22:54 +0800604 }
605 else{
luojiana6a47a92024-05-23 13:42:21 +0800606 mbtk_audio_pcm_sample_rate_set(MBTK_AUDIO_SAMPLE_RATE_8000);
b.liuc181beb2024-03-07 18:34:21 +0800607 sample_rate = 8000;
liubin281ac462023-07-19 14:22:54 +0800608 }
609
610 return 0;
611}
612
613int Ql_Mp3_To_Wav(const char *wavpath, char *mp3path)
614{
b.liuc1064f82023-10-11 16:47:39 +0800615 return 0;
liubin281ac462023-07-19 14:22:54 +0800616}
617
618int Ql_Mp3_To_Play(char *mp3path, int hdl,int sample_rate)
619{
b.liuc1064f82023-10-11 16:47:39 +0800620 return 0;
liubin281ac462023-07-19 14:22:54 +0800621}
622
623//add by grady, 2018-6-2
624/*
625 * describe : this function is use to open mixer device
626 * paras :
627 * device: mixer device
628 * return
629 * mixer handle
630 */
631struct mixer *quec_mixer_open(const char *device)
632{
633
634 return NULL;
635}
636
637/*
638 * describe : this function is use to close mixer device
639 * paras :
640 * mixer: mixer handle
641 * return
642 * none
643 */
644void quec_mixer_close(struct mixer *mixer)
645{
646
647
648}
649
650/*
651 * describe : this function is use to get mixer devie control
652 * paras :
653 * mixer: mixer handle
654 * name: mixer device
655 * index: mixer index
656 * return
657 * mixer control
658 */
659struct mixer_ctl *quec_mixer_get_control(struct mixer *mixer, const char *name, unsigned index)
660{
661
662 return NULL;
663}
664
665/*
666 * describe : this function is use to set mulvalues
667 * paras :
668 * mixer: mixer handle
669 * count: count
670 * argv: data
671 * return :
672 *
673 */
674int quec_mixer_ctl_mulvalues(struct mixer_ctl *ctl, int count, char ** argv)
675{
676
677 return 0;
678}
679
680
681//end grady
682
683/*****************************************************************
684* Function: Ql_AudPlayer_OpenExt
685*
686* Description:
687* expend function from Ql_AudPlayer_OpenExt
688* Open audio play device, and specify the callback function.
689* This function can be called twice to play different audio sources.
690*
691* Parameters:
692* device : a string that specifies the PCM device.
693* NULL, means the audio will be played on the default PCM device.
694*
695* If you want to mixedly play audio sources, you can call this
696* API twice with specifying different PCM device.
697* The string devices available:
698* "hw:0,0" (the default play device)
699* "hw:0,13" (this device can mix audio and TTS)
700* "hw:0,14"
701*
702* cb_func : callback function for audio player.
703* The results of all operations on audio player
704* are informed in callback function.
705*
706* flags : pcm flags, eg: PCM_MMAP, PCM_NMMAP.
707*
708* channels: pcm sample channels.
709*
710* rate : pcm sample rate.
711*
712* format : pcm sample fromat
713*
714* Return:
715* pcm device handle
716* NULL, fail
717*****************************************************************/
718int Ql_AudPlayer_OpenExt(
719 char *dev,
720 _cb_onPlayer cb_fun,
721 int flags,
722 int channels,
723 int rate,
724 int format)
725{
726 return 0;
727}
728
729/*****************************************************************
730* Function: Ql_AudRecorder_Open
731*
732* Description:
733* Open audio record device, and specify the callback function.
734*
735* Parameters:
736* device : not used. MUST be NULL.
737*
738* cb_func : callback function for audio player.
739* The results of all operations on audio recorder
740* are informed in callback function.
741*
742* flags : pcm flags, eg: PCM_MMAP, PCM_NMMAP.
743*
744* channels: pcm sample channels.
745*
746* rate : pcm sample rate.
747*
748* format : pcm sample fromat
749*
750* Return:
751* pcm device handle
752* NULL, fail
753*****************************************************************/
754int Ql_AudRecorder_OpenExt(
755 char *dev,
756 _cb_onRecorder cb_fun,
757 int flags,
758 int channels,
759 int rate,
760 int format)
761{
762
763
764 return 0;
765}
766
767/*
768* Function: uac enable
769*
770* Description:
771* uac enable
772*
773* Parameters:
774* none
775* Return:
776* TURE or FALSE
777*/
778int ql_uac_enable(void)
779{
780
781 return 0;
782}
783
784/*
785* Function: uac disable
786*
787* Description:
788* uac disable
789*
790* Parameters:
791* none
792* Return:
793* TURE or FALSE
794*/
795int ql_uac_disable(void)
796{
797
798 return 0;
luojiana6a47a92024-05-23 13:42:21 +0800799}