java - Convert audio stereo to audio byte -


i've trying audio processing, i'm stuck stereo mono conversion. looked in internet regarding stereo mono conversion.

as far know, can take left channel, right channel, sum them , divide 2. when dump result wav file again, got lot of foreground noise. know noise can caused when processing data, there overflow in byte variable.

this class retrieving byte[] data chunks mp3 file:

public class 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 file: " + this._inputfilename);         system.exit(1);     }      if (bytesread > 0)         return abdata;     else         return null; } 

}

this means, every time call getsamples, returns array like:

buff = {lchannel, rchannel, lchannel, rchannel,lchannel, rchannel,lchannel, rchannel...}

the processing routine conversion mono looks like:

    byte[] buff = null;         while( (buff = _input.getsamples()) != null ){              /** convert mono */             byte[] mono = new byte[buff.length/2];              (int = 0 ; < 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 average between 2 channels (stereo)*/                 mono[i * 2] = (byte)((short)(m >> 8));                 mono[i * 2 + 1] = (byte)(m & 0xff);             } 

}

and writing wav file using:

     public static void writewav(byte [] theresult, int samplerate, file outfile) {         // convert theresult wav file         // should use file if samplecount big!         int thesize = theresult.length;           inputstream = 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; done file");             return;         }       } 

with 44100 sample rate.

take in mind byte[] array i've got it's pcm, mp3 -> pcm conversion it's done specifying

 this._decodedformat = new audioformat(audioformat.encoding.pcm_signed, 44100, 16, 2, 1, 44100, false); this._audioinputdecodedstream = audiosystem.getaudioinputstream(this._decodedformat, this._audioinputstream); 

as said, when writing wav file i've got lot of noise. pretend apply every chunk of byte fft, think because of noisy sound result it's not correct.

because i'm taking 2 songs, 1 of them 20 seconds crop another, , when comparing crop fft result original 20 seconds subset, doesn't match @ all.

i think reason it's incorrect conversion stereo->mono.

hope know this,

regards.

as pointed out in comments, endianness may wrong. also, converting signed short , shifting may cause first byte 0xff.

try:

int hi = 0; int lo = 1; int left = (buff[i * 4 + hi] << 8) | (buff[i * 4 + lo] & 0xff); int right = (buff[i * 4 + 2 + hi] << 8) | (buff[i * 4 + 2 + lo] & 0xff); int avg = (left + right) / 2; mono[i * 2 + hi] = (byte)((avg >> 8) & 0xff); mono[i * 2 + lo] = (byte)(avg & 0xff); 

then switch values of hi , lo see if gets better.


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

qt - Errors in generated MOC files for QT5 from cmake -