我在论坛里面找了个heilx软件解码的程序,数据是通过串口接收的,
程序查找同步字都成功了,解码函数也执行通过就是没有看到输出PCM数据,不知道PCM数据到底是在那里输出的
大家帮忙看看在那个位置输出PCM
/**
* @brief mp3_player 进行mp3文件解码、播放
* @param filename:要播放的文件路径
* @retval none
*/
//static void mp3_player(const char *filename)
void mp3_player(void)
{
int err,/* i,*/ outputSamps;//, current_sample_rate = 0;
int read_offset = 0; /* 读偏移指针 */
int bytes_left = 0; /* 剩余字节数 */
unsigned long Frames = 0; /* mP3帧计数 */
unsigned char *read_ptr = buffer; /* 缓冲区指针 */
HMP3Decoder Mp3Decoder; /* mp3解码器指针 */
//打开成功
//初始化MP3解码器
Mp3Decoder = MP3InitDecoder();
//获取输入数据流,调用helix库解码,输出PCM数据,约20ms完成一次循环
//开始进入播放状态,期间中断会修改touch_even状态
while(1) //循环1, 如果touch_even不是切歌状态则继续呆在循环体里
{
//有时出现解码错误,错误后继续在本循环体内,继续播放
//
read_ptr = buffer;
bytes_left = 0;
//
Communication();
if(UART1_Index3 < 1126)
break;
read_ptr = buffer; //指向mp3输入流
bytes_left = UART1_Index3; //实际读到的输入流大小大小
UART1_Index3 = 0;
bufflag = 0;
// UART1_Index3 = 0;
//按帧处理
while(1)
{
read_offset = MP3FindSyncWord(read_ptr, bytes_left); //寻找帧同步,返回第一个同步字的位置
if(read_offset < 0) //没有找到同步字
{
break; //跳出循环2,回到循环1
}
read_ptr += read_offset; //偏移至同步字的位置
bytes_left -= read_offset; //同步字之后的数据大小
//
err = MP3Decode(Mp3Decoder, &read_ptr, &bytes_left, outBuf[bufflag], 0); //开始解码 参数:mp3解码结构体、输入流指针、输入流大小、输出流指针、数据格式
Frames++;
if (err != ERR_MP3_NONE) //错误处理
{
switch (err)
{
case ERR_MP3_INDATA_UNDERFLOW:
// printf("ERR_MP3_INDATA_UNDERFLOW
");
read_ptr = buffer;
//fres = f_read(&file, read_ptr, sizeof(buffer), &rw_num);
bytes_left = rw_num;
break;
case ERR_MP3_MAINDATA_UNDERFLOW:
/* do nothing - next call to decode will provide more mainData */
// printf("ERR_MP3_MAINDATA_UNDERFLOW
");
break;
default:
// printf("UNKNOWN ERROR:%d
", err);
// 跳过此帧
if (bytes_left > 0)
{
bytes_left --;
read_ptr ++;
}
break;
}
}
else //解码无错误,准备把数据输出到PCM
{
MP3GetLastFrameInfo(Mp3Decoder, &Mp3FrameInfo); //获取解码信息
/* 输出到DAC */
outputSamps = Mp3FrameInfo.outputSamps; //PCM数据个数
if (outputSamps > 0)
{
//
if(1 == Mp3FrameInfo.nChans)
Convert_Mono( &outBuf[bufflag][0]);
else
Convert_Stereo(&outBuf[bufflag][0]);
// if (Mp3FrameInfo.nChans == 1) //单声道
// {
//单声道数据需要复制一份到另一个声道
// for (i = outputSamps - 1; i >= 0; i--)
// {
// outBuf[bufflag][i * 2] = outBuf[bufflag];
// outBuf[bufflag][i * 2 + 1] = outBuf[bufflag];
// }
// outputSamps *= 2;
// }
// else
// {
// }
//非单声道数据可直接由DMA传输到IIS交给DAC
/* 等待DMA播放完,这段时间我们可以干其他的事,扫描事件进行处理 */
// while((DMA1_Channel5->CCR&DMA_CCR1_EN) && !(DMA1->ISR&DMA1_IT_TC5))
// {
// static uint8_t i=0;
// if(i==0)
// {
// PCM1770_VolumeSet(voice);
// i++;
// }
// even_process();
// }
/*DMA传输完毕*/
// DMA_ClearFlag(DMA1_FLAG_TC5 | DMA1_FLAG_TE5);
// DMA_I2S_Configuration((uint32_t)outBuf[bufflag], outputSamps);
// bufflag = 1 -bufflag; //切换buffer
}
}
// if(file.fptr==file.fsize) //如果指针指向了文件尾,表示数据全部读完
// {
// printf("END
");
// if(play_index<file_num-1) //自动开始下一首歌曲
// {
// play_index++;
// player_state = S_SWITCH; //进入切歌状态,跳出
//}
//else
//{
// play_index = 0;
// player_state = S_SWITCH;
//}
// break; //跳出这首歌的播放状态 while break;
// }
}
}
// f_close(&file); //结束播放本歌曲,关闭文件
// MP3FreeDecoder(Mp3Decoder);
// I2S_Stop();
}
程序已经执行到了红 {MOD}区域了,输出PCM个数是2304个PCM,但是我查看outbuf缓存区全部00不知道是怎么回事
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
谢谢的的回答,我看了你的程序,但是不知道你的PCM数据是不是放到,buffer1和,buffer2缓存区里面的,是不是红 {MOD}区域的代码,PCM数据就已经出错到,buffer缓存区里面的
/**
* @brief Start wave player
* @param None
* @retval None
*/
void WavePlayerStart(void)
{
u32 br;
FRESULT res;
uint16_t i;
char path[] = "0:/";
//buffer_switch = 1;
hMP3Decoder=MP3InitDecoder();//初始化MP3解码器
/* Get the read out protection status */
if (f_opendir(&dir, path)!= FR_OK)
{
while(1)
{
STM_EVAL_LEDToggle(LED5);
Delay(10);
}
}
else
{
if (WaveRecStatus == 1)
{
WaveFileName = REC_WAVE_NAME;
}
else
{
WaveFileName = "0:audio.mp3";//WAVE_NAME; 名字改下
}
/* Open the wave file to be played */
if (f_open(&fileR, WaveFileName , FA_READ) != FR_OK)
{
STM_EVAL_LEDOn(LED5);
Command_index = 1;
}
else
{
//复位计数器
bytesLeft=0;
readPtr=readBuf;
res=f_read(&fileR,readBuf,READBUF_SIZE,&br);
bytesLeft += br;
//if(res!=FR_OK||br==0) break;
XferCplt=1;
buffer_switch=0;
init=0;
WavePlayerInit((u32)44100);
while(1)
{
offset=MP3FindSyncWord(readPtr, bytesLeft);//寻找下一帧头 assume EOF if no sync found
if(offset<0)break;
readPtr+=offset; //data start point
bytesLeft-=offset; //in buffer
if(bytesLeft<READBUF_SIZE)
{
memmove(readBuf,readPtr,bytesLeft);
res=f_read(&fileR,readBuf+bytesLeft,READBUF_SIZE-bytesLeft,&br);
if((res)||(br==0)) break;
if(br<READBUF_SIZE-bytesLeft)
memset(readBuf+bytesLeft+br,0,READBUF_SIZE-bytesLeft-br);
bytesLeft=READBUF_SIZE;
readPtr=readBuf;
}
MP3GetLastFrameInfo(hMP3Decoder, &mp3FrameInfo);
从这里开始是不是PCM已经转换完成了,准备送往DA转换
// if(init==0)//根据MP3帧信息初始化音频接口 //
// {
// WavePlayerInit((u32)mp3FrameInfo.samprate);
// init=1;
// }
while(XferCplt==0);
XferCplt=0;
if(buffer_switch == 0)
{
Audio_MAL_Play((u32)buffer2,BUFF_SIZE*2);
//Decbuf=buffer1;
MP3Decode(hMP3Decoder,&readPtr,&bytesLeft,buffer1,0);
//Convert_Stereo(buffer1);
buffer_switch = 1;
}
else
{
Audio_MAL_Play((u32)buffer1,BUFF_SIZE*2);
//Decbuf=buffer2;
MP3Decode(hMP3Decoder,&readPtr,&bytesLeft,buffer2,0);
//Convert_Stereo(buffer2);
buffer_switch = 0;
}
}
}
}
}
解码是这句,前面只是读取mp3文件用的,
MP3Decode(hMP3Decoder,&readPtr,&bytesLeft,buffer1,0);
MP3Decode(hMP3Decoder,&readPtr,&bytesLeft,buffer2,0);
解码完成的PCM数据放在buffer1,2中,Audio_MAL_play实际是开启buffer到外部DAC的DMA通道
奥,我在看看,不知道为我执行过解码函数MP3Decode,buffer缓存区没有数据全部是00
如果清空缓冲区 说明mp3帧错误,你看看decode这个函数返回的什么值
一周热门 更多>