我試圖做一些音頻處理,我真的堅持立體聲單聲道轉換。我在互聯網上查看有關立體聲轉換爲單聲道。轉換音頻立體聲爲音頻字節
據我所知,我可以把左聲道,右聲道,總和它們除以2.但是當我把結果再次轉儲到WAV文件中時,我得到了很多前景噪聲。我知道處理數據時可能會引起噪聲,字節變量中會出現一些溢出。
這是從一個MP3文件中檢索字節[]數據塊我的課:
公共類InputSoundDecoder {
private int BUFFER_SIZE = 128000;
private String _inputFileName;
private File _soundFile;
private AudioInputStream _audioInputStream;
private AudioFormat _audioInputFormat;
private AudioFormat _decodedFormat;
private AudioInputStream _audioInputDecodedStream;
public InputSoundDecoder(String fileName) throws UnsuportedSampleRateException{
this._inputFileName = fileName;
this._soundFile = new File(this._inputFileName);
try{
this._audioInputStream = AudioSystem.getAudioInputStream(this._soundFile);
}
catch (Exception e){
e.printStackTrace();
System.err.println("Could not open file: " + this._inputFileName);
System.exit(1);
}
this._audioInputFormat = this._audioInputStream.getFormat();
this._decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 1, 44100, false);
this._audioInputDecodedStream = AudioSystem.getAudioInputStream(this._decodedFormat, this._audioInputStream);
/** Supported sample rates */
switch((int)this._audioInputFormat.getSampleRate()){
case 22050:
this.BUFFER_SIZE = 2304;
break;
case 44100:
this.BUFFER_SIZE = 4608;
break;
default:
throw new UnsuportedSampleRateException((int)this._audioInputFormat.getSampleRate());
}
System.out.println ("# Channels: " + this._decodedFormat.getChannels());
System.out.println ("Sample size (bits): " + this._decodedFormat.getSampleSizeInBits());
System.out.println ("Frame size: " + this._decodedFormat.getFrameSize());
System.out.println ("Frame rate: " + this._decodedFormat.getFrameRate());
}
public byte[] getSamples(){
byte[] abData = new byte[this.BUFFER_SIZE];
int bytesRead = 0;
try{
bytesRead = this._audioInputDecodedStream.read(abData,0,abData.length);
}
catch (Exception e){
e.printStackTrace();
System.err.println("Error getting samples from file: " + this._inputFileName);
System.exit(1);
}
if (bytesRead > 0)
return abData;
else
return null;
}
}
這意味着,每次我打電話getSamples時間,它返回一個數組,如:
buff = {Lchannel,Rchannel,Lchannel,Rchannel,Lchannel,Rchannel,Lchannel,Rchannel ...}
的處理例行程序的轉換到單聲道的樣子:
byte[] buff = null;
while((buff = _input.getSamples()) != null){
/** Convert to mono */
byte[] mono = new byte[buff.length/2];
for (int i = 0 ; i < mono.length/2; ++i){
int left = (buff[i * 4] << 8) | (buff[i * 4 + 1] & 0xff);
int right = (buff[i * 4 + 2] <<8) | (buff[i * 4 + 3] & 0xff);
int avg = (left + right)/2;
short m = (short)avg; /*Mono is an average between 2 channels (stereo)*/
mono[i * 2] = (byte)((short)(m >> 8));
mono[i * 2 + 1] = (byte)(m & 0xff);
}
}
和寫入到使用wav文件:
public static void writeWav(byte [] theResult, int samplerate, File outfile) {
// now convert theResult into a wav file
// probably should use a file if samplecount is too big!
int theSize = theResult.length;
InputStream is = new ByteArrayInputStream(theResult);
//Short2InputStream sis = new Short2InputStream(theResult);
AudioFormat audioF = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
samplerate,
16,
1, // channels
2, // framesize
samplerate,
false
);
AudioInputStream ais = new AudioInputStream(is, audioF, theSize);
try {
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, outfile);
} catch (IOException ioe) {
System.err.println("IO Exception; probably just done with file");
return;
}
}
隨着44100作爲採樣率。
考慮採取實際的byte []數組,我已經得到它已經PCM,所以MP3 - > PCM轉換它通過指定
this._decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 1, 44100, false); this._audioInputDecodedStream = AudioSystem.getAudioInputStream(this._decodedFormat, this._audioInputStream);
當我做說,寫入Wav文件時,我聽到很多噪音。我假裝對每一個字節應用一個FFT,但我認爲由於噪聲很大,結果是不正確的。
因爲我拍了兩首歌,其中一首是另一首20秒的作品,當比較作品的fft結果與原始的20秒子集時,它完全不匹配。
我認爲這是不正確的轉換stereo-> mono的原因。
希望有人知道這件事,
問候。
如果是由溢出引起的,爲什麼不除以2然後求和? – James 2013-05-09 16:26:55
您可能會錯誤地獲取數據的字節序。試着做一些像沒有轉換的讀寫操作,或者更好的辦法是通過一個已知的乾淨的數據源(也許是一個只使用2個不同振幅值的方波)並檢查輸出的原始字節。有了一點經驗,如果音頻軟件中的信號圖表可能會很快被識別出來。 – 2013-05-09 16:29:05
如果我不轉換,所有我從一個MP3文件它是原始編碼字節。轉換它不是一個可選的步驟,它必須完成才能將真實的聲音值輸入到數組中。 劃分和求和有相同的結果... – Mario 2013-05-09 16:33:43