| |
| #include "ql/ql_audio.h" |
| #include "mbtk_log.h" |
| #include "mbtk_audio2.h" |
| |
| typedef enum { |
| AUDIO_PLAY_STATE_STOP, |
| AUDIO_PLAY_STATE_RUNNING, |
| AUDIO_PLAY_STATE_PAUSE |
| } audio_play_state_enum; |
| |
| #define AUDIO_HANDLE 1 |
| #define WAV_PLAY_BUFF 1024 |
| |
| #ifdef MBTK_AF_SUPPORT |
| static mbtk_audio_handle player_hdl = NULL; |
| static int player_hdl_1 = AUDIO_HANDLE; |
| static _cb_onRecorder record_cb_fun = NULL; |
| static int Samprate = 8000; |
| #endif |
| |
| static int sample_rate = 8000; |
| static int play_handle = AUDIO_HANDLE; |
| static _cb_onPlayer play_cb_func = NULL; |
| static _cb_onRecorder recorder_cb_fun = NULL; |
| static int is_running = 0; |
| static audio_play_state_enum play_state = AUDIO_PLAY_STATE_STOP; |
| static int play_exit = 1; |
| |
| static void recorder_cb_func(void *data, uint32 data_len) |
| { |
| if(recorder_cb_fun) { |
| recorder_cb_fun(AUD_RECORDER_START, (unsigned char*)data, data_len); |
| } |
| } |
| |
| static int play_stream(unsigned char* pData, unsigned int length) |
| { |
| int rc, len, frames = 0; |
| int result = 0; |
| |
| play_state = AUDIO_PLAY_STATE_RUNNING; |
| play_exit = 0; |
| int data_send = 0; |
| |
| if (mbtk_audio_pcm_play_start()) { |
| printf("%s: error opening output device.", __FUNCTION__); |
| return -1; |
| } |
| |
| if(pData && length > 0) { |
| while (play_state != AUDIO_PLAY_STATE_STOP) { |
| if(play_state == AUDIO_PLAY_STATE_RUNNING) { |
| if (data_send >= length) { |
| LOGE("%s: Read pcm stream end.", __FUNCTION__); |
| break; |
| } |
| |
| if(length - data_send > WAV_PLAY_BUFF) { |
| len = WAV_PLAY_BUFF; |
| } else { |
| len = length - data_send; |
| } |
| |
| if((rc = mbtk_audio_pcm_play_data_send(pData + data_send, len)) != len) { |
| LOGE("Send data %d/%d", rc, len); |
| result = -1; |
| goto thread_end; |
| } |
| |
| data_send += len; |
| |
| LOGD("%s: No.%d frame playback", __FUNCTION__, ++frames); |
| } else { |
| usleep(200000); |
| } |
| } |
| } else { |
| result = -1; |
| } |
| |
| play_state = AUDIO_PLAY_STATE_STOP; |
| |
| |
| thread_end: |
| mbtk_audio_pcm_play_stop(); |
| play_exit = 1; |
| LOGD("%s: finished pcm playback.", __FUNCTION__); |
| return result; |
| } |
| |
| static int play_by_fd(int fd, int offset) |
| { |
| int rc, len, frames = 0; |
| int result = 0; |
| char buf[WAV_PLAY_BUFF]; |
| |
| play_state = AUDIO_PLAY_STATE_RUNNING; |
| if(play_cb_func) |
| play_cb_func(play_handle , AUDIO_PLAY_STATE_RUNNING); |
| play_exit = 0; |
| if(fd > 0) { |
| if(offset > 0) { |
| lseek(fd, offset, SEEK_SET); |
| } |
| |
| if (mbtk_audio_pcm_play_start()) { |
| printf("%s: error opening output device.", __FUNCTION__); |
| return -1; |
| } |
| |
| |
| while (play_state != AUDIO_PLAY_STATE_STOP) { |
| if(play_state == AUDIO_PLAY_STATE_RUNNING) { |
| memset(buf, 0x00, sizeof(buf)); |
| len = read(fd, buf, WAV_PLAY_BUFF); |
| if (len == -1) { |
| LOGE("%s: error reading from file", __FUNCTION__); |
| result = -1; |
| goto thread_end; |
| } |
| |
| if (len == 0) { |
| /* reached EOF */ |
| LOGE("%s: Read wav file end.", __FUNCTION__); |
| break; |
| } |
| |
| if((rc = mbtk_audio_pcm_play_data_send(buf, len)) < len) { |
| LOGE("Send data %d/%d", rc, len); |
| result = -1; |
| goto thread_end; |
| } |
| |
| LOGD("%s: No.%d frame playback", __FUNCTION__, ++frames); |
| } else { |
| usleep(200000); |
| } |
| } |
| } else { |
| result = -1; |
| } |
| |
| play_state = AUDIO_PLAY_STATE_STOP; |
| if(play_cb_func) |
| play_cb_func(play_handle , AUDIO_PLAY_STATE_STOP); |
| |
| thread_end: |
| mbtk_audio_pcm_play_stop(); |
| play_exit = 1; |
| LOGD("%s: finished pcm playback.", __FUNCTION__); |
| return result; |
| } |
| |
| /***************************************************************** |
| * Function: Ql_AudPlayer_Open |
| * |
| * Description: |
| * Open audio play device, and specify the callback function. |
| * This function can be called twice to play different audio sources. |
| * |
| * Parameters: |
| * device : a string that specifies the PCM device. |
| * NULL, means the audio will be played on the default PCM device. |
| * |
| * If you want to mixedly play audio sources, you can call this |
| * API twice with specifying different PCM device. |
| * The string devices available: |
| * "hw:0,0" (the default play device) |
| * "hw:0,13" (this device can mix audio and TTS) |
| * "hw:0,14" |
| * |
| * cb_func : callback function for audio player. |
| * The results of all operations on audio player |
| * are informed in callback function. |
| * |
| * Return: |
| * pcm device handle on success |
| * -1 for failure |
| *****************************************************************/ |
| int Ql_AudPlayer_Open(char* device, _cb_onPlayer cb_func) |
| { |
| #ifdef MBTK_AF_SUPPORT |
| player_hdl = mbtk_audio_open_new(MBTK_AUTIO_TYPE_OUT, 1, Samprate, cb_func); |
| if(player_hdl == NULL) |
| { |
| return -1; |
| } |
| else |
| { |
| return player_hdl_1 = AUDIO_HANDLE; |
| } |
| #else |
| if(is_running || mbtk_audio_pcm_init()) { |
| return -1; |
| } else { |
| play_cb_func = cb_func; |
| is_running = 1; |
| return play_handle; |
| } |
| #endif |
| } |
| |
| /*======================================================================== |
| FUNCTION: Ql_AudPlayer_Play |
| =========================================================================*/ |
| /** @brief |
| This function writes pcm data to pcm device to play. |
| |
| @param[in] hdl, the handle returned by Ql_AudPlayer_Open(). |
| @param[in] pData, pointer to the start address of pcm data. |
| @param[in] length, the length of pcm data. |
| |
| @return |
| on success, the return value is the number of bytes to play |
| on failure, the return value is -1; |
| |
| @dependencies |
| Ql_AudPlayer_Open() must be first called successfully. |
| */ |
| /*=======================================================================*/ |
| int Ql_AudPlayer_Play(int hdl, unsigned char* pData, unsigned int length) |
| { |
| #ifdef MBTK_AF_SUPPORT |
| if(hdl != player_hdl_1 || player_hdl == NULL){ |
| LOGE("Handle error : %d", hdl); |
| return -1; |
| } |
| return mbtk_audio_play_stream_new((void *)player_hdl, pData, length,50); |
| |
| #else |
| if(!is_running || hdl != play_handle) { |
| LOGE("Handle error : %d", hdl); |
| return -1; |
| } |
| |
| return play_stream(pData, length); |
| #endif |
| } |
| |
| /*======================================================================== |
| FUNCTION: Ql_AudPlayer_PlayFrmFile |
| =========================================================================*/ |
| /** @brief |
| This function plays the pcm data from the specified file. |
| |
| @param[in] hdl, the handle returned by Ql_AudPlayer_Open(). |
| @param[in] fd, a file descriptor that contains pcm data. |
| Note: |
| the file offset should be set to the start position of pcm |
| data region, which means you should move the file offset |
| skipping the file header (such as wave header, amr header). |
| @param[in] offset, file offset. Please set it to -1 if no need to use. |
| |
| @return |
| 0 on success |
| -1 on failure |
| |
| @dependencies |
| Ql_AudPlayer_Open() must be first called successfully. |
| */ |
| /*=======================================================================*/ |
| |
| int Ql_AudPlayer_PlayFrmFile(int hdl, int fd, int offset) |
| { |
| #ifdef MBTK_AF_SUPPORT |
| if(hdl != player_hdl_1 || player_hdl == NULL){ |
| LOGE("Handle error : %d", hdl); |
| return -1; |
| } |
| |
| return mbtk_audio_play_file_new((void *)player_hdl, fd, offset); |
| |
| #else |
| if(!is_running || hdl != play_handle) { |
| LOGE("Handle error : %d", hdl); |
| return -1; |
| } |
| |
| return play_by_fd(fd, offset); |
| #endif |
| } |
| |
| // |
| // Function: Ql_AudPlayer_Pause |
| // |
| // Description: |
| // Pause playing. |
| // @param hdl: |
| // Handle received from Ql_AudPlayer_Open(). |
| int Ql_AudPlayer_Pause(int hdl) |
| { |
| if(!is_running || hdl != play_handle) { |
| LOGE("Handle error : %d", hdl); |
| return -1; |
| } |
| |
| play_state = AUDIO_PLAY_STATE_PAUSE; |
| |
| while(!play_exit) { |
| usleep(10000); |
| } |
| |
| return 0; |
| } |
| |
| // |
| // Function: Ql_AudPlayer_Resume |
| // |
| // Description: |
| // Resume playing. |
| // @param hdl: |
| // Handle received from Ql_AudPlayer_Open(). |
| int Ql_AudPlayer_Resume(int hdl) |
| { |
| if(!is_running || hdl != play_handle) { |
| LOGE("Handle error : %d", hdl); |
| return -1; |
| } |
| |
| play_state = AUDIO_PLAY_STATE_RUNNING; |
| |
| while(!play_exit) { |
| usleep(10000); |
| } |
| return 0; |
| } |
| |
| // |
| // Function: Ql_AudPlayer_Stop |
| // |
| // Description: |
| // Stop playing audio |
| // hdl: |
| // Handle received from Ql_AudPlayer_Open(). |
| void Ql_AudPlayer_Stop(int hdl) |
| { |
| if(!is_running || hdl != play_handle) { |
| LOGE("Handle error : %d", hdl); |
| return; |
| } |
| |
| play_state = AUDIO_PLAY_STATE_STOP; |
| |
| while(!play_exit) { |
| usleep(10000); |
| } |
| } |
| |
| // |
| // Function: Ql_AudPlayer_Close |
| // |
| // Description: |
| // Close player, and free the resource. |
| // @param hdl: |
| // Handle received from Ql_AudPlayer_Open(). |
| void Ql_AudPlayer_Close(int hdl) |
| { |
| #ifdef MBTK_AF_SUPPORT |
| if(hdl != player_hdl_1 || player_hdl == NULL){ |
| LOGE("Handle error : %d", hdl); |
| return -1; |
| } |
| |
| mbtk_audio_close_new((void *)player_hdl); |
| player_hdl_1 = 0; |
| |
| #else |
| if(!is_running || hdl != play_handle) { |
| LOGE("Handle error : %d", hdl); |
| return; |
| } |
| play_state = AUDIO_PLAY_STATE_STOP; |
| |
| while(!play_exit) { |
| usleep(10000); |
| } |
| |
| is_running = 0; |
| mbtk_audio_pcm_deinit(); |
| #endif |
| } |
| |
| |
| int Ql_AudPlayer_set_LessDataThreshold(int hdl, unsigned short threshSize) |
| { |
| |
| return 0; |
| } |
| |
| int Ql_AudPlayer_get_freeSpace(int hdl) |
| { |
| |
| return 0; |
| } |
| |
| |
| /***************************************************************** |
| * Function: Ql_AudRecorder_Open |
| * |
| * Description: |
| * Open audio record device, and specify the callback function. |
| * |
| * Parameters: |
| * device : not used. MUST be NULL. |
| * |
| * cb_func : callback function for audio player. |
| * The results of all operations on audio recorder |
| * are informed in callback function. |
| * |
| * Return: |
| * pcm device handle |
| * -1 for failure |
| *****************************************************************/ |
| int Ql_AudRecorder_Open(char* device, _cb_onRecorder cb_fun) |
| { |
| if(is_running || mbtk_audio_pcm_init()) { |
| return -1; |
| } else { |
| is_running = 1; |
| recorder_cb_fun = cb_fun; |
| return play_handle; |
| } |
| } |
| |
| // |
| // Function: Ql_AudRecorder_StartRecord |
| // |
| // Description: |
| // Start to record. |
| // The record data is output in _cb_onRecorder. |
| // |
| // Return: |
| // 0 on success |
| // -1 on failure |
| int Ql_AudRecorder_StartRecord(void) |
| { |
| if(!is_running) { |
| LOGE("No open device."); |
| return -1; |
| } |
| |
| return mbtk_audio_pcm_recorder_start(recorder_cb_func); |
| } |
| |
| // |
| // Function: Ql_AudRecorder_Pause |
| // |
| // Description: |
| // Pause recording |
| int Ql_AudRecorder_Pause(void) |
| { |
| if(!is_running) { |
| LOGE("No open device."); |
| return -1; |
| } |
| |
| return mbtk_audio_pcm_recorder_pause(); |
| } |
| |
| // |
| // Function: Ql_AudRecorder_Resume |
| // |
| // Description: |
| // Resume recording |
| int Ql_AudRecorder_Resume(void) |
| { |
| if(!is_running) { |
| LOGE("No open device."); |
| return -1; |
| } |
| |
| return mbtk_audio_pcm_recorder_resume(); |
| } |
| |
| // |
| // Function: Ql_AudRecorder_Stop |
| // |
| // Description: |
| // Stop recording |
| void Ql_AudRecorder_Stop(void) |
| { |
| if(!is_running) { |
| LOGE("No open device."); |
| return; |
| } |
| |
| mbtk_audio_pcm_recorder_stop(); |
| } |
| |
| // |
| // Function: Ql_AudRecorder_Close |
| // |
| // Description: |
| // Close recorder, and free the resource |
| void Ql_AudRecorder_Close(void) |
| { |
| if(!is_running) { |
| LOGE("No open device."); |
| return; |
| } |
| |
| is_running = 0; |
| mbtk_audio_pcm_deinit(); |
| } |
| |
| // |
| // Function: Ql_clt_set_mixer_value |
| // |
| // Description: |
| // Close recorder, and free the resource |
| boolean Ql_clt_set_mixer_value(const char *device, int count, const char *value) |
| { |
| |
| return FALSE; |
| } |
| |
| |
| int Ql_AudTone_Open(char* device, _cb_onPlayer cb)//cb not support now |
| { |
| return 0; |
| } |
| |
| int Ql_AudTone_Start(int hdl, struct Ql_TonePara *para) |
| { |
| return 0; |
| } |
| |
| void Ql_AudTone_Stop(int hdl) |
| { |
| |
| } |
| |
| void Ql_AudTone_Close(int hdl) |
| { |
| |
| } |
| |
| |
| //****************QL Codec API************************// |
| |
| // |
| // Function: Ql_AudCodec_Set_ALC5616_DRCAGC |
| // |
| // Description: |
| // Set ALC5616 DRC/AGC configuration |
| int Ql_AudCodec_Set_ALC5616_DRCAGC(const char *i2c, struct Ql_ALC5616_DRCAGC *cfg) |
| { |
| return 0; |
| } |
| |
| // |
| // Function: Ql_Update_wav_size |
| // |
| // Description: |
| // update wav format file size in the header |
| // @param fd: |
| // wav file discriptor |
| // @param size: |
| // wav file size to update |
| int Ql_Update_wav_size(int fd, int size) |
| { |
| return 0; |
| } |
| |
| //add by grady, 2018-5-29 |
| /* |
| * describe : this function is use to open pcm device |
| * paras : |
| * device : this should be fix to hw:0,0 |
| * flags ; pcm play flags |
| * rate: sample rate |
| * channels : audio channal 1 or 2 |
| * format: format to play or record, 16bit line,MP3 |
| * hostless: if there is no file it is true |
| * return : |
| * pcm : pcm handle, use can use this handle to read write data |
| */ |
| struct pcm *quec_pcm_open(char *device, unsigned flags, unsigned rate, unsigned channels, unsigned format, unsigned hostless) |
| { |
| return NULL; |
| } |
| |
| /* |
| * describe : this function is use to close pcm handle |
| * paras : |
| * pcm : pcm handle to close |
| * return : |
| */ |
| int quec_pcm_close(struct pcm *pcm ) |
| { |
| return 0; |
| } |
| |
| /* |
| * describe : this function is use to read pcm buffer |
| * paras : |
| * pcm : pcm handle to write date |
| * buffer: data buffer |
| * lenth: data length |
| * return : |
| */ |
| int quec_read_pcm(struct pcm *pcm, void * buffer, int length) |
| { |
| |
| return 0; |
| } |
| |
| /* |
| * describe : this function is use to get pcm buffer lenth |
| * paras : |
| * lenth: data length |
| * return |
| * buffer length |
| */ |
| int quec_get_pem_buffer_len(struct pcm *pcm) |
| { |
| |
| return 0; |
| } |
| |
| void dtmf_cb1(char dtmf) |
| { |
| printf("%s:%c\n", __FUNCTION__, dtmf); |
| } |
| |
| /** |
| * @brief Set RX DSP Gain |
| * @details |
| * Gain support [-36,12] dB |
| * |
| * @param gain |
| * DSP gain |
| */ |
| |
| int Ql_Rxgain_Set(int value) |
| { |
| #ifdef MBTK_AF_SUPPORT |
| int volume =0; |
| if(value < -36 || value > 13) |
| { |
| volume = 0; |
| } |
| else |
| { |
| volume = value; |
| } |
| |
| if(player_hdl==NULL) |
| return 0; |
| |
| char databuf[1025]={0}; |
| memcpy(databuf, " ", 1024); |
| |
| mbtk_audio_play_stream_new(player_hdl, databuf, 1024, volume); |
| return 0; |
| #else |
| mbtk_dsp_gain_set(1, value); |
| return 0; |
| #endif |
| return 0; |
| } |
| |
| |
| /** Ql_Playback_Samprate_Set |
| * @brief Set Playback PCM Samprate |
| * @details |
| * 0 for NB 1 for WB |
| * |
| * @param samprate |
| * samprate for PCM playback,default value is PCM NB |
| */ |
| int Ql_Playback_Samprate_Set(int samprate) |
| { |
| printf("samprate is %d \n",samprate); |
| if(samprate == 1) |
| { |
| sample_rate = 16000; |
| mbtk_audio_pcm_sample_rate_set(MBTK_AUDIO_SAMPLE_RATE_16000); |
| } |
| else{ |
| mbtk_audio_pcm_sample_rate_set(MBTK_AUDIO_SAMPLE_RATE_8000); |
| sample_rate = 8000; |
| } |
| |
| return 0; |
| } |
| |
| int Ql_Mp3_To_Wav(const char *wavpath, char *mp3path) |
| { |
| return 0; |
| } |
| |
| int Ql_Mp3_To_Play(char *mp3path, int hdl,int sample_rate) |
| { |
| return 0; |
| } |
| |
| //add by grady, 2018-6-2 |
| /* |
| * describe : this function is use to open mixer device |
| * paras : |
| * device: mixer device |
| * return |
| * mixer handle |
| */ |
| struct mixer *quec_mixer_open(const char *device) |
| { |
| |
| return NULL; |
| } |
| |
| /* |
| * describe : this function is use to close mixer device |
| * paras : |
| * mixer: mixer handle |
| * return |
| * none |
| */ |
| void quec_mixer_close(struct mixer *mixer) |
| { |
| |
| |
| } |
| |
| /* |
| * describe : this function is use to get mixer devie control |
| * paras : |
| * mixer: mixer handle |
| * name: mixer device |
| * index: mixer index |
| * return |
| * mixer control |
| */ |
| struct mixer_ctl *quec_mixer_get_control(struct mixer *mixer, const char *name, unsigned index) |
| { |
| |
| return NULL; |
| } |
| |
| /* |
| * describe : this function is use to set mulvalues |
| * paras : |
| * mixer: mixer handle |
| * count: count |
| * argv: data |
| * return : |
| * |
| */ |
| int quec_mixer_ctl_mulvalues(struct mixer_ctl *ctl, int count, char ** argv) |
| { |
| |
| return 0; |
| } |
| |
| |
| //end grady |
| |
| /***************************************************************** |
| * Function: Ql_AudPlayer_OpenExt |
| * |
| * Description: |
| * expend function from Ql_AudPlayer_OpenExt |
| * Open audio play device, and specify the callback function. |
| * This function can be called twice to play different audio sources. |
| * |
| * Parameters: |
| * device : a string that specifies the PCM device. |
| * NULL, means the audio will be played on the default PCM device. |
| * |
| * If you want to mixedly play audio sources, you can call this |
| * API twice with specifying different PCM device. |
| * The string devices available: |
| * "hw:0,0" (the default play device) |
| * "hw:0,13" (this device can mix audio and TTS) |
| * "hw:0,14" |
| * |
| * cb_func : callback function for audio player. |
| * The results of all operations on audio player |
| * are informed in callback function. |
| * |
| * flags : pcm flags, eg: PCM_MMAP, PCM_NMMAP. |
| * |
| * channels: pcm sample channels. |
| * |
| * rate : pcm sample rate. |
| * |
| * format : pcm sample fromat |
| * |
| * Return: |
| * pcm device handle |
| * NULL, fail |
| *****************************************************************/ |
| int Ql_AudPlayer_OpenExt( |
| char *dev, |
| _cb_onPlayer cb_fun, |
| int flags, |
| int channels, |
| int rate, |
| int format) |
| { |
| return 0; |
| } |
| |
| /***************************************************************** |
| * Function: Ql_AudRecorder_Open |
| * |
| * Description: |
| * Open audio record device, and specify the callback function. |
| * |
| * Parameters: |
| * device : not used. MUST be NULL. |
| * |
| * cb_func : callback function for audio player. |
| * The results of all operations on audio recorder |
| * are informed in callback function. |
| * |
| * flags : pcm flags, eg: PCM_MMAP, PCM_NMMAP. |
| * |
| * channels: pcm sample channels. |
| * |
| * rate : pcm sample rate. |
| * |
| * format : pcm sample fromat |
| * |
| * Return: |
| * pcm device handle |
| * NULL, fail |
| *****************************************************************/ |
| int Ql_AudRecorder_OpenExt( |
| char *dev, |
| _cb_onRecorder cb_fun, |
| int flags, |
| int channels, |
| int rate, |
| int format) |
| { |
| |
| |
| return 0; |
| } |
| |
| /* |
| * Function: uac enable |
| * |
| * Description: |
| * uac enable |
| * |
| * Parameters: |
| * none |
| * Return: |
| * TURE or FALSE |
| */ |
| int ql_uac_enable(void) |
| { |
| |
| return 0; |
| } |
| |
| /* |
| * Function: uac disable |
| * |
| * Description: |
| * uac disable |
| * |
| * Parameters: |
| * none |
| * Return: |
| * TURE or FALSE |
| */ |
| int ql_uac_disable(void) |
| { |
| |
| return 0; |
| } |