blob: 5ffee7803245fab3669ab605f8f98f2ce523c835 [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
luojian21604d92024-06-25 14:11:25 +080077
b.liuc181beb2024-03-07 18:34:21 +080078thread_end:
79 mbtk_audio_pcm_play_stop();
80 play_exit = 1;
81 LOGD("%s: finished pcm playback.", __FUNCTION__);
82 return result;
83}
84
85static int play_by_fd(int fd, int offset)
86{
87 int rc, len, frames = 0;
88 int result = 0;
89 char buf[WAV_PLAY_BUFF];
90
91 play_state = AUDIO_PLAY_STATE_RUNNING;
luojian21604d92024-06-25 14:11:25 +080092 if(play_cb_func)
93 play_cb_func(play_handle , AUDIO_PLAY_STATE_RUNNING);
b.liuc181beb2024-03-07 18:34:21 +080094 play_exit = 0;
95 if(fd > 0) {
96 if(offset > 0) {
97 lseek(fd, offset, SEEK_SET);
98 }
luojiana6a47a92024-05-23 13:42:21 +080099
100 if (mbtk_audio_pcm_play_start()) {
101 printf("%s: error opening output device.", __FUNCTION__);
102 return -1;
103 }
104
105
b.liuc181beb2024-03-07 18:34:21 +0800106 while (play_state != AUDIO_PLAY_STATE_STOP) {
107 if(play_state == AUDIO_PLAY_STATE_RUNNING) {
108 memset(buf, 0x00, sizeof(buf));
109 len = read(fd, buf, WAV_PLAY_BUFF);
110 if (len == -1) {
111 LOGE("%s: error reading from file", __FUNCTION__);
112 result = -1;
113 goto thread_end;
114 }
115
116 if (len == 0) {
117 /* reached EOF */
118 LOGE("%s: Read wav file end.", __FUNCTION__);
119 break;
120 }
121
122 if((rc = mbtk_audio_pcm_play_data_send(buf, len)) < len) {
123 LOGE("Send data %d/%d", rc, len);
124 result = -1;
125 goto thread_end;
126 }
127
128 LOGD("%s: No.%d frame playback", __FUNCTION__, ++frames);
129 } else {
130 usleep(200000);
131 }
132 }
133 } else {
134 result = -1;
135 }
136
137 play_state = AUDIO_PLAY_STATE_STOP;
luojian21604d92024-06-25 14:11:25 +0800138 if(play_cb_func)
139 play_cb_func(play_handle , AUDIO_PLAY_STATE_STOP);
b.liuc181beb2024-03-07 18:34:21 +0800140
141thread_end:
142 mbtk_audio_pcm_play_stop();
143 play_exit = 1;
144 LOGD("%s: finished pcm playback.", __FUNCTION__);
145 return result;
146}
liubin281ac462023-07-19 14:22:54 +0800147
148/*****************************************************************
149* Function: Ql_AudPlayer_Open
150*
151* Description:
152* Open audio play device, and specify the callback function.
153* This function can be called twice to play different audio sources.
154*
155* Parameters:
156* device : a string that specifies the PCM device.
157* NULL, means the audio will be played on the default PCM device.
158*
159* If you want to mixedly play audio sources, you can call this
160* API twice with specifying different PCM device.
161* The string devices available:
162* "hw:0,0" (the default play device)
163* "hw:0,13" (this device can mix audio and TTS)
164* "hw:0,14"
165*
166* cb_func : callback function for audio player.
167* The results of all operations on audio player
168* are informed in callback function.
169*
170* Return:
171* pcm device handle on success
172* -1 for failure
173*****************************************************************/
174int Ql_AudPlayer_Open(char* device, _cb_onPlayer cb_func)
175{
b.liuc181beb2024-03-07 18:34:21 +0800176 if(is_running || mbtk_audio_pcm_init()) {
177 return -1;
178 } else {
179 play_cb_func = cb_func;
180 is_running = 1;
181 return play_handle;
182 }
liubin281ac462023-07-19 14:22:54 +0800183}
184
185/*========================================================================
186 FUNCTION: Ql_AudPlayer_Play
187=========================================================================*/
188/** @brief
189 This function writes pcm data to pcm device to play.
190
191 @param[in] hdl, the handle returned by Ql_AudPlayer_Open().
192 @param[in] pData, pointer to the start address of pcm data.
193 @param[in] length, the length of pcm data.
194
195 @return
196 on success, the return value is the number of bytes to play
197 on failure, the return value is -1;
198
199 @dependencies
200 Ql_AudPlayer_Open() must be first called successfully.
201*/
202/*=======================================================================*/
203int Ql_AudPlayer_Play(int hdl, unsigned char* pData, unsigned int length)
204{
b.liuc181beb2024-03-07 18:34:21 +0800205 if(!is_running || hdl != play_handle) {
206 LOGE("Handle error : %d", hdl);
207 return -1;
208 }
209
210 return play_stream(pData, length);
liubin281ac462023-07-19 14:22:54 +0800211}
212
213/*========================================================================
214 FUNCTION: Ql_AudPlayer_PlayFrmFile
215=========================================================================*/
216/** @brief
217 This function plays the pcm data from the specified file.
218
219 @param[in] hdl, the handle returned by Ql_AudPlayer_Open().
220 @param[in] fd, a file descriptor that contains pcm data.
221 Note:
222 the file offset should be set to the start position of pcm
223 data region, which means you should move the file offset
224 skipping the file header (such as wave header, amr header).
225 @param[in] offset, file offset. Please set it to -1 if no need to use.
226
227 @return
228 0 on success
229 -1 on failure
230
231 @dependencies
232 Ql_AudPlayer_Open() must be first called successfully.
233*/
234/*=======================================================================*/
zhangzh8711cea2023-10-20 10:47:43 +0800235
liubin281ac462023-07-19 14:22:54 +0800236int Ql_AudPlayer_PlayFrmFile(int hdl, int fd, int offset)
237{
b.liuc181beb2024-03-07 18:34:21 +0800238 if(!is_running || hdl != play_handle) {
239 LOGE("Handle error : %d", hdl);
240 return -1;
241 }
242
243 return play_by_fd(fd, offset);
liubin281ac462023-07-19 14:22:54 +0800244}
245
246//
247// Function: Ql_AudPlayer_Pause
248//
249// Description:
250// Pause playing.
251// @param hdl:
252// Handle received from Ql_AudPlayer_Open().
253int Ql_AudPlayer_Pause(int hdl)
254{
b.liuc181beb2024-03-07 18:34:21 +0800255 if(!is_running || hdl != play_handle) {
256 LOGE("Handle error : %d", hdl);
257 return -1;
258 }
259
260 play_state = AUDIO_PLAY_STATE_PAUSE;
261
262 while(!play_exit) {
263 usleep(10000);
264 }
265
b.liu5fa9e772023-11-23 18:00:55 +0800266 return 0;
liubin281ac462023-07-19 14:22:54 +0800267}
268
269//
270// Function: Ql_AudPlayer_Resume
271//
272// Description:
273// Resume playing.
274// @param hdl:
275// Handle received from Ql_AudPlayer_Open().
276int Ql_AudPlayer_Resume(int hdl)
277{
b.liuc181beb2024-03-07 18:34:21 +0800278 if(!is_running || hdl != play_handle) {
279 LOGE("Handle error : %d", hdl);
280 return -1;
281 }
282
283 play_state = AUDIO_PLAY_STATE_RUNNING;
284
285 while(!play_exit) {
286 usleep(10000);
287 }
b.liu5fa9e772023-11-23 18:00:55 +0800288 return 0;
liubin281ac462023-07-19 14:22:54 +0800289}
290
291//
292// Function: Ql_AudPlayer_Stop
293//
294// Description:
295// Stop playing audio
296// hdl:
297// Handle received from Ql_AudPlayer_Open().
298void Ql_AudPlayer_Stop(int hdl)
299{
b.liuc181beb2024-03-07 18:34:21 +0800300 if(!is_running || hdl != play_handle) {
301 LOGE("Handle error : %d", hdl);
302 return;
303 }
b.liu5fa9e772023-11-23 18:00:55 +0800304
b.liuc181beb2024-03-07 18:34:21 +0800305 play_state = AUDIO_PLAY_STATE_STOP;
306
307 while(!play_exit) {
308 usleep(10000);
309 }
liubin281ac462023-07-19 14:22:54 +0800310}
311
312//
313// Function: Ql_AudPlayer_Close
314//
315// Description:
316// Close player, and free the resource.
317// @param hdl:
318// Handle received from Ql_AudPlayer_Open().
319void Ql_AudPlayer_Close(int hdl)
320{
b.liuc181beb2024-03-07 18:34:21 +0800321 if(!is_running || hdl != play_handle) {
322 LOGE("Handle error : %d", hdl);
323 return;
324 }
325 play_state = AUDIO_PLAY_STATE_STOP;
b.liu5fa9e772023-11-23 18:00:55 +0800326
b.liuc181beb2024-03-07 18:34:21 +0800327 while(!play_exit) {
328 usleep(10000);
329 }
330
331 is_running = 0;
332 mbtk_audio_pcm_deinit();
liubin281ac462023-07-19 14:22:54 +0800333}
334
335
336int Ql_AudPlayer_set_LessDataThreshold(int hdl, unsigned short threshSize)
337{
338
339 return 0;
340}
341
342int Ql_AudPlayer_get_freeSpace(int hdl)
343{
344
345 return 0;
346}
347
348
349/*****************************************************************
350* Function: Ql_AudRecorder_Open
351*
352* Description:
353* Open audio record device, and specify the callback function.
354*
355* Parameters:
356* device : not used. MUST be NULL.
357*
358* cb_func : callback function for audio player.
359* The results of all operations on audio recorder
360* are informed in callback function.
361*
362* Return:
363* pcm device handle
364* -1 for failure
365*****************************************************************/
366int Ql_AudRecorder_Open(char* device, _cb_onRecorder cb_fun)
367{
b.liuc181beb2024-03-07 18:34:21 +0800368 if(is_running || mbtk_audio_pcm_init()) {
369 return -1;
370 } else {
371 is_running = 1;
372 recorder_cb_fun = cb_fun;
373 return play_handle;
374 }
liubin281ac462023-07-19 14:22:54 +0800375}
376
377//
378// Function: Ql_AudRecorder_StartRecord
379//
380// Description:
381// Start to record.
382// The record data is output in _cb_onRecorder.
383//
384// Return:
385// 0 on success
386// -1 on failure
387int Ql_AudRecorder_StartRecord(void)
388{
b.liuc181beb2024-03-07 18:34:21 +0800389 if(!is_running) {
390 LOGE("No open device.");
391 return -1;
392 }
b.liu5fa9e772023-11-23 18:00:55 +0800393
b.liuc181beb2024-03-07 18:34:21 +0800394 return mbtk_audio_pcm_recorder_start(recorder_cb_func);
liubin281ac462023-07-19 14:22:54 +0800395}
396
397//
398// Function: Ql_AudRecorder_Pause
399//
400// Description:
401// Pause recording
402int Ql_AudRecorder_Pause(void)
403{
b.liuc181beb2024-03-07 18:34:21 +0800404 if(!is_running) {
405 LOGE("No open device.");
406 return -1;
407 }
408
409 return mbtk_audio_pcm_recorder_pause();
liubin281ac462023-07-19 14:22:54 +0800410}
411
412//
413// Function: Ql_AudRecorder_Resume
414//
415// Description:
416// Resume recording
417int Ql_AudRecorder_Resume(void)
418{
b.liuc181beb2024-03-07 18:34:21 +0800419 if(!is_running) {
420 LOGE("No open device.");
421 return -1;
422 }
423
424 return mbtk_audio_pcm_recorder_resume();
liubin281ac462023-07-19 14:22:54 +0800425}
426
427//
428// Function: Ql_AudRecorder_Stop
429//
430// Description:
431// Stop recording
432void Ql_AudRecorder_Stop(void)
433{
b.liuc181beb2024-03-07 18:34:21 +0800434 if(!is_running) {
435 LOGE("No open device.");
436 return;
437 }
liubin281ac462023-07-19 14:22:54 +0800438
b.liuc181beb2024-03-07 18:34:21 +0800439 mbtk_audio_pcm_recorder_stop();
liubin281ac462023-07-19 14:22:54 +0800440}
441
442//
443// Function: Ql_AudRecorder_Close
444//
445// Description:
446// Close recorder, and free the resource
447void Ql_AudRecorder_Close(void)
448{
b.liuc181beb2024-03-07 18:34:21 +0800449 if(!is_running) {
450 LOGE("No open device.");
451 return;
452 }
b.liu5fa9e772023-11-23 18:00:55 +0800453
b.liuc181beb2024-03-07 18:34:21 +0800454 is_running = 0;
455 mbtk_audio_pcm_deinit();
liubin281ac462023-07-19 14:22:54 +0800456}
457
458//
459// Function: Ql_clt_set_mixer_value
460//
461// Description:
462// Close recorder, and free the resource
463boolean Ql_clt_set_mixer_value(const char *device, int count, const char *value)
464{
465
466 return FALSE;
467}
468
469
470int Ql_AudTone_Open(char* device, _cb_onPlayer cb)//cb not support now
471{
472 return 0;
473}
474
475int Ql_AudTone_Start(int hdl, struct Ql_TonePara *para)
476{
477 return 0;
478}
479
480void Ql_AudTone_Stop(int hdl)
481{
482
483}
484
485void Ql_AudTone_Close(int hdl)
486{
487
488}
489
490
491//****************QL Codec API************************//
492
493//
494// Function: Ql_AudCodec_Set_ALC5616_DRCAGC
495//
496// Description:
497// Set ALC5616 DRC/AGC configuration
498int Ql_AudCodec_Set_ALC5616_DRCAGC(const char *i2c, struct Ql_ALC5616_DRCAGC *cfg)
499{
500 return 0;
501}
502
503//
504// Function: Ql_Update_wav_size
505//
506// Description:
507// update wav format file size in the header
508// @param fd:
509// wav file discriptor
510// @param size:
511// wav file size to update
512int Ql_Update_wav_size(int fd, int size)
513{
514 return 0;
515}
516
517//add by grady, 2018-5-29
518/*
519 * describe : this function is use to open pcm device
520 * paras :
521 * device : this should be fix to hw:0,0
522 * flags ; pcm play flags
523 * rate: sample rate
524 * channels : audio channal 1 or 2
525 * format: format to play or record, 16bit line,MP3
526 * hostless: if there is no file it is true
527 * return :
528 * pcm : pcm handle, use can use this handle to read write data
529 */
530struct pcm *quec_pcm_open(char *device, unsigned flags, unsigned rate, unsigned channels, unsigned format, unsigned hostless)
531{
532 return NULL;
533}
534
535/*
536 * describe : this function is use to close pcm handle
537 * paras :
538 * pcm : pcm handle to close
539 * return :
540 */
541int quec_pcm_close(struct pcm *pcm )
542{
543 return 0;
544}
545
546/*
547 * describe : this function is use to read pcm buffer
548 * paras :
549 * pcm : pcm handle to write date
550 * buffer: data buffer
551 * lenth: data length
552 * return :
553 */
554int quec_read_pcm(struct pcm *pcm, void * buffer, int length)
555{
556
557 return 0;
558}
559
560/*
561 * describe : this function is use to get pcm buffer lenth
562 * paras :
563 * lenth: data length
564 * return
565 * buffer length
566 */
567int quec_get_pem_buffer_len(struct pcm *pcm)
568{
569
570 return 0;
571}
572
573void dtmf_cb1(char dtmf)
574{
575 printf("%s:%c\n", __FUNCTION__, dtmf);
576}
577
578/**
579 * @brief Set RX DSP Gain
580 * @details
581 * Gain support [-36,12] dB
582 *
583 * @param gain
584 * DSP gain
585 */
586
587int Ql_Rxgain_Set(int value)
588{
luojiana6a47a92024-05-23 13:42:21 +0800589 mbtk_dsp_gain_set(1, value);
b.liu5fa9e772023-11-23 18:00:55 +0800590 return 0;
liubin281ac462023-07-19 14:22:54 +0800591}
592
593
594/** Ql_Playback_Samprate_Set
595 * @brief Set Playback PCM Samprate
596 * @details
597 * 0 for NB 1 for WB
598 *
599 * @param samprate
600 * samprate for PCM playback,default value is PCM NB
601 */
602int Ql_Playback_Samprate_Set(int samprate)
603{
604 printf("samprate is %d \n",samprate);
605 if(samprate == 1)
606 {
b.liuc181beb2024-03-07 18:34:21 +0800607 sample_rate = 16000;
luojiana6a47a92024-05-23 13:42:21 +0800608 mbtk_audio_pcm_sample_rate_set(MBTK_AUDIO_SAMPLE_RATE_16000);
liubin281ac462023-07-19 14:22:54 +0800609 }
610 else{
luojiana6a47a92024-05-23 13:42:21 +0800611 mbtk_audio_pcm_sample_rate_set(MBTK_AUDIO_SAMPLE_RATE_8000);
b.liuc181beb2024-03-07 18:34:21 +0800612 sample_rate = 8000;
liubin281ac462023-07-19 14:22:54 +0800613 }
614
615 return 0;
616}
617
618int Ql_Mp3_To_Wav(const char *wavpath, char *mp3path)
619{
b.liuc1064f82023-10-11 16:47:39 +0800620 return 0;
liubin281ac462023-07-19 14:22:54 +0800621}
622
623int Ql_Mp3_To_Play(char *mp3path, int hdl,int sample_rate)
624{
b.liuc1064f82023-10-11 16:47:39 +0800625 return 0;
liubin281ac462023-07-19 14:22:54 +0800626}
627
628//add by grady, 2018-6-2
629/*
630 * describe : this function is use to open mixer device
631 * paras :
632 * device: mixer device
633 * return
634 * mixer handle
635 */
636struct mixer *quec_mixer_open(const char *device)
637{
638
639 return NULL;
640}
641
642/*
643 * describe : this function is use to close mixer device
644 * paras :
645 * mixer: mixer handle
646 * return
647 * none
648 */
649void quec_mixer_close(struct mixer *mixer)
650{
651
652
653}
654
655/*
656 * describe : this function is use to get mixer devie control
657 * paras :
658 * mixer: mixer handle
659 * name: mixer device
660 * index: mixer index
661 * return
662 * mixer control
663 */
664struct mixer_ctl *quec_mixer_get_control(struct mixer *mixer, const char *name, unsigned index)
665{
666
667 return NULL;
668}
669
670/*
671 * describe : this function is use to set mulvalues
672 * paras :
673 * mixer: mixer handle
674 * count: count
675 * argv: data
676 * return :
677 *
678 */
679int quec_mixer_ctl_mulvalues(struct mixer_ctl *ctl, int count, char ** argv)
680{
681
682 return 0;
683}
684
685
686//end grady
687
688/*****************************************************************
689* Function: Ql_AudPlayer_OpenExt
690*
691* Description:
692* expend function from Ql_AudPlayer_OpenExt
693* Open audio play device, and specify the callback function.
694* This function can be called twice to play different audio sources.
695*
696* Parameters:
697* device : a string that specifies the PCM device.
698* NULL, means the audio will be played on the default PCM device.
699*
700* If you want to mixedly play audio sources, you can call this
701* API twice with specifying different PCM device.
702* The string devices available:
703* "hw:0,0" (the default play device)
704* "hw:0,13" (this device can mix audio and TTS)
705* "hw:0,14"
706*
707* cb_func : callback function for audio player.
708* The results of all operations on audio player
709* are informed in callback function.
710*
711* flags : pcm flags, eg: PCM_MMAP, PCM_NMMAP.
712*
713* channels: pcm sample channels.
714*
715* rate : pcm sample rate.
716*
717* format : pcm sample fromat
718*
719* Return:
720* pcm device handle
721* NULL, fail
722*****************************************************************/
723int Ql_AudPlayer_OpenExt(
724 char *dev,
725 _cb_onPlayer cb_fun,
726 int flags,
727 int channels,
728 int rate,
729 int format)
730{
731 return 0;
732}
733
734/*****************************************************************
735* Function: Ql_AudRecorder_Open
736*
737* Description:
738* Open audio record device, and specify the callback function.
739*
740* Parameters:
741* device : not used. MUST be NULL.
742*
743* cb_func : callback function for audio player.
744* The results of all operations on audio recorder
745* are informed in callback function.
746*
747* flags : pcm flags, eg: PCM_MMAP, PCM_NMMAP.
748*
749* channels: pcm sample channels.
750*
751* rate : pcm sample rate.
752*
753* format : pcm sample fromat
754*
755* Return:
756* pcm device handle
757* NULL, fail
758*****************************************************************/
759int Ql_AudRecorder_OpenExt(
760 char *dev,
761 _cb_onRecorder cb_fun,
762 int flags,
763 int channels,
764 int rate,
765 int format)
766{
767
768
769 return 0;
770}
771
772/*
773* Function: uac enable
774*
775* Description:
776* uac enable
777*
778* Parameters:
779* none
780* Return:
781* TURE or FALSE
782*/
783int ql_uac_enable(void)
784{
785
786 return 0;
787}
788
789/*
790* Function: uac disable
791*
792* Description:
793* uac disable
794*
795* Parameters:
796* none
797* Return:
798* TURE or FALSE
799*/
800int ql_uac_disable(void)
801{
802
803 return 0;
luojiana6a47a92024-05-23 13:42:21 +0800804}