java - AudioRecord PCM data of no use? -
i have recorded using mic in android app , plays when using audioplayer class having streamed data in. problem want append wav header data can played outside of application. pretty sure methods create header work after playing around in hex editor other audio files, leads pcm data recorded not being useful raw data in wav file?
can shed light on this? can import pcm/wav file audacity raw file , plays when try opening wav noise, again hinting pcm data @ fault.
recording settings:
int frequency = 22050; int channelconfiguration = audioformat.channel_configuration_mono; int audioencoding = audioformat.encoding_pcm_16bit; header variables:
byte[] clipdata = data; long mydatasize = clipdata.length; long mysubchunk1size = 16; int mybitspersample= 16; int myformat = 1; long mychannels = 1; long mysamplerate = 22050; long mybyterate = mysamplerate * mychannels * mybitspersample/8; int myblockalign = (int) (mychannels * mybitspersample/8); long mychunk2size = mydatasize * mychannels * mybitspersample/8; long mychunksize = 36 + mychunk2size; try { file audiodirectory = new file(environment .getexternalstoragedirectory().getabsolutepath() + "/directory/"); audiodirectory.mkdir(); file file = new file(audiodirectory, "test.wav"); if (file.exists()) file.delete(); // create new file. try { file.createnewfile(); } catch (ioexception e) { throw new illegalstateexception("failed create " + file.tostring()); } outputstream os = new fileoutputstream(file); bufferedoutputstream bos = new bufferedoutputstream(os); dataoutputstream outfile = new dataoutputstream(bos); // write wav file per wav file format outfile.writebytes("riff"); // 00 - riff outfile.write(inttobytearray((int)mychunksize), 0, 4); // 04 - how big rest of file? outfile.writebytes("wave"); // 08 - wave outfile.writebytes("fmt "); // 12 - fmt outfile.write(inttobytearray((int)mysubchunk1size), 0, 4); // 16 - size of chunk outfile.write(shorttobytearray((short)myformat), 0, 2); // 20 - audio format? 1 pcm = pulse code modulation outfile.write(shorttobytearray((short)mychannels), 0, 2); // 22 - mono or stereo? 1 or 2? (or 5 or ???) outfile.write(inttobytearray((int)mysamplerate), 0, 4); // 24 - samples per second (numbers per second) outfile.write(inttobytearray((int)mybyterate), 0, 4); // 28 - bytes per second outfile.write(shorttobytearray((short)myblockalign), 0, 2); // 32 - # of bytes in 1 sample, channels outfile.write(shorttobytearray((short)mybitspersample), 0, 2); // 34 - how many bits in sample(number)? 16 or 24 outfile.writebytes("data"); // 36 - data outfile.write(inttobytearray((int)mydatasize), 0, 4); // 40 - how big data chunk outfile.write(clipdata); // 44 - actual data - long string of numbers } convertors
public static int bytearraytoint(byte[] b) { int start = 0; int low = b[start] & 0xff; int high = b[start+1] & 0xff; return (int)( high << 8 | low ); } // these 2 routines convert byte array unsigned integer public static long bytearraytolong(byte[] b) { int start = 0; int = 0; int len = 4; int cnt = 0; byte[] tmp = new byte[len]; (i = start; < (start + len); i++) { tmp[cnt] = b[i]; cnt++; } long accum = 0; = 0; ( int shiftby = 0; shiftby < 32; shiftby += 8 ) { accum |= ( (long)( tmp[i] & 0xff ) ) << shiftby; i++; } return accum; } // =========================== // convert java types bytes // =========================== // returns byte array of length 4 private static byte[] inttobytearray(int i) { byte[] b = new byte[4]; b[0] = (byte) (i & 0x00ff); b[1] = (byte) ((i >> 8) & 0x000000ff); b[2] = (byte) ((i >> 16) & 0x000000ff); b[3] = (byte) ((i >> 24) & 0x000000ff); return b; } // convert short byte array public static byte[] shorttobytearray(short data) { return new byte[]{(byte)(data & 0xff),(byte)((data >>> 8) & 0xff)}; }
you're setting header properties wrong. wav format header should 44 bytes, followed raw audio data. here description of wav format:
http://www.sonicspot.com/guide/wavefiles.html
if you've created header , appended raw data, , resulting file plays without error sounds noise, culprit raw audio uses 2 bytes per sample set bitspersample property in header 8.
the approach you're using (prepending wav header raw audio) valid , should work fine.
update: hey, shouldn't conversion method be
// convert short byte array public static byte[] shorttobytearray(short data) { return new byte[]{(byte)(data & 0xff),(byte)((data >> 8) & 0xff)}; } ? i'm not sure >>> means in bit-shifting world.
Comments
Post a Comment