?? audio.c
字號:
//音頻編解碼主程序
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "decode.h"
void main(int argc, char**argv)
{
FILE *musicout;
Bit_stream_struc bs;
frame_params fr_ps;
IIS_side_info_t IIS_side_info;
IIS_scalefac_t IIS_scalefac;
unsigned int old_crc;
layer info;
int sync, clip;
int done = FALSE;
unsigned long frameNum=0;
unsigned long bitsPerSlot;
unsigned long sample_frames;
typedef short PCM[2][SSLIMIT][SBLIMIT];
PCM *pcm_sample; //PCM采樣
pcm_sample = (PCM *) mem_alloc((long) sizeof(PCM), "PCM Samp");
if (argc==1)
{
printf("Useage:decode file.mp3 output.pcm\n");
return;
}
fr_ps.header = &info;
if ((musicout = fopen(argv[2], "w+b")) == NULL) {
printf ("Could not create \"%s\".\n", argv[2]);
exit(1);
}
open_bit_stream_r(&bs, argv[1], BUFFER_SIZE);
sample_frames = 0;
while(!end_bs(&bs))
{
//嘗試幀同步
sync = seek_sync(&bs, SYNC_WORD, SYNC_WORD_LENGTH);
if (!sync)
{
done = TRUE;
printf("\nFrame cannot be located\n");
out_fifo(*pcm_sample, 3, &fr_ps, done, musicout, &sample_frames);
break;
}
//解碼幀頭
decode_info(&bs, &fr_ps);
//將fr_ps.header中的信息解讀到fr_ps的相關域中
hdr_to_frps(&fr_ps);
//輸出相關信息
if(frameNum == 0)
WriteHdr(&fr_ps);
printf("\r%05lu", frameNum++);
if (info.error_protection)
buffer_CRC(&bs, &old_crc);
switch (info.lay) {
case 3:
{
int nSlots, main_data_end, flush_main;
int bytes_to_discard, gr, ch, ss, sb;
static int frame_start = 0;
bitsPerSlot = 8;
//取Side信息
IIS_get_side_info(&bs, &IIS_side_info, &fr_ps);
nSlots = main_data_slots(fr_ps);
//讀取音頻主數據
for (; nSlots > 0; nSlots--)
hputbuf((unsigned int) getbits(&bs,8), 8);
main_data_end = hsstell() / 8; /*前一幀數據*/
if ( flush_main=(hsstell() % bitsPerSlot) )
{
hgetbits((int)(bitsPerSlot - flush_main));
main_data_end ++;
}
bytes_to_discard = frame_start - main_data_end - IIS_side_info.main_data_begin ;
if( main_data_end > 4096 )
{
frame_start -= 4096;
rewindNbytes( 4096 );
}
frame_start += main_data_slots(fr_ps);
if (bytes_to_discard < 0)
{
printf("Not enough main data to decode frame %d. Frame discarded.\n",
frameNum - 1);
break;
}
for (; bytes_to_discard > 0; bytes_to_discard--) hgetbits(8);
clip = 0;
for (gr=0;gr<2;gr++) {
double lr[2][SBLIMIT][SSLIMIT],ro[2][SBLIMIT][SSLIMIT];
//主解碼
for (ch=0; ch<fr_ps.stereo; ch++)
{
long int is[SBLIMIT][SSLIMIT]; /*保存量化數據*/
int part2_start;
part2_start = hsstell();
//獲取比例因子
IIS_get_scale_factors(&IIS_scalefac,&IIS_side_info, gr, ch, &fr_ps);
//Huffman解碼
IIS_hufman_decode(is, &IIS_side_info, ch, gr, part2_start, &fr_ps);
//反量化采樣
IIS_dequantize_sample(is, ro[ch], &IIS_scalefac, &(IIS_side_info.ch[ch].gr[gr]), ch, &fr_ps);
}
//立體聲處理
IIS_stereo(ro, lr, &IIS_scalefac, &(IIS_side_info.ch[0].gr[gr]), &fr_ps);
for (ch=0; ch<fr_ps.stereo; ch++)
{
double re[SBLIMIT][SSLIMIT];
double hybridIn[SBLIMIT][SSLIMIT]; /* 濾波器輸入 */
double hybridOut[SBLIMIT][SSLIMIT]; /* 濾波器輸出 */
double polyPhaseIn[SBLIMIT]; /* 多項輸入. */
IIS_reorder(lr[ch], re, &(IIS_side_info.ch[ch].gr[gr]), &fr_ps);
//抗鋸齒處理
IIS_antialias(re, hybridIn,
&(IIS_side_info.ch[ch].gr[gr]), &fr_ps);
//IMDCT
for (sb=0; sb<SBLIMIT; sb++)
{ /* 合成. */
IIS_hybrid(hybridIn[sb], hybridOut[sb], sb, ch, &(IIS_side_info.ch[ch].gr[gr]), &fr_ps);
}
for (ss=0;ss<18;ss++) //多相頻率倒置
for (sb=0; sb<SBLIMIT; sb++)
if ((ss%2) && (sb%2))
hybridOut[sb][ss] = -hybridOut[sb][ss];
for (ss=0;ss<18;ss++) { //多相合成
for (sb=0; sb<SBLIMIT; sb++)
polyPhaseIn[sb] = hybridOut[sb][ss];
//子帶合成
clip += SubBandSynthesis(polyPhaseIn, ch, &((*pcm_sample)[ch][ss][0]));
}
}
//PCM輸出
out_fifo(*pcm_sample, 18, &fr_ps, done, musicout, &sample_frames);
}
if(clip > 0)
printf("\n%d samples clipped.\n", clip);
}
break;
default:
printf("\nOnly layer IIS supported!\n");
exit(1);
break;
}
}
close_bit_stream_r(&bs);
fclose(musicout);
printf("\nDecoding done.\n");
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -