?? encode.c
字號:
#include <stdio.h>#include "global.h"#include "common.h"#include "encoder.h"#include "enwindow.h"#include "video.h"extern unsigned _stklen = 16384;extern FILE *hOutput;extern unsigned long length, last_sample;extern int channels; void filter(short *work_buffer, unsigned int length, unsigned int stereo, unsigned int mult);/* 低通濾波程序*/void low_pass( buffer, length, stereo, mult)short *buffer;unsigned int length, stereo, mult;{ short work_buffer[PCM_BUFFER + 8]; unsigned int i; static char init = TRUE; short pass1[8], pass2[8], pass3[8], pass4[8]; if (init) { for(i=0; i<8; i++) { work_buffer[i]=0; pass1[i]=pass2[i]=pass3[i]=pass4[i]=0; } init = FALSE; } for(i=0; i<length; i++) work_buffer[i+8] = buffer[i]; // 將采樣復制到工作緩存 for(i=0; i<8; i++) work_buffer[i] = pass1[i]; for(i=0; i<8; i++) pass1[i] = buffer[length - 8 + i]; filter( work_buffer, length, stereo, mult); //采用1階濾波器 for(i=0; i<8; i++) work_buffer[i] = pass2[i]; for(i=0; i<8; i++) pass2[i] = buffer[length - 8 + i]; filter( work_buffer, length, stereo, mult); for(i=0; i<8; i++) work_buffer[i] = pass3[i]; for(i=0; i<8; i++) pass3[i] = buffer[length - 8 + i]; filter( work_buffer, length, stereo, mult); for(i=0; i<8; i++) work_buffer[i] = pass4[i]; for(i=0; i<8; i++) pass4[i] = buffer[length - 8 + i]; filter( work_buffer, length, stereo, mult); for(i=0; i<length; i++) buffer[i] = work_buffer [i+8];}void filter(work_buffer, length, stereo, mult)short *work_buffer;unsigned int length, stereo, mult;{ short temp_buffer[PCM_BUFFER]; unsigned int i; if(stereo) { if(mult == 2) { //立體聲22050 for(i=0; i<length; i++) temp_buffer[i] = (short)(0.612626*work_buffer[i+8] + 0.375311*work_buffer[i+6]); } else { //立體聲11025 for(i=0; i<length; i++) temp_buffer[i] = (short)(0.516851*work_buffer[i+8] + 0.267135*work_buffer[i+6] + 0.138069*work_buffer[i+4] + 0.071361*work_buffer[i+2]); } } else // 單聲道 { if(mult == 2) { //單聲道22050 for (i=0; i<length; i++) temp_buffer[i] = (short)(0.612626*work_buffer[i+8] + 0.375311*work_buffer[i+7]); } else { //單聲道11025 for (i=0; i<length; i++) temp_buffer[i] = (short)(0.516851*work_buffer[i+8] + 0.267135*work_buffer[i+7] + 0.138069*work_buffer[i+6] + 0.071361*work_buffer[i+5]); } } for(i=0; i<length; i++) work_buffer[i+8] = temp_buffer[i];}/************************************************************************//*/* read_samples()/*/* 功能: 從avi文件中讀取PCM采樣到緩存/*/* 限制條件: 僅適用于未壓縮的在11.025, 22.05, and 44.1Khz采樣率下的
/* 8 和 16 bit音頻 at/* /*/* 結構描述:/* 從#pAudioStream#制定的avi文件中讀取#samples_read#個片斷。如果為8bit則
/* 將其擴展到16bit。如果采樣率為11.025或22.05Khz,則將采樣復制并進行低通
/* 濾波。最后返回讀取的采樣數。
/************************************************************************/unsigned long read_samples(sample_buffer, num_samples, frame_size)short sample_buffer[PCM_BUFFER];unsigned long num_samples, frame_size;{ unsigned long samples_read, written, nsamples; static unsigned long samples_to_read, avi_samples; static char init = TRUE; int result; unsigned int i; short *dest, *source; unsigned char *csource; int file; long file_start=0; if (init) { samples_to_read = num_samples; init = FALSE; } if(bytes_processed == num_samples) { printf("\nInternal error, bytes_processed = num_samples!!!\n"); exit(-99); } if (samples_to_read >= frame_size) samples_read = frame_size; else samples_read = samples_to_read; if (channels == 2) avi_samples = samples_read/2; else avi_samples = samples_read; if(pWavFormat.nSamplesPerSec == 22050) avi_samples = avi_samples/2; if(pWavFormat.nSamplesPerSec == 11025) avi_samples = avi_samples/4; for(file=0;file<numAviFiles;file++) { if (last_sample < nextFileSamples[file]) break; file_start = nextFileSamples[file]; } result=-1; if (avi_samples==0) nsamples=0; else if ((last_sample + avi_samples) <= nextFileSamples[file]) result = AVIStreamRead(pAudioStreams[file], last_sample-file_start, avi_samples, sample_buffer, (PCM_BUFFER)*sizeof(short), &written, &nsamples); else { long want_samples1 = nextFileSamples[file] - last_sample; long want_samples2 = avi_samples - want_samples1; long got_samples1, got_samples2; result = AVIStreamRead(pAudioStreams[file], last_sample-file_start, want_samples1, sample_buffer, (PCM_BUFFER)*sizeof(short), &written, &got_samples1); result = AVIStreamRead(pAudioStreams[file + 1], 0, want_samples2, &sample_buffer[want_samples1], (PCM_BUFFER)*sizeof(short), &written, &got_samples2); nsamples = got_samples1+got_samples2; } last_sample = last_sample + nsamples; if (avi_samples != nsamples) { if(!fake_bad_frames) { fprintf(stderr, "\nHit end of audio data, audio length does not match video!\n"); fprintf(stderr, "avi file may be corrupt, try -e option.\n"); exit(23); } else { csource = (unsigned char*)sample_buffer; for(i = nsamples; i < avi_samples; i++) { bad_audio_count++; if(pWavFormat.wBitsPerSample == 8) { *csource++ = 128; i++; } else { *csource++ = 0; *csource++ = 0; } } } } if(samples_to_read&&!result) { samples_to_read -= samples_read; if(pWavFormat.wBitsPerSample == 8) { dest = sample_buffer + written - 1; csource = ((unsigned char*)(sample_buffer)) + written - 1; for(i = 0; i < written; i++) *dest-- = (*csource-- - 128) << 8; written = written * 2; } if((pWavFormat.nSamplesPerSec == 22050)&&(channels == 1)) { dest = sample_buffer + PCM_BUFFER - 1; source = sample_buffer + PCM_BUFFER/2 - 1; for(i = 0; i < PCM_BUFFER/2; i++) { *dest-- = *source; *dest-- = *source--; } low_pass(sample_buffer, samples_read, 0, 2); } if((pWavFormat.nSamplesPerSec == 22050)&&(channels == 2)) { dest = sample_buffer + PCM_BUFFER - 1; source = sample_buffer + PCM_BUFFER/2 - 1; for(i = 0; i < PCM_BUFFER/4; i++) { *dest = *source; *(dest - 2) = *source--; dest--; *dest = *source; *(dest - 2) = *source--; dest = dest - 3; } low_pass(sample_buffer, samples_read, 1, 2); } if((pWavFormat.nSamplesPerSec == 11025)&&(channels == 1)) { dest = sample_buffer + PCM_BUFFER - 1; source = sample_buffer + PCM_BUFFER/4 - 1; for(i = 0; i < PCM_BUFFER/4; i++) { *dest-- = *source; *dest-- = *source; *dest-- = *source; *dest-- = *source--; } low_pass(sample_buffer, samples_read, 0, 4); } if((pWavFormat.nSamplesPerSec == 11025)&&(channels == 2)) { dest = sample_buffer + PCM_BUFFER - 1; source = sample_buffer + PCM_BUFFER/4 - 1; for(i = 0; i < PCM_BUFFER/8; i++) { *dest = *source; *(dest - 2) = *source; *(dest - 4) = *source; *(dest - 6) = *source--; dest--; *dest = *source; *(dest - 2) = *source; *(dest - 4) = *source; *(dest - 6) = *source--; dest = dest - 7; } low_pass(sample_buffer, samples_read, 1, 4); } if (samples_read < frame_size && samples_read > 0) { for (; samples_read < frame_size; sample_buffer[samples_read++] = 0); samples_to_read = 0; } bytes_processed = samples_to_read; return(samples_read); } else return(0); }/************************************************************************//*/* get_audio()/*/* 功能: 從一個文件中讀取一幀音頻數據到緩存區/* 將數據排序以備后面的處理,并將其分成左右聲道/*/*/************************************************************************/ unsigned long get_audio(buffer, num_samples, stereo, lay)short buffer[2][1152];unsigned long num_samples;int stereo, lay;{ int j; short insamp[2304]; unsigned long samples_read; if (lay == 1) { if(stereo == 2) { /* layer 1, stereo */ samples_read = read_samples(insamp, num_samples, (unsigned long) 768); for(j=0;j<448;j++) { if(j<64) { buffer[0][j] = buffer[0][j+384]; buffer[1][j] = buffer[1][j+384]; } else { buffer[0][j] = insamp[2*j-128]; buffer[1][j] = insamp[2*j-127]; } } } else { /* layer 1, mono */ samples_read = read_samples(insamp, num_samples, (unsigned long) 384); for(j=0;j<448;j++) { if(j<64) { buffer[0][j] = buffer[0][j+384]; buffer[1][j] = 0; } else { buffer[0][j] = insamp[j-64]; buffer[1][j] = 0; } } } } else { if(stereo == 2) { /* layer 2 (or 3), stereo */ samples_read = read_samples(insamp, num_samples, (unsigned long) 2304); for(j=0;j<1152;j++) { buffer[0][j] = insamp[2*j]; buffer[1][j] = insamp[2*j+1]; } } else { /* layer 2 (or 3), mono */ samples_read = read_samples(insamp, num_samples, (unsigned long) 1152); for(j=0;j<1152;j++) { buffer[0][j] = insamp[j]; buffer[1][j] = 0; } } } return(samples_read);} /************************************************************************//*/* read_ana_window()/*/* 功能: 將編碼器窗文件 "enwindow" 讀入數組#ana_win#/*/*/************************************************************************/ void read_ana_window(ana_win)double ana_win[HAN_SIZE];{ int i; for(i=0; i<512; i++) { ana_win[i] = enwindow[i]; }}/************************************************************************//*/* window_subband()/*/* 功能: 對PCM采樣重疊窗口/*/************************************************************************/ void window_subband(buffer, z, k)short **buffer;double z[HAN_SIZE];int k;{ typedef double XX[2][HAN_SIZE]; static XX *x; int i, j; static off[2] = {0,0}; static char init = 0; static double *c; if (!init) { c = (double *) mem_alloc(sizeof(double) * HAN_SIZE, "window"); read_ana_window(c); x = (XX *) mem_alloc(sizeof(XX),"x"); for (i=0;i<2;i++) for (j=0;j<HAN_SIZE;j++) (*x)[i][j] = 0; init = 1; } for (i=0;i<32;i++) (*x)[k][31-i+off[k]] = (double) *(*buffer)++/SCALE; for (i=0;i<HAN_SIZE;i++) z[i] = (*x)[k][(i+off[k])&HAN_SIZE-1] * c[i]; off[k] += 480; off[k] &= HAN_SIZE-1;} /************************************************************************//*/* create_ana_filter()/*/* 功能: 計算分解濾波器組的系數/*
/* 結構描述:/* 計算分解濾波器組的系數并四舍五入到小數點后第9位/* 系數存儲在#filter#中。/*/************************************************************************/ void create_ana_filter(filter)double filter[SBLIMIT][64];{ register int i,k; for (i=0; i<32; i++) for (k=0; k<64; k++) { if ((filter[i][k] = 1e9*cos((double)((2*i+1)*(16-k)*PI64))) >= 0) modf(filter[i][k]+0.5, &filter[i][k]); else modf(filter[i][k]-0.5, &filter[i][k]); filter[i][k] *= 1e-9; }}/************************************************************************//*/* filter_subband()/*/* 功能: 計算分解濾波組系數/*/* 結構解釋:/* 加窗的采樣值#z#通過由矩陣#m#定義的數字濾波器,產生子帶采樣值#s#。這
是通過從加窗的樣本中取樣,并和濾波器的矩陣相乘得到的32位子帶采樣值。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -