- tinymp3源码获取:cpuimage/tinymp3: a tiny mp3 encoder && decoder example (github.com)
- 下载下来的源码文件:
- 移植shine_mp3到嵌入式工程:
源码里面有使用动态分配内存的方式,我这边省事直接使用freeRTOS 的heap4.c的API代替。
在heap_4.c中添加calloc函数:
在shine_mp3.h中定义宏:
使用定义的宏替换shine_mp3.c中的malloc、calloc、free;
所以需要在heap_4.c中申请一个100K的数组。
- 测试MP3编码:
void TinyMp3Test(const TCHAR* pMp3filePath,const TCHAR* pwavefilePath)
{
__WaveHeader pWavhead;
UINT fnum;
FIL mp3fil;
FIL wavefil;
FRESULT nRet; /* API result code */
shine_config_t config;
int written;
shine_t s;
uint32_t count,i;
unsigned char *data;
shine_set_config_mpeg_defaults(&config.mpeg);
config.wave.channels = PCM_MONO;
config.wave.samplerate = 16000;
//config.mpeg.bitr = 24;
printf("size = %d\n",sizeof(shine_t));
if(shine_check_config(config.wave.samplerate,config.mpeg.bitr)<0)
{
printf("unsupported samplerate/bitrate configuration\n");
}
if(config.wave.channels>1)
{
config.mpeg.mode = STEREO;
}
else
{
config.mpeg.mode = MONO;
}
config.mpeg.mode = MONO;
s = shine_initialise(&config);
if(NULL != s)
{
printf("shine initialise success\n");
}
else
{
printf("shine initialise error\n");
return ;
}
printf("each frame need data %d\n",shine_samples_per_pass(s));
/* 打开wave文件,跳过头,每次读取576*2字节数据
* */
nRet = f_open(&wavefil,pwavefilePath,FA_READ|FA_OPEN_EXISTING);
if(nRet!=FR_OK)
{
printf("f_open error res = %d\r\n",nRet);
return;
}
nRet = f_read(&wavefil,&pWavhead,44,&fnum);
if(nRet!=FR_OK)
{
printf("f_open error res = %d\r\n",nRet);
return;
}
/* 打开mp3文件,写方式
* */
nRet = f_open(&mp3fil,pMp3filePath,FA_CREATE_ALWAYS|FA_WRITE);
if(nRet!=FR_OK)
{
printf("f_open error res = %d\r\n",nRet);
return;
}
printf("data.chunksize = %d\r\n",pWavhead.data.ChunkSize);
count = pWavhead.data.ChunkSize/(shine_samples_per_pass(s)*2);
for(i=0;i<count;i++)
{
nRet = f_read(&wavefil,&gWavebuf,sizeof(gWavebuf),&fnum);
if(nRet!=FR_OK)
{
printf("f_open error res = %d\r\n",nRet);
f_close(&mp3fil);
f_close(&wavefil);
return;
}
data = shine_encode_buffer_interleaved(s,gWavebuf,&written);
printf("written = %d\r\n",written);
nRet = f_write(&mp3fil,(UINT8*)data,written,&fnum);
if(nRet!=FR_OK)
{
printf("uFF_WriteWavFileHead : f_write error res = %d\r\n",nRet);
f_close(&mp3fil);
f_close(&wavefil);
return;
}
}
data = shine_flush(s,&written);
nRet = f_write(&mp3fil,(UINT8*)data,written,&fnum);
if(nRet!=FR_OK)
{
printf("uFF_WriteWavFileHead : f_write error res = %d\r\n",nRet);
f_close(&mp3fil);
f_close(&wavefil);
return;
}
/*close encoder*/
shine_close(s);
f_close(&mp3fil);
f_close(&wavefil);
printf("encode mp3 success ok \n");
}