Я пытаюсь выполнить некоторую обработку звука, я действительно придерживаюсь стереофонического преобразования в моно. Я смотрел в интернете, касаясь стереофонического преобразования.Преобразование аудио-стерео в аудио-байт
Насколько я знаю, я могу взять левый канал, правый канал, суммировать их и разделить на 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 как частота дискретизации.
Примите во внимание, что на самом деле байт [] массив, который я получил это уже ИКМ, так mp3 -> преобразования ИКМ это делается путем указания
this._decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 1, 44100, false); this._audioInputDecodedStream = AudioSystem.getAudioInputStream(this._decodedFormat, this._audioInputStream);
В I сказал, при записи в Wav-файл у меня много шума. Я притворяюсь, что применим к каждому фрагменту байта БПФ, но я думаю, из-за шумного звука результат не правильный.
Потому что я беру две песни, одна из них - это 20-секундный урожай от другой, и при сравнении результата урожая fft с исходным 20-секундным подмножеством это совсем не совпадает.
Я думаю, что это неправильное преобразование стерео-> моно.
Надежда кто-то знает что-то об этом,
С уважением.
Если это вызвано переполнением, почему бы не разделить на 2, а затем суммировать? – James
Возможно, вы ошиблись в представлении данных.Попробуйте сделать что-то вроде чтения и записи без преобразования или, еще лучше, поместите через него известный чистый источник данных (возможно, прямоугольную волну, используя только 2 различных значения амплитуды) и исследуйте необработанные байты вывода. Имея небольшой опыт, можно быстро распознать типы проблем, если графический сигнал в аудиопрограмме. –
Если я не конвертирую, все, что у меня есть из mp3-файла, это необработанные закодированные байты. Преобразование - это необязательный шаг, это нужно сделать, чтобы иметь реальные значения звука в массиве. Разделение и суммирование имеют тот же результат ... – Mario