pure sdk for main
This commit is contained in:
@@ -0,0 +1,720 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/sleep.h"
|
||||
#include "osal/timer.h"
|
||||
#include "osal/work.h"
|
||||
|
||||
|
||||
#include "custom_mem/custom_mem.h"
|
||||
#include "stream_frame.h"
|
||||
|
||||
#include "interf_dec.h"
|
||||
#include "sp_dec.h"
|
||||
#include "typedef.h"
|
||||
|
||||
#include "amr_app.h"
|
||||
#include "fatfs/osal_file.h"
|
||||
#include "osal/string.h"
|
||||
|
||||
|
||||
static uint32_t get_amrnb_data_len(void *data)
|
||||
{
|
||||
struct data_structure *d = (struct data_structure *)data;
|
||||
return ((uint32_t)d->priv);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t set_amrnb_data_len(void *data,uint32_t len)
|
||||
{
|
||||
struct data_structure *d = (struct data_structure *)data;
|
||||
d->priv = (void*)len;
|
||||
return (uint32_t)len;
|
||||
}
|
||||
|
||||
|
||||
static const stream_ops_func stream_sound_ops =
|
||||
{
|
||||
.get_data_len = get_amrnb_data_len,
|
||||
.set_data_len = set_amrnb_data_len,
|
||||
// .set_data_time = set_sound_data_time,
|
||||
};
|
||||
|
||||
static int opcode_func(stream *s,void *priv,int opcode)
|
||||
{
|
||||
int res = 0;
|
||||
switch(opcode)
|
||||
{
|
||||
case STREAM_OPEN_ENTER:
|
||||
break;
|
||||
case STREAM_OPEN_EXIT:
|
||||
{
|
||||
stream_data_dis_mem_custom(s);
|
||||
streamSrc_bind_streamDest(s,R_SPEAKER);
|
||||
streamSrc_bind_streamDest(s,R_SAVE_STREAM_DATA);
|
||||
s->priv = priv;
|
||||
}
|
||||
break;
|
||||
case STREAM_OPEN_FAIL:
|
||||
break;
|
||||
case STREAM_DATA_DIS:
|
||||
{
|
||||
struct data_structure *data = (struct data_structure *)priv;
|
||||
//int data_num = (int)data->priv;
|
||||
data->type = SET_DATA_TYPE(SOUND,SOUND_AMRNB);//设置声音的类型
|
||||
data->priv = (void*)(AMRNB_TO_PCM_SIZE*2);
|
||||
//注册对应函数
|
||||
data->ops = (stream_ops_func*)&stream_sound_ops;
|
||||
//申请最大的音频size
|
||||
data->data = (void*)custom_malloc_psram((AMRNB_TO_PCM_SIZE*2));
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_DATA_DESTORY:
|
||||
{
|
||||
struct data_structure *data = (struct data_structure *)priv;
|
||||
if(data->data)
|
||||
{
|
||||
custom_free_psram(data->data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//如果释放空间,则删除所有的节点
|
||||
case STREAM_DATA_FREE:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_DATA_FREE_END:
|
||||
break;
|
||||
|
||||
//每次即将发送到一个流,就调用一次
|
||||
case STREAM_SEND_TO_DEST:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
//数据发送完成
|
||||
case STREAM_SEND_DATA_FINISH:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
//退出,则关闭对应得流
|
||||
case STREAM_CLOSE_EXIT:
|
||||
{
|
||||
}
|
||||
break;
|
||||
//这里移除priv(流名称动态申请)
|
||||
case STREAM_DEL:
|
||||
{
|
||||
if(s->priv)
|
||||
{
|
||||
custom_free(s->priv);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
//默认都返回成功
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static struct amr_extern_read *g_amrnb_decode = NULL;
|
||||
//读取当前amr解码的状态,如果播放之前,最好先判断一下
|
||||
uint8_t get_amrnb_decode_status()
|
||||
{
|
||||
//os_printf("g_amrnb_decode:%X\n",g_amrnb_decode);
|
||||
if(g_amrnb_decode)
|
||||
{
|
||||
// os_printf("g_amrnb_decode->inside_status:%d\n",g_amrnb_decode->inside_status);
|
||||
return g_amrnb_decode->inside_status;
|
||||
}
|
||||
return AMR_STOP;
|
||||
}
|
||||
|
||||
//外部调用,可以控制mp3解码状态,但不是立刻生效,应该是等待解码下一帧开始生效
|
||||
uint8_t set_amrnb_decode_status(uint8_t status)
|
||||
{
|
||||
if(g_amrnb_decode)
|
||||
{
|
||||
g_amrnb_decode->status = status;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void amrnb_decode_file_thread(void *d)
|
||||
{
|
||||
stream *s = NULL;
|
||||
uint32_t offset = 0;
|
||||
uint32_t readlen = 0;
|
||||
uint32_t read_size = 0;
|
||||
uint32_t timeout = 0;
|
||||
int frames = 0;
|
||||
int send_success = 0;
|
||||
struct data_structure *data = NULL;
|
||||
uint32_t data_offset = 0;
|
||||
short *buf = NULL;
|
||||
short synth[160];
|
||||
|
||||
unsigned char analysis[32];
|
||||
enum Mode dec_mode;
|
||||
|
||||
char magic[8];
|
||||
const short block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
struct amr_extern_read *amr = (struct amr_extern_read*)d;
|
||||
|
||||
|
||||
char *amr_stream_name = (char*)custom_malloc(64);
|
||||
os_sprintf(amr_stream_name,"%s_%d",S_AMRNB_AUDIO,(uint32_t)(os_jiffies()%1000));
|
||||
s = open_stream_available(amr_stream_name,8,0,opcode_func,amr_stream_name);
|
||||
if(!s)
|
||||
{
|
||||
goto amrnb_decode_file_thread_end;
|
||||
}
|
||||
|
||||
int * destate;
|
||||
|
||||
os_printf("%s:%d start\n",__FUNCTION__,__LINE__);
|
||||
|
||||
|
||||
|
||||
//识别是否为正常的amrnb数据
|
||||
readlen = amr->amr_read( amr,magic, offset,sizeof( char )*strlen( AMRNB_MAGIC_NUMBER ));
|
||||
offset += readlen;
|
||||
if (strncmp( magic, AMRNB_MAGIC_NUMBER, strlen( AMRNB_MAGIC_NUMBER ) ) )
|
||||
{
|
||||
os_printf("%s:%d\tmagic:%s\n",__FUNCTION__,__LINE__,magic);
|
||||
goto amrnb_decode_file_thread_end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
broadcast_cmd_to_destStream(s,SET_CMD_TYPE(CMD_AUDIO_DAC_MODIFY_HZ,8000));
|
||||
destate = Decoder_Interface_init();
|
||||
/* find mode, read file */
|
||||
while(amr->amr_read( amr,analysis, offset,sizeof (unsigned char)) > 0)
|
||||
{
|
||||
//这里判断一下是否暂停或者其他操作
|
||||
if(amr->status == AMR_PAUSE)
|
||||
{
|
||||
printf("%s pause\n",__FUNCTION__);
|
||||
amr->inside_status = amr->status;
|
||||
while(amr->status == AMR_PAUSE)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
amr->inside_status = AMR_PLAY;
|
||||
}
|
||||
//退出
|
||||
if(amr->status == AMR_STOP)
|
||||
{
|
||||
printf("%s stop\n",__FUNCTION__);
|
||||
//mad_read->inside_status = mad_read->status;
|
||||
break;
|
||||
}
|
||||
offset += sizeof (unsigned char);
|
||||
dec_mode = (analysis[0] >> 3) & 0x000F;
|
||||
|
||||
read_size = block_size[dec_mode];
|
||||
|
||||
readlen = amr->amr_read( amr,&analysis[1], offset,read_size);
|
||||
if(readlen <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
offset += readlen;
|
||||
|
||||
|
||||
frames ++;
|
||||
|
||||
/* call decoder */
|
||||
//可以设置正确的buf位置
|
||||
Decoder_Interface_Decode(destate, analysis, synth, 0);
|
||||
|
||||
//这里进行拷贝数据到节点,然后发送,先获取data,然后设置copy buf的空间
|
||||
timeout = 0;
|
||||
while(!data && timeout < 1000)
|
||||
{
|
||||
data = get_src_data_f(s);
|
||||
if(!data)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
timeout++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//数据拷贝偏移清0
|
||||
data_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//timeout超时,可能由异常
|
||||
if(timeout >= 1000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//这里是拷贝数据
|
||||
buf = (short*)get_stream_real_data(data);
|
||||
memcpy(buf+data_offset,synth,160*2);
|
||||
data_offset+=160;
|
||||
|
||||
|
||||
|
||||
//实际这里一定不能大于,如果大于就是越界了,当data_offset == AMRNB_TO_PCM_SIZE,代表这个音频数据
|
||||
//写满,可以发送出去进行播放
|
||||
if(data_offset >= AMRNB_TO_PCM_SIZE)
|
||||
{
|
||||
|
||||
//先hold住,因为可能不会立刻发送成功
|
||||
hold_data(data);
|
||||
|
||||
//尝试发送
|
||||
timeout = 0;
|
||||
|
||||
|
||||
set_stream_real_data_len(data,AMRNB_TO_PCM_SIZE*2);
|
||||
send_success = 0;
|
||||
while(!send_success && timeout < 1000)
|
||||
{
|
||||
send_success = send_data_to_stream(data);
|
||||
if(!send_success)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
timeout++;
|
||||
}
|
||||
|
||||
}
|
||||
//发送成功或者超时,则释放
|
||||
free_data(data);
|
||||
//os_printf("%s2 data:%X\n",__FUNCTION__,data);
|
||||
data = NULL;
|
||||
|
||||
//timeout超时,可能由异常
|
||||
if(timeout >= 1000 || send_success == 0)
|
||||
{
|
||||
os_printf("%s:%d timeout:%d\t send_success:%d err ~~~~~~~~~~~~~~~~~~\n",__FUNCTION__,__LINE__,timeout,send_success);
|
||||
break;
|
||||
}
|
||||
|
||||
data_offset = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//osal_fwrite( synth, sizeof (short), 160, file_speech );
|
||||
}
|
||||
if(data)
|
||||
{
|
||||
|
||||
if(data_offset > 0)
|
||||
{
|
||||
//这里将剩余数据清0
|
||||
buf = (short*)get_stream_real_data(data);
|
||||
memset(buf+data_offset,0,(AMRNB_TO_PCM_SIZE-data_offset)*2);
|
||||
set_stream_real_data_len(data,AMRNB_TO_PCM_SIZE*2);
|
||||
|
||||
send_success = 0;
|
||||
timeout = 0;
|
||||
hold_data(data);
|
||||
while(!send_success && timeout < 1000)
|
||||
{
|
||||
send_success = send_data_to_stream(data);
|
||||
if(!send_success)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
timeout++;
|
||||
}
|
||||
|
||||
}
|
||||
//发送成功或者超时,则释放
|
||||
free_data(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
force_del_data(data);
|
||||
}
|
||||
//os_printf("%s1 data:%X\n",__FUNCTION__,data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
Decoder_Interface_exit(destate);
|
||||
os_printf("frames:%d\n",frames);
|
||||
os_printf("%s:%d end\n",__FUNCTION__,__LINE__);
|
||||
|
||||
|
||||
amrnb_decode_file_thread_end:
|
||||
|
||||
amr->inside_status = AMR_STOP;
|
||||
amr->amr_close(amr,NULL);
|
||||
if(s)
|
||||
{
|
||||
close_stream(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "dec_if.h"
|
||||
void amrwb_decode_file_thread(void *d)
|
||||
{
|
||||
stream *s = NULL;
|
||||
uint32_t offset = 0;
|
||||
uint32_t readlen = 0;
|
||||
uint32_t timeout = 0;
|
||||
int frames = 0;
|
||||
int send_success = 0;
|
||||
struct data_structure *data = NULL;
|
||||
uint32_t data_offset = 0;
|
||||
short *buf = NULL;
|
||||
Word16 synth[L_FRAME16k]; /* Buffer for speech @ 16kHz */
|
||||
UWord8 serial[NB_SERIAL_MAX];
|
||||
|
||||
//unsigned char analysis[32];
|
||||
|
||||
char magic[16] = {0};
|
||||
const UWord8 block_size[16]= {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
|
||||
|
||||
void *st;
|
||||
Word16 mode;
|
||||
|
||||
|
||||
struct amr_extern_read *amr = (struct amr_extern_read*)d;
|
||||
|
||||
|
||||
char *amr_stream_name = (char*)custom_malloc(64);
|
||||
os_sprintf(amr_stream_name,"%s_%d",S_AMRWB_AUDIO,(uint32_t)(os_jiffies()%1000));
|
||||
s = open_stream_available(amr_stream_name,8,0,opcode_func,amr_stream_name);
|
||||
if(!s)
|
||||
{
|
||||
goto amrwb_decode_file_thread_end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
os_printf("%s:%d start\n",__FUNCTION__,__LINE__);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//识别是否为正常的amrnb数据
|
||||
readlen = amr->amr_read( amr,magic, offset,sizeof( char )*strlen( AMRWB_MAGIC_NUMBER ));
|
||||
offset += readlen;
|
||||
os_printf("magic:%s\n",magic);
|
||||
if (strncmp( magic, AMRWB_MAGIC_NUMBER, strlen( AMRWB_MAGIC_NUMBER ) ) )
|
||||
{
|
||||
|
||||
goto amrwb_decode_file_thread_end;
|
||||
}
|
||||
|
||||
//修改一下硬件的采样率
|
||||
broadcast_cmd_to_destStream(s,SET_CMD_TYPE(CMD_AUDIO_DAC_MODIFY_HZ,16000));
|
||||
st = D_IF_init();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* find mode, read file */
|
||||
while(amr->amr_read( amr,serial, offset,sizeof (UWord8)) > 0)
|
||||
{
|
||||
//这里判断一下是否暂停或者其他操作
|
||||
if(amr->status == AMR_PAUSE)
|
||||
{
|
||||
printf("%s pause\n",__FUNCTION__);
|
||||
amr->inside_status = amr->status;
|
||||
while(amr->status == AMR_PAUSE)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
amr->inside_status = AMR_PLAY;
|
||||
}
|
||||
//退出
|
||||
if(amr->status == AMR_STOP)
|
||||
{
|
||||
printf("%s stop\n",__FUNCTION__);
|
||||
//mad_read->inside_status = mad_read->status;
|
||||
break;
|
||||
}
|
||||
offset += sizeof (unsigned char);
|
||||
mode = (Word16)((serial[0] >> 3) & 0x0F);
|
||||
|
||||
|
||||
|
||||
readlen = amr->amr_read( amr,&serial[1], offset,block_size[mode]-1);
|
||||
if(readlen <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
offset += readlen;
|
||||
|
||||
|
||||
frames ++;
|
||||
|
||||
/* call decoder */
|
||||
//可以设置正确的buf位置
|
||||
D_IF_decode( st, serial, synth, _good_frame);
|
||||
|
||||
//这里进行拷贝数据到节点,然后发送,先获取data,然后设置copy buf的空间
|
||||
timeout = 0;
|
||||
while(!data && timeout < 1000)
|
||||
{
|
||||
data = get_src_data_f(s);
|
||||
if(!data)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
timeout++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//数据拷贝偏移清0
|
||||
data_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//timeout超时,可能由异常
|
||||
if(timeout >= 1000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//这里是拷贝数据
|
||||
buf = (short*)get_stream_real_data(data);
|
||||
memcpy(buf+data_offset,synth,L_FRAME16k*2);
|
||||
data_offset+=L_FRAME16k;
|
||||
|
||||
|
||||
|
||||
//实际这里一定不能大于,如果大于就是越界了,当data_offset == AMRWB_TO_PCM_SIZE,代表这个音频数据
|
||||
//写满,可以发送出去进行播放
|
||||
if(data_offset >= AMRWB_TO_PCM_SIZE)
|
||||
{
|
||||
|
||||
//先hold住,因为可能不会立刻发送成功
|
||||
hold_data(data);
|
||||
|
||||
//尝试发送
|
||||
timeout = 0;
|
||||
|
||||
|
||||
set_stream_real_data_len(data,AMRWB_TO_PCM_SIZE*2);
|
||||
send_success = 0;
|
||||
while(!send_success && timeout < 1000)
|
||||
{
|
||||
send_success = send_data_to_stream(data);
|
||||
if(!send_success)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
timeout++;
|
||||
}
|
||||
|
||||
}
|
||||
//发送成功或者超时,则释放
|
||||
free_data(data);
|
||||
//os_printf("%s2 data:%X\n",__FUNCTION__,data);
|
||||
data = NULL;
|
||||
|
||||
//timeout超时,可能由异常
|
||||
if(timeout >= 1000 || send_success == 0)
|
||||
{
|
||||
os_printf("%s:%d timeout:%d\t send_success:%d err ~~~~~~~~~~~~~~~~~~\n",__FUNCTION__,__LINE__,timeout,send_success);
|
||||
break;
|
||||
}
|
||||
|
||||
data_offset = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//osal_fwrite( synth, sizeof (short), 160, file_speech );
|
||||
}
|
||||
if(data)
|
||||
{
|
||||
|
||||
if(data_offset > 0)
|
||||
{
|
||||
|
||||
_os_printf("++++++++++++++++++++++\n");
|
||||
//这里将剩余数据清0
|
||||
buf = (short*)get_stream_real_data(data);
|
||||
memset(buf+data_offset,0,(AMRWB_TO_PCM_SIZE-data_offset)*2);
|
||||
set_stream_real_data_len(data,AMRWB_TO_PCM_SIZE*2);
|
||||
|
||||
send_success = 0;
|
||||
timeout = 0;
|
||||
hold_data(data);
|
||||
while(!send_success && timeout < 1000)
|
||||
{
|
||||
send_success = send_data_to_stream(data);
|
||||
if(!send_success)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
timeout++;
|
||||
}
|
||||
|
||||
}
|
||||
//发送成功或者超时,则释放
|
||||
free_data(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
force_del_data(data);
|
||||
}
|
||||
|
||||
//os_printf("%s1 data:%X\n",__FUNCTION__,data);
|
||||
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
D_IF_exit(st);
|
||||
os_printf("frames:%d\n",frames);
|
||||
os_printf("%s:%d end\n",__FUNCTION__,__LINE__);
|
||||
|
||||
|
||||
amrwb_decode_file_thread_end:
|
||||
|
||||
amr->inside_status = AMR_STOP;
|
||||
amr->amr_close(amr,NULL);
|
||||
if(s)
|
||||
{
|
||||
close_stream(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//需要根据MP3的读取长度配置
|
||||
#define SD_TMP_SIZE (4096)
|
||||
//这里只是读取一次文件,如果长度不对,不
|
||||
uint32_t amr_read_func(struct amr_extern_read *e_read,void *ptr,uint32_t offset,uint32_t size)
|
||||
{
|
||||
void *fp = e_read->fp;
|
||||
uint32_t len;
|
||||
uint32_t read_size = SD_TMP_SIZE;
|
||||
uint32_t read_offset = 0;
|
||||
//os_printf("read size:%d\tptr:%X\n",size,ptr);
|
||||
while(size)
|
||||
{
|
||||
if(size > SD_TMP_SIZE)
|
||||
{
|
||||
len = osal_fread(e_read->sd_buf,1,SD_TMP_SIZE,fp);
|
||||
read_size += SD_TMP_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = osal_fread(e_read->sd_buf,1,size,fp);
|
||||
read_size = size;
|
||||
}
|
||||
memcpy(ptr+read_offset,e_read->sd_buf,read_size);
|
||||
read_offset += read_size;
|
||||
size -= read_size;
|
||||
}
|
||||
|
||||
return read_offset;
|
||||
}
|
||||
|
||||
void amr_close_func(struct amr_extern_read *e_read,void *data)
|
||||
{
|
||||
osal_fclose(e_read->fp);
|
||||
custom_free(e_read->sd_buf);
|
||||
e_read->fp = NULL;
|
||||
custom_free(e_read);
|
||||
}
|
||||
|
||||
void amr_seek_func(struct amr_extern_read *e_read,uint32_t offset)
|
||||
{
|
||||
osal_fseek(e_read->fp,offset);
|
||||
}
|
||||
|
||||
|
||||
char myamr_buf[4098];
|
||||
void *amr_read_init(char *filename)
|
||||
{
|
||||
//已经有使用该mp3解码,需要先等待解码结束才可以继续,可以去读取状态或者控制状态
|
||||
|
||||
struct amr_extern_read *e_read = (struct amr_extern_read*)custom_malloc(sizeof(struct amr_extern_read));
|
||||
memset(e_read,0,sizeof(struct amr_extern_read));
|
||||
e_read->fp = osal_fopen(filename,"rb");
|
||||
os_printf("e_read->fp:%X\n",e_read->fp);
|
||||
e_read->readsize = osal_fsize(e_read->fp);
|
||||
os_printf("e_read->readsize:%d\n",e_read->readsize);
|
||||
e_read->amr_read = amr_read_func;
|
||||
e_read->amr_close = amr_close_func;
|
||||
e_read->amr_seek = amr_seek_func;
|
||||
//注意,这个要用sram的空间
|
||||
e_read->sd_buf = (uint8_t*)custom_malloc(SD_TMP_SIZE);
|
||||
//sd卡临时buf申请
|
||||
os_printf("sd_buf:%X\n",e_read->sd_buf);
|
||||
|
||||
|
||||
g_amrnb_decode = e_read;
|
||||
return (void*)e_read;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void amr_decode_thread(void *d)
|
||||
{
|
||||
char *filename = (char *)d;
|
||||
|
||||
uint32_t count = 0;
|
||||
uint8_t status = get_amrnb_decode_status();
|
||||
if(status != AMR_STOP)
|
||||
{
|
||||
set_amrnb_decode_status(AMR_STOP);
|
||||
}
|
||||
while((get_amrnb_decode_status() != AMR_STOP) && count < 1000)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
count ++;
|
||||
}
|
||||
if(count >= 1000)
|
||||
{
|
||||
os_printf("%s creat fail:%d\n",__FUNCTION__,get_amrnb_decode_status());
|
||||
return;
|
||||
}
|
||||
|
||||
struct amr_extern_read *amr = (struct amr_extern_read*)amr_read_init(filename);
|
||||
|
||||
//这里先判断是amrwb还是amrnb,根据不同去创建不同的线程
|
||||
|
||||
if(amr)
|
||||
{
|
||||
char magic[16];
|
||||
amr->amr_read( amr,magic, 0,sizeof( char )*strlen( AMRWB_MAGIC_NUMBER ));
|
||||
amr->amr_seek(amr,0);
|
||||
//如果不是wb就是nb(即使不是nb,也会进去判断后退出)
|
||||
if (strncmp( magic, AMRWB_MAGIC_NUMBER, strlen( AMRWB_MAGIC_NUMBER ) ) == 0 )
|
||||
{
|
||||
os_task_create("amrwb", amrwb_decode_file_thread, (void*)amr, OS_TASK_PRIORITY_NORMAL, 0, NULL, 4*1024);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_task_create("amrnb", amrnb_decode_file_thread, (void*)amr, OS_TASK_PRIORITY_NORMAL, 0, NULL, 3*1024);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef __AMR_APP_H
|
||||
#define __AMR_APP_H
|
||||
|
||||
#define AMRNB_MAGIC_NUMBER "#!AMR\n"
|
||||
#define AMRWB_MAGIC_NUMBER "#!AMR-WB\n"
|
||||
|
||||
#define AMRNB_TO_PCM_SIZE (160*8) //一定是160的倍数
|
||||
#define AMRWB_TO_PCM_SIZE (320*4) //一定是160的倍数
|
||||
enum
|
||||
{
|
||||
AMR_NOT_RUN, //代表可能创建了线程,但没有实际运行(可能是创建线程失败或者被其他高优先级任务一直卡住)
|
||||
AMR_PLAY,
|
||||
AMR_PAUSE,
|
||||
AMR_STOP,
|
||||
};
|
||||
struct amr_extern_read;
|
||||
|
||||
typedef uint32_t (*_amr_read)(struct amr_extern_read *extern_read,void *ptr,uint32_t offset,uint32_t size);
|
||||
typedef void (*_amr_close)(struct amr_extern_read *extern_read,void *data);
|
||||
typedef void (*_amr_seek)(struct amr_extern_read *extern_read,uint32_t offset);
|
||||
//读取mp3的接口,外部先将fp创建,然后注册read和close的函数
|
||||
struct amr_extern_read
|
||||
{
|
||||
void *fp;
|
||||
uint32_t readsize;
|
||||
_amr_read amr_read;
|
||||
_amr_close amr_close;
|
||||
_amr_seek amr_seek;
|
||||
uint8_t *sd_buf;
|
||||
uint8_t status; //用于控制是否继续编码或者是否为暂停、播放、退出几个状态,只是由外部去控制
|
||||
uint8_t inside_status; //内部状态,由内部去修改状态
|
||||
};
|
||||
|
||||
uint8_t get_amrnb_decode_status();
|
||||
uint8_t set_amrnb_decode_status(uint8_t status);
|
||||
void amr_decode_thread(void *d);
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user