Initial import of NFC GNSS SDK project
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
/*------------------------------------------------------------
|
||||
(C) Copyright [2006-2008] Marvell International Ltd.
|
||||
All Rights Reserved
|
||||
------------------------------------------------------------*/
|
||||
|
||||
/*--------------------------------------------------------------------------------------------------------------------
|
||||
INTEL CONFIDENTIAL
|
||||
Copyright 2006 Intel Corporation All Rights Reserved.
|
||||
The source code contained or described herein and all documents related to the source code ("Material") are owned
|
||||
by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or
|
||||
its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of
|
||||
Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and
|
||||
treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted,
|
||||
transmitted, distributed, or disclosed in any way without Intel's prior express written permission.
|
||||
|
||||
No license under any patent, copyright, trade secret or other intellectual property right is granted to or
|
||||
conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement,
|
||||
estoppel or otherwise. Any license under such intellectual property rights must be express and approved by
|
||||
Intel in writing.
|
||||
-------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#include "diags.h"
|
||||
#include "platform.h"
|
||||
#include "audio_config.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Global function for FOTA upgrade.
|
||||
0: system in NOT in FOTA upgrade, should do audio processing
|
||||
1: system is in FOTA upgrade, should bypass audio processing
|
||||
***************************************************************************/
|
||||
extern BOOL IsMiniSystem(void);
|
||||
|
||||
|
||||
extern void audioPhase1Init_internal(void);
|
||||
extern void audioPhase2Init_internal(void);
|
||||
extern void audioServerPhase2Init_internal(void);
|
||||
extern void audioGsmResumeCB_internal(void);
|
||||
extern void audioGsmSuspendCB_internal(void);
|
||||
extern void amrSuspend_internal(void);
|
||||
extern void amrResume_internal(void);
|
||||
extern void LteVoiceSuspend_internal(void);
|
||||
extern void LteVoiceResume_internal(void);
|
||||
extern BOOL CraneCodecADCOnOff_internal(BOOL OnOff);
|
||||
|
||||
|
||||
static void audioGsmCB_NULL(void)
|
||||
{
|
||||
DIAG_FILTER(AUDIO, Voice, audioGsmCB_NULL, DIAG_ERROR)
|
||||
diagTextPrintf("audioGsmCB_NULL");
|
||||
}
|
||||
|
||||
|
||||
static void Audio_Init_FakeBind(void)
|
||||
{
|
||||
|
||||
|
||||
#if !defined (INTEL_2CHIP_PLAT_BVD)
|
||||
#if !NO_APLP
|
||||
#if defined (_AUDIO_HANDOVER_)
|
||||
#if defined (INTEL_UPGRADE_DUAL_RAT )
|
||||
extern void audioBindGsmResume(void(*)());
|
||||
extern void audioBindGsmSuspend(void(*)());
|
||||
extern void audioBindGsmStartTest(void(*)());
|
||||
extern void audioBindGsmStopTest(void(*)());
|
||||
audioBindGsmResume(audioGsmCB_NULL);
|
||||
audioBindGsmSuspend(audioGsmCB_NULL);
|
||||
audioBindGsmStartTest(audioGsmCB_NULL);
|
||||
audioBindGsmStopTest(audioGsmCB_NULL);
|
||||
#endif /*INTEL_UPGRADE_DUAL_RAT */
|
||||
#endif /*_AUDIO_HANDOVER_*/
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void audioServerPhase2Init(void)
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
audioServerPhase2Init_internal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Function: audioPhase1Init
|
||||
* Description:
|
||||
* Parameters: none
|
||||
* Return Value: none .
|
||||
***************************************************************************/
|
||||
//ICAT EXPORTED FUNCTION - Audio,Common,audioPhase1Init
|
||||
void audioPhase1Init(void)
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
audioPhase1Init_internal();
|
||||
}
|
||||
else
|
||||
{
|
||||
Audio_Init_FakeBind();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !NO_APLP
|
||||
/****************************************************************************
|
||||
* Function: audioPhase2Init
|
||||
* Description:
|
||||
* Parameters: none
|
||||
* Return Value: none .
|
||||
***************************************************************************/
|
||||
//ICAT EXPORTED FUNCTION - Audio,Common,audioPhase2Init
|
||||
void audioPhase2Init(void)
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
audioPhase2Init_internal();
|
||||
}
|
||||
}
|
||||
#endif // !NO_APLP
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Function: amrResume
|
||||
* Description: AudioCtrl API - called to resume AMR activity when it is suspended.
|
||||
* Call: Protocol Stack
|
||||
* Parameters: none
|
||||
* Return Value: none .
|
||||
***************************************************************************/
|
||||
//ICAT EXPORTED FUNCTION - Audio,Voice,amrResume
|
||||
void amrResume(void)
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
amrResume_internal();
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: amrSuspend
|
||||
* Description: AudioCtrl API - called to temporary suspend AMR activity
|
||||
* during hard handover.
|
||||
* Call: Protocol Stack
|
||||
* Parameters: none
|
||||
* Return Value: none .
|
||||
***************************************************************************/
|
||||
//ICAT EXPORTED FUNCTION - Audio,Voice,amrSuspend
|
||||
void amrSuspend(void)
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
amrSuspend_internal();
|
||||
}
|
||||
}
|
||||
|
||||
void audioGsmSuspendCB(void)
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
audioGsmSuspendCB_internal();
|
||||
}
|
||||
}
|
||||
|
||||
void audioGsmResumeCB(void)
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
audioGsmResumeCB_internal();
|
||||
}
|
||||
}
|
||||
|
||||
void LteVoiceSuspend()//LTE handover/reselect to GSM/UMTS
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
LteVoiceSuspend_internal();
|
||||
}
|
||||
}
|
||||
|
||||
//ICAT EXPORTED FUNCTION - ADEMO, Voice, LteVoiceResume
|
||||
void LteVoiceResume()//LTE handover/reselect to GSM/UMTS fails || GSM/UMTS handover to LTE
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
LteVoiceResume_internal();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CraneCodecADCOnOff(BOOL OnOff)
|
||||
{
|
||||
if(!IsMiniSystem())
|
||||
{
|
||||
return CraneCodecADCOnOff_internal(OnOff);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configure variable
|
||||
#-------------------------------------------------------------------------------
|
||||
TOP_DIR:=${TOP_DIR}
|
||||
MAKEFILE_PATH :=$(subst $(strip \),/,$(abspath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configure source code files
|
||||
#-------------------------------------------------------------------------------
|
||||
SRC_FILES+= \
|
||||
ql_audio_old_api.c \
|
||||
ql_audio.c \
|
||||
AudioExtern.c \
|
||||
quec_audio.c \
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# the include directories
|
||||
#-------------------------------------------------------------------------------
|
||||
INC_DIRS+= \
|
||||
-I${TOP_DIR}\ \
|
||||
-I${TOP_DIR}\common\include \
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configure compile flag for C
|
||||
#-------------------------------------------------------------------------------
|
||||
ifneq (,$(findstring 1606,${ASR_PLATFORM}))
|
||||
U_FLAGS+= \
|
||||
|
||||
endif
|
||||
ifneq (,$(findstring 1602,${ASR_PLATFORM}))
|
||||
U_FLAGS+= \
|
||||
|
||||
endif
|
||||
ifneq (,$(findstring 1605,${ASR_PLATFORM}))
|
||||
U_FLAGS+= \
|
||||
|
||||
endif
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configure compile flag for C++
|
||||
#-------------------------------------------------------------------------------
|
||||
U_CPPFLAGS+=
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configure default macro define
|
||||
#-------------------------------------------------------------------------------
|
||||
ifneq (,$(findstring 1606,${ASR_PLATFORM}))
|
||||
DFLAGS+= \
|
||||
-D"NO_APLP=0" \
|
||||
-D"GPRS_MULTISLOT_CLASS=12" \
|
||||
-DGPIO_TRACE \
|
||||
-D"EGPRS_MULTISLOT_CLASS=12" \
|
||||
|
||||
endif
|
||||
ifneq (,$(findstring 1602,${ASR_PLATFORM}))
|
||||
DFLAGS+= \
|
||||
-D"NO_APLP=0" \
|
||||
-D"GPRS_MULTISLOT_CLASS=12" \
|
||||
-DGPIO_TRACE \
|
||||
-D"EGPRS_MULTISLOT_CLASS=12" \
|
||||
|
||||
endif
|
||||
ifneq (,$(findstring 1605,${ASR_PLATFORM}))
|
||||
DFLAGS+= \
|
||||
-D"NO_APLP=0" \
|
||||
-D"GPRS_MULTISLOT_CLASS=12" \
|
||||
-DGPIO_TRACE \
|
||||
-D"EGPRS_MULTISLOT_CLASS=12" \
|
||||
|
||||
endif
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configure link library
|
||||
#-------------------------------------------------------------------------------
|
||||
U_LIBS:=
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# include mk file
|
||||
#-------------------------------------------------------------------------------
|
||||
include ${TOP_DIR}\config\common\makefile.mk
|
||||
@@ -0,0 +1,235 @@
|
||||
/*================================================================
|
||||
Copyright (c) 2022, Quectel Wireless Solutions Co., Ltd. All rights reserved.
|
||||
Quectel Wireless Solutions Proprietary and Confidential.
|
||||
=================================================================*/
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ql_audio.c
|
||||
* @author august.yang
|
||||
* @version V1.0.0
|
||||
* @date 2022/04/09
|
||||
* @brief ´ËÎļþ´æ·ÅaudioÏà¹ØapiµÄ·â×°
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef NO_AUDIO
|
||||
#include "ql_audio.h"
|
||||
#include "acm_calibration.h"
|
||||
|
||||
/*audio_hal api*/
|
||||
int ql_get_audio_state(void)
|
||||
{
|
||||
return quec_get_audio_state();
|
||||
}
|
||||
void ql_codec_choose(codec_choose_state codec_choose, quec_codecpcm_config* pcm_config)
|
||||
{
|
||||
quec_codec_choose(codec_choose, pcm_config);
|
||||
}
|
||||
|
||||
void ql_set_audio_path_earphone(void)
|
||||
{
|
||||
quec_set_audio_path_to_headset();
|
||||
}
|
||||
|
||||
void ql_set_audio_path_receiver(void)
|
||||
{
|
||||
quec_set_audio_path_to_handset();
|
||||
}
|
||||
|
||||
void ql_set_audio_path_speaker(void)
|
||||
{
|
||||
quec_set_audio_path_to_speaker();
|
||||
}
|
||||
|
||||
void ql_set_volume(QL_AUDIOHAL_SPK_LEVEL vol)
|
||||
{
|
||||
quec_set_volume((char)vol);
|
||||
}
|
||||
int ql_get_volume(void)
|
||||
{
|
||||
return quec_get_volume();
|
||||
}
|
||||
|
||||
void ql_bind_speakerpa_cb(cb_on_speakerpa cb)
|
||||
{
|
||||
quec_bind_speakerpa_cb(cb);
|
||||
}
|
||||
|
||||
int ql_set_dtmf_detect(DTMFDetectionHandler_t cb, int onoff)
|
||||
{
|
||||
return quec_set_dtmf_detect(cb,onoff);
|
||||
}
|
||||
int ql_aud_dtmf_play(QL_AUDIOHAL_TONE_TYPE dtmf, int onoff)
|
||||
{
|
||||
return quec_aud_dtmf_play((QUEC_AUDIOHAL_TONE_TYPE)dtmf, onoff);
|
||||
}
|
||||
void ql_set_txdspgain(signed char gain)
|
||||
{
|
||||
quec_set_txdspgain(gain);
|
||||
}
|
||||
|
||||
signed char ql_get_txdspgain(void)
|
||||
{
|
||||
return quec_get_txdspgain();
|
||||
}
|
||||
|
||||
void ql_set_txcodecgain(short gain)
|
||||
{
|
||||
quec_set_txcodecgain(gain);
|
||||
}
|
||||
short ql_get_txcodecgain(void)
|
||||
{
|
||||
return quec_get_txcodecgain();
|
||||
}
|
||||
void ql_set_dtmf_volume(int vo)
|
||||
{
|
||||
quec_set_dtmf_volume(vo);
|
||||
}
|
||||
|
||||
int ql_set_dsp_gain_table(unsigned int profile_id, signed short *gain)
|
||||
{
|
||||
return quec_set_dsp_gain_out(profile_id, gain);
|
||||
}
|
||||
int ql_set_txcodec_gain_table(unsigned int profile_id, unsigned int PGA_Stage1, unsigned int PGA_Stage2, unsigned int diggain)
|
||||
{
|
||||
return quec_set_txcodec_gain_table(profile_id, PGA_Stage1, PGA_Stage2, diggain);
|
||||
}
|
||||
|
||||
int ql_set_rxcodec_gain_table(unsigned int profile_id, signed int level, unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4, unsigned int data5)
|
||||
{
|
||||
return quec_set_codec_gain_table(profile_id, level, data1, data2, data3, data4, data5);
|
||||
}
|
||||
|
||||
int ql_set_eqcoeff_table(unsigned int profile_id, signed int tx_rx, unsigned int rate, signed short * data)
|
||||
{
|
||||
return quec_set_eqcoeff_table(profile_id,tx_rx,rate,data);
|
||||
}
|
||||
|
||||
int ql_set_mediave_coeff_table(ACMCP_MediaVEarametersT *AudioMediaVETable)
|
||||
{
|
||||
return quec_set_mediave_coeff_table( AudioMediaVETable);
|
||||
}
|
||||
|
||||
int ql_aud_tone_play(int f1, int f2, int onoff)
|
||||
{
|
||||
return quec_aud_tone_play(f1, f2, onoff);
|
||||
}
|
||||
|
||||
audio_track_handle ql_audio_track_open(unsigned int rate, unsigned int channels, int64_t option, audio_track_callback event_cb)
|
||||
{
|
||||
return quec_audio_track_open(rate,channels,option,event_cb);
|
||||
}
|
||||
int ql_audio_track_write(audio_track_handle handle, uint8_t* data, unsigned int size)
|
||||
{
|
||||
return quec_audio_track_write(handle, data, size);
|
||||
}
|
||||
int ql_audio_track_close(audio_track_handle handle,int force)
|
||||
{
|
||||
return quec_audio_track_close(handle,force);
|
||||
}
|
||||
int ql_audio_track_ctrl(audio_track_handle handle, acm_audio_track_control_t ctrl_type, int ctrl_value)
|
||||
{
|
||||
return quec_audio_track_ctrl(handle,ctrl_type,ctrl_value);
|
||||
}
|
||||
audio_record_handle ql_audio_record_open(unsigned int rate, unsigned int channels, int64_t option, audio_record_callback event_cb)
|
||||
{
|
||||
return quec_audio_record_open(rate, channels, option,event_cb);
|
||||
}
|
||||
|
||||
int ql_audio_record_read(audio_record_handle handle, uint8_t*data, unsigned int*count)
|
||||
{
|
||||
return quec_audio_record_read(handle,data,count);
|
||||
}
|
||||
|
||||
int ql_audio_record_close(audio_record_handle handle,int force)
|
||||
{
|
||||
return quec_audio_record_close(handle,force);
|
||||
}
|
||||
|
||||
int ql_audio_record_ctrl(audio_record_handle handle, acm_audio_record_control_t ctrl_type, int ctrl_value)
|
||||
{
|
||||
return quec_audio_record_ctrl(handle,ctrl_type,ctrl_value);
|
||||
}
|
||||
|
||||
int ql_wav_play(const char* file_name, struct audio_track_config* track_config, audio_track_handle* handle)
|
||||
{
|
||||
return quec_wav_play( file_name, track_config, handle);
|
||||
}
|
||||
|
||||
int ql_wav_play_stop(audio_track_handle handle,char force)
|
||||
{
|
||||
return quec_wav_play_stop(handle, force);
|
||||
}
|
||||
#ifdef QL_MP3_FUNC
|
||||
int ql_play_mp3(char *file_name,Mp3PlaybackHandle* handle,Mp3PlayConfigInfo* mp3_configInfo)
|
||||
{
|
||||
return quec_mp3_play(file_name,handle,mp3_configInfo);
|
||||
}
|
||||
int ql_play_mp3_stream_buffer(Mp3PlaybackHandle handle,unsigned char *mp3_buff, int mp3_size)
|
||||
{
|
||||
return quec_mp3_stream_play_buffer(handle,mp3_buff,mp3_size);
|
||||
}
|
||||
int ql_stop_mp3_play(Mp3PlaybackHandle handle,int drain)
|
||||
{
|
||||
return quec_mp3_play_stop(handle,drain);
|
||||
}
|
||||
int ql_mp3_get_pcm_handle(Mp3PlaybackHandle handle, unsigned int* pcm_handle)
|
||||
{
|
||||
return quec_mp3_get_pcm_handle(handle,pcm_handle);
|
||||
}
|
||||
#endif
|
||||
#ifdef QL_AMR_FUNC
|
||||
int ql_play_amr(char *file_name,AmrPlaybackHandle* handle,AmrPlaybackConfigInfo* amr_configInfo)
|
||||
{
|
||||
return quec_amr_play(file_name,handle,amr_configInfo);
|
||||
}
|
||||
int ql_play_amr_stream_buffer(AmrPlaybackHandle handle,unsigned char *amr_buff, int amr_size)
|
||||
{
|
||||
return quec_amr_stream_play_buffer(handle,amr_buff,amr_size);
|
||||
}
|
||||
int ql_stop_amr_play(AmrPlaybackHandle handle,int drain)
|
||||
{
|
||||
return quec_amr_play_stop(handle,drain);
|
||||
}
|
||||
int ql_amr_get_pcm_handle(AmrPlaybackHandle handle, unsigned int* track_handle)
|
||||
{
|
||||
return quec_amr_get_pcm_handle(handle,track_handle);
|
||||
}
|
||||
|
||||
int ql_record_amr(char *file_name,AmrEncodeHandle* handle,AmrEncConfigInfo* amr_configInfo)
|
||||
{
|
||||
return quec_amr_record(file_name, handle, amr_configInfo);
|
||||
}
|
||||
int ql_record_amr_stop(AmrEncodeHandle handle)
|
||||
{
|
||||
return quec_amr_record_stop(handle);
|
||||
}
|
||||
#endif
|
||||
void ql_set_dtmf_volume2(int vo)
|
||||
{
|
||||
ACMAudioSetDTMFVolume(vo);
|
||||
}
|
||||
|
||||
void ql_audio_pipeline_config(unsigned int rate, unsigned int channel)
|
||||
{
|
||||
quec_audio_pipeline_config(rate, channel);
|
||||
}
|
||||
|
||||
int ql_audio_track_pipeline_read(unsigned char * buf, unsigned int * size)
|
||||
{
|
||||
return quec_audio_track_pipeline_read(buf, size);
|
||||
}
|
||||
|
||||
void ql_set_audio_ouput_type(char mode)
|
||||
{
|
||||
quec_set_audio_ouput_type(mode);
|
||||
}
|
||||
char ql_get_audio_ouput_type(void)
|
||||
{
|
||||
return quec_get_audio_ouput_type();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,957 @@
|
||||
|
||||
/*兼容旧同步接口*/
|
||||
/*这些接口灵活性很低不建议客户使用*/
|
||||
/*在kernel使用接口请自行移植到kernel*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef NO_AUDIO
|
||||
#include "ql_audio.h"
|
||||
#include "ql_audio_old_api.h"
|
||||
#include "ql_rtos.h"
|
||||
#include "ql_fs.h"
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define SEEK_SET 0
|
||||
#define ID_RIFF 0x46464952
|
||||
#define ID_WAVE 0x45564157
|
||||
#define ID_FMT 0x20746d66
|
||||
#define ID_DATA 0x61746164
|
||||
#define ID_IOS 0x524c4c46//wav data id by IOS
|
||||
#define QUEC_PCM_BLOCK_FLAG (0x01)
|
||||
#define QUEC_PCM_NONBLOCK_FLAG (0x02)
|
||||
#define QUEC_PCM_READ_FLAG (0x04)
|
||||
#define QUEC_PCM_WRITE_FLAG (0x08)
|
||||
#define AUDIO_PLAY 1
|
||||
#define AUDIO_RECORD 2
|
||||
|
||||
#ifndef QL_MP3_FUNC
|
||||
int ql_play_mp3(char *file_name,Mp3PlaybackHandle* handle,Mp3PlayConfigInfo* mp3_configInfo)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ql_play_mp3_stream_buffer(Mp3PlaybackHandle handle,unsigned char *mp3_buff, int mp3_size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ql_stop_mp3_play(Mp3PlaybackHandle handle,int drain)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ql_mp3_get_pcm_handle(Mp3PlaybackHandle handle, unsigned int* pcm_handle)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#ifndef QL_AMR_FUNC
|
||||
int ql_play_amr(char *file_name,AmrPlaybackHandle* handle,AmrPlaybackConfigInfo* amr_configInfo)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ql_play_amr_stream_buffer(AmrPlaybackHandle handle,unsigned char *amr_buff, int amr_size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ql_stop_amr_play(AmrPlaybackHandle handle,int drain)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ql_amr_get_pcm_handle(AmrPlaybackHandle handle, unsigned int* track_handle)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ql_record_amr(char *file_name,AmrEncodeHandle* handle,AmrEncConfigInfo* amr_configInfo)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ql_record_amr_stop(AmrEncodeHandle handle)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
long long QUEC_2_ASR_AUDIO_TRACK_OPTION(unsigned int flags)
|
||||
{
|
||||
AUDIO_PLAY_OPTION option ;
|
||||
long long option1;
|
||||
memset(&option,0,sizeof(long long));
|
||||
if(QUEC_PCM_BLOCK_FLAG&flags)
|
||||
{
|
||||
option.write_mode = 1;
|
||||
}
|
||||
else if(QUEC_PCM_NONBLOCK_FLAG&flags)
|
||||
{
|
||||
option.write_mode = 0;
|
||||
}
|
||||
option.active_point = 1;
|
||||
memcpy(&option1,&option,sizeof(long long));
|
||||
return option1;
|
||||
}
|
||||
static char is_support_samplerate(unsigned int rate)
|
||||
{
|
||||
switch(rate) {
|
||||
case 8000:
|
||||
case 16000:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int check_wav_file(QFILE *fd, aud_input_para_t *para)
|
||||
{
|
||||
int ret = 0,i = 0;
|
||||
struct riff_chunk riff_hdr;
|
||||
struct format_chunk format_hdr;
|
||||
struct data_chunk data_hdr;
|
||||
unsigned int chunk_id = 0,chunk_size = 0,chunk_len = 0;
|
||||
unsigned int data = 0,data_size = 0;
|
||||
|
||||
if(!para)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ql_fseek(fd, 0, SEEK_SET);
|
||||
if(ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
ret = ql_fread(&riff_hdr, sizeof(riff_hdr),1,fd); //riff
|
||||
if(ret < sizeof(riff_hdr))
|
||||
{
|
||||
ql_fseek(fd, 0, SEEK_SET);
|
||||
return -1;
|
||||
}
|
||||
if( (riff_hdr.riff != ID_RIFF) || (riff_hdr.wave!= ID_WAVE))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0;i < riff_hdr.file_size;){ //format
|
||||
ql_fread(&chunk_id, sizeof(chunk_id),1,fd);
|
||||
if(chunk_id == ID_FMT){
|
||||
ql_fread(&format_hdr.format_size, sizeof(unsigned int),1,fd);
|
||||
format_hdr.format = chunk_id;
|
||||
break;
|
||||
}else{
|
||||
ql_fread(&chunk_size, sizeof(chunk_size),1,fd);
|
||||
i += (chunk_size + 8);
|
||||
if(i > riff_hdr.file_size)
|
||||
return -1;
|
||||
ret = ql_fseek(fd, chunk_size, 1);
|
||||
if(ret < chunk_size)
|
||||
return -1;
|
||||
chunk_len = i;
|
||||
}
|
||||
|
||||
}
|
||||
ql_fread(&format_hdr.aud_fmt, format_hdr.format_size,1,fd);
|
||||
if(is_support_samplerate(format_hdr.sample) == false){
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
for(i = 0;i < (riff_hdr.file_size-chunk_len-format_hdr.format_size);){ //data
|
||||
ql_fread(&data, sizeof(data),1,fd);
|
||||
if(data == ID_DATA){
|
||||
ql_fread(&data_hdr.data_size, sizeof(unsigned int),1,fd);
|
||||
data_hdr.data = data;
|
||||
break;
|
||||
}else{
|
||||
ql_fread(&data_size, sizeof(data_size),1,fd);
|
||||
i += (data_size + 8);
|
||||
if(i > riff_hdr.file_size-chunk_len-format_hdr.format_size)
|
||||
return -1;
|
||||
ret = ql_fseek(fd, data_size, 1);
|
||||
if(ret < data_size)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
switch (format_hdr.bits_sample)
|
||||
{
|
||||
case 8:
|
||||
para->format = QUEC_PCM_FORMAT_S8;
|
||||
break;
|
||||
case 16:
|
||||
para->format = QUEC_PCM_FORMAT_S16_LE;
|
||||
break;
|
||||
case 24:
|
||||
para->format = QUEC_PCM_FORMAT_S24_LE;
|
||||
break;
|
||||
case 32:
|
||||
para->format = QUEC_PCM_FORMAT_S32_LE;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
para->rate = format_hdr.sample;
|
||||
para->channels = format_hdr.channel;
|
||||
para->hsize = 4;
|
||||
para->type = AUD_STREAM_FORMAT_PCM;
|
||||
para->file_size = data_hdr.data_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_mp3_file(QFILE *fd)
|
||||
{
|
||||
int ret = 0;
|
||||
char head[10] = {0};
|
||||
|
||||
ret = ql_fseek(fd, 0, SEEK_SET);
|
||||
if(ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ql_fread(head, sizeof(head),1,fd);
|
||||
if(ret < sizeof(head))
|
||||
{
|
||||
ql_fseek(fd, 0, SEEK_SET);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(memcmp(head, "ID3", 3) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if( (head[0] == 0xFF) && (head[1] & 0xF0) == 0xF0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int check_amr_file(QFILE *fd, aud_input_para_t *para)
|
||||
{
|
||||
int bytesRead = 0;
|
||||
int ret = 0;
|
||||
char header[6] = {0};
|
||||
ret = ql_fseek(fd, 0, SEEK_SET);
|
||||
if(ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// Validate the input AMR file
|
||||
bytesRead = ql_fread(header, 6,1,fd);
|
||||
if (bytesRead != 6 || memcmp(header, "#!AMR\n", 6)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int check_audio_format(QFILE *fd, aud_input_para_t *para)
|
||||
{
|
||||
|
||||
if(!check_wav_file(fd, para))
|
||||
{
|
||||
return AUD_STREAM_FORMAT_PCM;
|
||||
}
|
||||
else if(!check_mp3_file(fd))
|
||||
{
|
||||
return AUD_STREAM_FORMAT_MP3;
|
||||
}
|
||||
else if(!check_amr_file(fd, para))
|
||||
{
|
||||
return AUD_STREAM_FORMAT_AMR;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Name: ql_audio_file_play
|
||||
*
|
||||
* Description: 播放音频文件 ,文件类型可以是mp3,pcm ,wav 异步接口
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
***********************************************************************/
|
||||
static cb_on_player aud_play_cb = NULL;
|
||||
|
||||
static Mp3PlaybackHandle mp3_handle;
|
||||
static Mp3PlayConfigInfo mp3_configInfo;
|
||||
static unsigned char is_mp3_playing = 0;
|
||||
static audio_track_handle wav_handle;
|
||||
static AmrPlaybackHandle amr_handle;
|
||||
static AmrPlaybackConfigInfo amr_config;
|
||||
static struct audio_track_config wav_config;
|
||||
static unsigned char is_wav_file_playing;
|
||||
static unsigned char is_amr_file_playing;
|
||||
|
||||
static AmrPlaybackHandle amr_stream_handle;
|
||||
static AmrPlaybackConfigInfo amr_stream_config;
|
||||
static unsigned char is_amr_stream_playing = 0;
|
||||
|
||||
int ql_audio_play_init(cb_on_player aud_cb)
|
||||
{
|
||||
aud_play_cb = aud_cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wav_play_callback(acm_audio_track_handle handle, acm_audio_track_event_t event)
|
||||
{
|
||||
if(handle == wav_handle)
|
||||
{
|
||||
if(event == AUDIO_TRACK_EVENT_STARTED)
|
||||
{
|
||||
is_wav_file_playing = 1;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_START);
|
||||
}
|
||||
}
|
||||
if(event == AUDIO_TRACK_EVENT_UNDERRUN)
|
||||
{
|
||||
is_wav_file_playing = 0;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_FINISHED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
static void ql_Mp3PlaybackEvent(Mp3PlayEventType event, int val)
|
||||
{
|
||||
if(event == MP3_PLAYBACK_EVENT_STATUS){
|
||||
if(val == MP3_PLAYBACK_STATUS_STARTED)
|
||||
{
|
||||
is_mp3_playing = 1;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_START);
|
||||
}
|
||||
}
|
||||
if(val == MP3_PLAYBACK_STATUS_ENDED)
|
||||
{
|
||||
is_mp3_playing = 0;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_FINISHED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ql_amr_palyback_event(AmrPlaybackEventType event, int val)
|
||||
{
|
||||
if(event == AMR_PLAYBACK_EVENT_STATUS){
|
||||
if(val == AMR_PLAYBACK_STATUS_STARTED)
|
||||
{
|
||||
is_amr_file_playing = 1;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_START);
|
||||
}
|
||||
}
|
||||
if(val == AMR_PLAYBACK_STATUS_ENDED)
|
||||
{
|
||||
is_amr_stream_playing = 0;
|
||||
is_amr_file_playing = 0;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_FINISHED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int ql_audio_file_play(char *file_name)
|
||||
{
|
||||
int rc = 0,ret=0;
|
||||
QFILE * fd = NULL;
|
||||
aud_input_para_t para;
|
||||
rc = ql_access(file_name,0);
|
||||
if(rc == 0)
|
||||
{
|
||||
fd = ql_fopen(file_name, "rb");
|
||||
if(fd == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
ret = check_audio_format(fd, ¶);
|
||||
ql_fclose(fd);
|
||||
if(AUD_STREAM_FORMAT_MP3 == ret)
|
||||
{
|
||||
if(is_mp3_playing == 1) {
|
||||
return -2;
|
||||
}
|
||||
mp3_configInfo.listener = ql_Mp3PlaybackEvent;
|
||||
ql_play_mp3(file_name,&mp3_handle,&mp3_configInfo);
|
||||
}
|
||||
else if(AUD_STREAM_FORMAT_PCM == ret)
|
||||
{
|
||||
if(is_wav_file_playing == 1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
wav_config.event_cb = wav_play_callback;
|
||||
ql_wav_play(file_name,&wav_config,&wav_handle);
|
||||
}
|
||||
else if(AUD_STREAM_FORMAT_AMR == ret)
|
||||
{
|
||||
if(is_amr_file_playing == 1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
amr_config.listener = ql_amr_palyback_event;
|
||||
ret = ql_play_amr(file_name,&amr_handle,&amr_config);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ql_audio_file_stop(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/***********************************************************************
|
||||
*
|
||||
* Name: ql_play_file_start
|
||||
*
|
||||
* Description: 播放音频文件 ,文件类型可以是mp3,pcm ,wav ,,同步接口
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
***********************************************************************/
|
||||
static Mp3PlaybackHandle mp3_handle_sync;
|
||||
static Mp3PlayConfigInfo mp3_configInfo_sync;
|
||||
static unsigned char mp3_sync_playing = 0;
|
||||
|
||||
static audio_track_handle wav_handle_sync;
|
||||
static struct audio_track_config wav_config_sync;
|
||||
static unsigned char wav_sync_playing = 0;
|
||||
|
||||
static AmrPlaybackHandle amr_handle_sync;
|
||||
static AmrPlaybackConfigInfo amr_config_sync;
|
||||
static unsigned char amr_sync_playing = 0;
|
||||
|
||||
static void wav_sync_play_callback(acm_audio_track_handle handle, acm_audio_track_event_t event)
|
||||
{
|
||||
if(handle == wav_handle)
|
||||
{
|
||||
if(event == AUDIO_TRACK_EVENT_STARTED)
|
||||
{
|
||||
wav_sync_playing = 1;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_START);
|
||||
}
|
||||
}
|
||||
if(event == AUDIO_TRACK_EVENT_UNDERRUN)
|
||||
{
|
||||
wav_sync_playing = 0;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_FINISHED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
static void mp3_sync_play_callback(Mp3PlayEventType event, int val)
|
||||
{
|
||||
if(event == MP3_PLAYBACK_EVENT_STATUS){
|
||||
if(val == MP3_PLAYBACK_STATUS_STARTED)
|
||||
{
|
||||
mp3_sync_playing = 1;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_START);
|
||||
}
|
||||
}
|
||||
if(val == MP3_PLAYBACK_STATUS_ENDED)
|
||||
{
|
||||
mp3_sync_playing = 0;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_FINISHED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void amr_sync_play_callback(AmrPlaybackEventType event, int val)
|
||||
{
|
||||
if(event == AMR_PLAYBACK_EVENT_STATUS){
|
||||
if(val == AMR_PLAYBACK_STATUS_STARTED)
|
||||
{
|
||||
amr_sync_playing = 1;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_START);
|
||||
}
|
||||
}
|
||||
if(val == AMR_PLAYBACK_STATUS_ENDED)
|
||||
{
|
||||
amr_sync_playing = 0;
|
||||
if(aud_play_cb)
|
||||
{
|
||||
aud_play_cb(NULL, 0, AUD_PLAYER_FINISHED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ql_play_file_start(char *file_name)
|
||||
{
|
||||
int rc = 0,ret=0;
|
||||
QFILE * fd = NULL;
|
||||
aud_input_para_t para;
|
||||
rc = ql_access(file_name,0);
|
||||
if(rc == 0)
|
||||
{
|
||||
fd = ql_fopen(file_name, "rb");
|
||||
if(fd == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
ret = check_audio_format(fd, ¶);
|
||||
ql_fclose(fd);
|
||||
if(AUD_STREAM_FORMAT_MP3 == ret)
|
||||
{
|
||||
if(mp3_sync_playing == 1) {
|
||||
return -2;
|
||||
}
|
||||
mp3_configInfo_sync.listener = mp3_sync_play_callback;
|
||||
ret = ql_play_mp3(file_name,&mp3_handle_sync,&mp3_configInfo_sync);
|
||||
do
|
||||
{
|
||||
ql_rtos_task_sleep_ms(50);
|
||||
} while (mp3_sync_playing);
|
||||
}
|
||||
else if(AUD_STREAM_FORMAT_PCM == ret)
|
||||
{
|
||||
if(wav_sync_playing == 1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
wav_config_sync.event_cb = wav_sync_play_callback;
|
||||
ret = ql_wav_play(file_name,&wav_config_sync,&wav_handle_sync);
|
||||
do
|
||||
{
|
||||
ql_rtos_task_sleep_ms(50);
|
||||
} while (wav_sync_playing);
|
||||
}
|
||||
else if(AUD_STREAM_FORMAT_AMR == ret)
|
||||
{
|
||||
if(amr_sync_playing == 1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
amr_config_sync.listener = amr_sync_play_callback;
|
||||
ret = ql_play_amr(file_name,&amr_handle_sync,&amr_config_sync);
|
||||
do
|
||||
{
|
||||
ql_rtos_task_sleep_ms(50);
|
||||
} while (amr_sync_playing);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ql_play_file_stop(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ql_wav_file_play(char *file_name)
|
||||
{
|
||||
if(!file_name){
|
||||
return -1;
|
||||
}
|
||||
if(is_wav_file_playing == 1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
wav_config.event_cb = wav_play_callback;
|
||||
wav_config.prepare_threshold = 64;
|
||||
return ql_wav_play(file_name,&wav_config,&wav_handle);
|
||||
}
|
||||
|
||||
void ql_wav_file_stop(void)
|
||||
{
|
||||
ql_wav_play_stop(wav_handle,1);
|
||||
}
|
||||
|
||||
int ql_mp3_file_play(char *file_name)
|
||||
{
|
||||
if(!file_name){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(is_mp3_playing == 1) {
|
||||
return -2;
|
||||
}
|
||||
mp3_configInfo.listener = ql_Mp3PlaybackEvent;
|
||||
return ql_play_mp3(file_name,&mp3_handle,&mp3_configInfo);
|
||||
}
|
||||
|
||||
void ql_mp3_file_stop(void)
|
||||
{
|
||||
ql_stop_mp3_play(mp3_handle,0);
|
||||
}
|
||||
|
||||
|
||||
static int ql_amr_file_play_type = 0;
|
||||
int ql_amr_file_play(char *file_name)
|
||||
{
|
||||
if(!file_name){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(is_amr_file_playing == 1) {
|
||||
return -2;
|
||||
}
|
||||
ql_amr_file_play_type = 0;
|
||||
amr_config.listener = ql_amr_palyback_event;
|
||||
return ql_play_amr(file_name,&amr_handle,&amr_config);
|
||||
}
|
||||
|
||||
int ql_amr_file_play2(const char *data, unsigned int size)
|
||||
{
|
||||
int ret = -1;
|
||||
if(is_amr_stream_playing == 0)
|
||||
{
|
||||
amr_config.listener = ql_amr_palyback_event;
|
||||
ql_play_amr(NULL,&amr_stream_handle,&amr_stream_config);
|
||||
is_amr_stream_playing = 1;
|
||||
ql_amr_file_play_type = 1;
|
||||
ret = ql_play_amr_stream_buffer(amr_stream_handle,(unsigned char *)data, size);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = ql_stop_amr_play(amr_stream_handle,1);//播缓存,等待结束事件
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ql_amr_file_stop(void)
|
||||
{
|
||||
if (ql_amr_file_play_type == 0)//文件播放调用播文件句柄
|
||||
{
|
||||
ql_stop_amr_play(amr_handle,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ql_amr_file_play_type = 0;
|
||||
if (is_amr_stream_playing)
|
||||
{
|
||||
is_amr_stream_playing = 0;
|
||||
ql_stop_amr_play(amr_stream_handle,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static AmrEncodeHandle record_amr_handle;
|
||||
static AmrEncConfigInfo record_amr_config;
|
||||
int ql_record_amr_file_start(char *file_name)
|
||||
{
|
||||
if(!file_name){
|
||||
return -1;
|
||||
}
|
||||
return ql_record_amr(file_name, &record_amr_handle , &record_amr_config);
|
||||
}
|
||||
|
||||
void ql_record_amr_file_stop(void)
|
||||
{
|
||||
ql_record_amr_stop(record_amr_handle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Name:
|
||||
*
|
||||
* Description: 播放音频文件 ,文件类型可以是mp3,pcm ,wav
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
***********************************************************************/
|
||||
/*尾插单链表*/
|
||||
typedef struct Node {
|
||||
unsigned int data;
|
||||
struct Node* next;
|
||||
} Node;
|
||||
// 初始化一个空链表
|
||||
Node* initializeList() {
|
||||
return NULL;
|
||||
}
|
||||
// 在链表末尾插入一个新节点
|
||||
Node* insertNode(Node* head, unsigned int data) {
|
||||
Node* newNode = (Node*)malloc(sizeof(Node));
|
||||
newNode->data = data;
|
||||
newNode->next = NULL;
|
||||
|
||||
if (head == NULL) {
|
||||
return newNode;
|
||||
}
|
||||
|
||||
Node* current = head;
|
||||
while (current->next != NULL) {
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
current->next = newNode;
|
||||
return head;
|
||||
}
|
||||
|
||||
// 删除链表中第一个匹配给定数据的节点
|
||||
Node* deleteNode(Node* head, unsigned int data) {
|
||||
if (head == NULL) {
|
||||
return NULL; // 空链表,无需删除
|
||||
}
|
||||
|
||||
if (head->data == data) {
|
||||
Node* temp = head;
|
||||
head = head->next;
|
||||
free(temp);
|
||||
return head;
|
||||
}
|
||||
|
||||
Node* current = head;
|
||||
while (current->next != NULL && current->next->data != data) {
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
if (current->next != NULL) {
|
||||
Node* temp = current->next;
|
||||
current->next = current->next->next;
|
||||
free(temp);
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
PCM_HANDLE_T findList(Node* head , unsigned int handle) {
|
||||
Node* current = head;
|
||||
PCM_HANDLE_T quec_audio_handle = NULL;
|
||||
while (current != NULL) {
|
||||
quec_audio_handle = (PCM_HANDLE_T)current->data;
|
||||
if(quec_audio_handle->handle == handle)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
quec_audio_handle = NULL;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
return quec_audio_handle;
|
||||
}
|
||||
|
||||
// 释放链表内存
|
||||
void freeList(Node* head) {
|
||||
Node* current = head;
|
||||
Node* next;
|
||||
while (current != NULL) {
|
||||
next = current->next;
|
||||
free(current);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
Node* pcm_hadle_list;
|
||||
#define PCM_END_FLAG 0x1
|
||||
char record_work_mode=0;
|
||||
char list_created = 0;
|
||||
void OLD_pcm_play_callback(acm_audio_track_handle handle, acm_audio_track_event_t event)
|
||||
{
|
||||
PCM_HANDLE_T quec_audio_handle = findList(pcm_hadle_list , (unsigned int)handle);
|
||||
if(quec_audio_handle){
|
||||
if(event == AUDIO_TRACK_EVENT_CLOSED)
|
||||
ql_rtos_flag_release(quec_audio_handle->pcm_stream_flag,PCM_END_FLAG, QL_FLAG_OR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PCM_HANDLE_T ql_pcm_open(QL_PCM_CONFIG_T *config, unsigned int flags)
|
||||
{
|
||||
PCM_HANDLE_T quec_audio_handle = malloc(sizeof(ql_pcm_hadle_t));
|
||||
long long option = 0;
|
||||
if (flags&QUEC_PCM_WRITE_FLAG)
|
||||
{
|
||||
if(list_created)
|
||||
{
|
||||
list_created=1;
|
||||
pcm_hadle_list=initializeList();
|
||||
}
|
||||
pcm_hadle_list = insertNode(pcm_hadle_list, (unsigned int)quec_audio_handle);
|
||||
ql_rtos_flag_create(&(quec_audio_handle->pcm_stream_flag));
|
||||
quec_audio_handle->record_or_play = AUDIO_PLAY;
|
||||
option = QUEC_2_ASR_AUDIO_TRACK_OPTION(flags);
|
||||
quec_audio_handle->handle = ql_audio_track_open(config->samplerate, config->channels,option, OLD_pcm_play_callback);
|
||||
}
|
||||
else if(flags&QUEC_PCM_READ_FLAG)
|
||||
{
|
||||
if(flags&QUEC_PCM_BLOCK_FLAG)
|
||||
record_work_mode = 1;
|
||||
else
|
||||
record_work_mode = 0;
|
||||
quec_audio_handle->record_or_play = AUDIO_RECORD;
|
||||
quec_audio_handle->handle = ql_audio_record_open(config->samplerate, config->channels, option,NULL);
|
||||
}
|
||||
return (PCM_HANDLE_T)quec_audio_handle;
|
||||
}
|
||||
|
||||
int ql_pcm_read(PCM_HANDLE_T handle, void *data, unsigned int count)
|
||||
{
|
||||
ql_pcm_hadle_t *quec_audio_handle = handle;
|
||||
int ret = -1,CNT=0;
|
||||
unsigned int count1=0;
|
||||
if(count == 0 || data == NULL)
|
||||
return ret;
|
||||
count1 = count;
|
||||
if(record_work_mode == 1)/*由于asr的录音不带阻塞模式,故在此增加阻塞*/
|
||||
{
|
||||
while(ret&&CNT<10){
|
||||
count1 = count;
|
||||
ret = ql_audio_record_read(quec_audio_handle->handle, data, &count1);
|
||||
ql_rtos_task_sleep_ms(5);
|
||||
CNT++;
|
||||
}
|
||||
if(ret<0)
|
||||
count1 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ql_audio_record_read(quec_audio_handle->handle, data, &count1);
|
||||
if(ret<0)
|
||||
count1 = 0;
|
||||
}
|
||||
|
||||
return count1;
|
||||
}
|
||||
|
||||
int ql_pcm_write(PCM_HANDLE_T handle, void *data, unsigned int count)
|
||||
{
|
||||
int ret = 0;
|
||||
int temp_cnt = 0;
|
||||
|
||||
temp_cnt = count;
|
||||
ql_pcm_hadle_t *quec_audio_handle = handle;
|
||||
ret = ql_audio_track_write(quec_audio_handle->handle, data, count);
|
||||
if (ret == 0)
|
||||
{
|
||||
return temp_cnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ql_pcm_close(PCM_HANDLE_T handle)
|
||||
{
|
||||
ql_pcm_hadle_t *quec_audio_handle = handle;
|
||||
int ret = 0;
|
||||
u32 flags = 0;
|
||||
if(quec_audio_handle->record_or_play==AUDIO_PLAY)
|
||||
{
|
||||
ret = ql_audio_track_close(quec_audio_handle->handle,1);
|
||||
ql_rtos_task_sleep_ms(20);
|
||||
// ql_rtos_flag_wait(quec_audio_handle->pcm_stream_flag, PCM_END_FLAG, QL_FLAG_OR_CLEAR, &flags, 0xFFFFFFFF);
|
||||
pcm_hadle_list = deleteNode(pcm_hadle_list, (unsigned int)quec_audio_handle);
|
||||
ql_rtos_flag_delete(quec_audio_handle->pcm_stream_flag);
|
||||
}
|
||||
else if(quec_audio_handle->record_or_play==AUDIO_RECORD)
|
||||
{
|
||||
ret = ql_audio_record_close(quec_audio_handle->handle,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
free(quec_audio_handle);
|
||||
return ret;
|
||||
}
|
||||
cb_on_player ql_pcm_play_cb;
|
||||
audio_track_handle track_handle = 0;
|
||||
|
||||
static void pcm_play_callback(acm_audio_track_handle handle, acm_audio_track_event_t event)
|
||||
{
|
||||
enum_aud_player_state ql_aug_event = AUD_PLAYER_ERROR;
|
||||
if(handle == track_handle)
|
||||
{
|
||||
if(event == AUDIO_TRACK_EVENT_STARTED)
|
||||
{
|
||||
if(ql_pcm_play_cb)
|
||||
ql_pcm_play_cb(NULL,0,AUD_PLAYER_START);
|
||||
}
|
||||
if(event == AUDIO_TRACK_EVENT_UNDERRUN)
|
||||
{
|
||||
if(ql_pcm_play_cb)
|
||||
ql_pcm_play_cb(NULL,0,AUD_PLAYER_NODATA);
|
||||
}
|
||||
if(event == AUDIO_TRACK_EVENT_NEARLY_OVERRUN)
|
||||
{
|
||||
if(ql_pcm_play_cb)
|
||||
ql_pcm_play_cb(NULL,0,AUD_PLAYER_MOREDATA);
|
||||
}
|
||||
if(event == AUDIO_TRACK_EVENT_NEARLY_UNDERRUN)
|
||||
{
|
||||
if(ql_pcm_play_cb)
|
||||
ql_pcm_play_cb(NULL,0,AUD_PLAYER_LESSDATA);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ql_pcm_play_init(cb_on_player play_cb)
|
||||
{
|
||||
ql_pcm_play_cb=play_cb;
|
||||
return 0;
|
||||
}
|
||||
int ql_pcm_play(int hdl, unsigned char *buffer, int wav_size)
|
||||
{
|
||||
track_handle = ql_audio_track_open(8000, 1,0, pcm_play_callback);
|
||||
return ql_audio_track_write(track_handle, buffer, wav_size);
|
||||
}
|
||||
|
||||
int ql_pcm_play_stop(int hdl)
|
||||
{
|
||||
return ql_audio_track_close(track_handle,0);
|
||||
}
|
||||
|
||||
int ql_pcm_play_deinit(int hdl)
|
||||
{
|
||||
ql_pcm_play_cb=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user