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