I recorded voice samples from my microphone using Adobe Flash Builder 4.6 / AIR, voice recorded successfully. I first converted voice data(byte array) to base64 format in actionscript then I converted that base64 data to WAV file using my PHP code. but that WAV file throw file corrupted issue in RiffPad.
RIFFPad is a viewer for RIFF formatted files like WAV, AVI.
expected wav file specification:
sampling Rate : 22KHZ
// -- saves the current audio data as a .wav file
protected function onSubmit( event:Event ):void {
alertBox.show("Processing ... please wait.");
stopPlayback();
stopRecording();
playBtn.enabled = recordBtn.enabled = submitBtn.enabled = false;
var position:int = capture.buffer.position;
var wavWriter:WAVWriter = new WAVWriter()
var wavWriter1:WaveEncoder = new WaveEncoder()
wavWriter.numOfChannels = 1;
wavWriter.samplingRate = 22050;
wavWriter.sampleBitRate = 16;
var wavBytes:ByteArray = new ByteArray;
capture.buffer.position = 0;
wavWriter.processSamples(wavBytes, capture.buffer, capture.microphone.rate * 1000, 1);
Settings.alertBox3.show("RATE :"+capture.microphone.rate); //Here show RATE: 8
//wavWriter.processSamples(wavBytes, capture.buffer, 22050, 1);
//wavBytes = wavWriter1.encode( capture.buffer, 1, 16, 22050);
capture.buffer.position = position;
wavBytes.position=0;
submitVoiceSample(Base64_new.encodeByteArray(wavBytes));
}
WAV Writer header function:
public var samplingRate = 22050;
public var sampleBitRate:int = 8;
public var numOfChannels:int = 2;
private var compressionCode:int = 1;
private function header(dataOutput:IDataOutput, fileSize:Number):void
{
dataOutput.writeUTFBytes("RIFF");
dataOutput.writeUnsignedInt(fileSize); // Size of whole file
dataOutput.writeUTFBytes("WAVE");
// WAVE Chunk
dataOutput.writeUTFBytes("fmt "); // Chunk ID
dataOutput.writeUnsignedInt(16); // Header Chunk Data Size
dataOutput.writeShort(compressionCode); // Compression code - 1 = PCM
dataOutput.writeShort(numOfChannels); // Number of channels
dataOutput.writeUnsignedInt(samplingRate); // Sample rate
dataOutput.writeUnsignedInt(samplingRate * numOfChannels * sampleBitRate / 8); // Byte Rate == SampleRate * NumChannels * BitsPerSample/8
dataOutput.writeShort(numOfChannels * sampleBitRate / 8); // Block align == NumChannels * BitsPerSample/8
dataOutput.writeShort(sampleBitRate); // Bits Per Sample
}
WAV file Writer function:
public function processSamples(dataOutput:IDataOutput, dataInput:ByteArray, inputSamplingRate:int, inputNumChannels:int = 1):void
{
if (!dataInput || dataInput.bytesAvailable <= 0) // Return if null
throw new Error("No audio data");
// 16 bit values are between -32768 to 32767.
var bitResolution:Number = (Math.pow(2, sampleBitRate)/2)-1;
var soundRate:Number = samplingRate / inputSamplingRate;
var dataByteLength:int = ((dataInput.length/4) * soundRate * sampleBitRate/8);
// data.length is in 4 bytes per float, where we want samples * sampleBitRate/8 for bytes
//var fileSize:int = 32 + 8 + dataByteLength;
var fileSize:int = 32 + 4 + dataByteLength;
// WAV format requires little-endian
dataOutput.endian = Endian.LITTLE_ENDIAN;
// RIFF WAVE Header Information
header(dataOutput, fileSize);
// Data Chunk Header
dataOutput.writeUTFBytes("data");
dataOutput.writeUnsignedInt(dataByteLength); // Size of whole file
// Write data to file
dataInput.position = 0;
var tempData:ByteArray = new ByteArray();
tempData.endian = Endian.LITTLE_ENDIAN;
// Write to file in chunks of converted data.
while (dataInput.bytesAvailable > 0)
{
tempData.clear();
// Resampling logic variables
var minSamples:int = Math.min(dataInput.bytesAvailable/4, 8192);
var readSampleLength:int = minSamples;//Math.floor(minSamples/soundRate);
var resampleFrequency:int = 100; // Every X frames drop or add frames
var resampleFrequencyCheck:int = (soundRate-Math.floor(soundRate))*resampleFrequency;
var soundRateCeil:int = Math.ceil(soundRate);
var soundRateFloor:int = Math.floor(soundRate);
var jlen:int = 0;
var channelCount:int = (numOfChannels-inputNumChannels);
/*
trace("resampleFrequency: " + resampleFrequency + " resampleFrequencyCheck: " + resampleFrequencyCheck
+ " soundRateCeil: " + soundRateCeil + " soundRateFloor: " + soundRateFloor);
*/
var value:Number = 0;
// Assumes data is in samples of float value
for (var i:int = 0;i < readSampleLength;i+=4)
{
value = dataInput.readFloat();
// Check for sanity of float value
if (value > 1 || value < -1)
throw new Error("Audio samples not in float format");
// Special case with 8bit WAV files
if (sampleBitRate == 8)
value = (bitResolution * value) + bitResolution;
else
value = bitResolution * value;
// Resampling Logic for non-integer sampling rate conversions
jlen = (resampleFrequencyCheck > 0 && i % resampleFrequency < resampleFrequencyCheck) ? soundRateCeil : soundRateFloor;
for (var j:int = 0; j < jlen; j++)
{
writeCorrectBits(tempData, value, channelCount);
}
}
dataOutput.writeBytes(tempData);
}
}
I send that base64 data to my service request php side i got the '$this->request->voiceSample' parameter and decode base64 to .wav file
file_put_contents('name.wav', base64_decode($this->request->voiceSample));
After load that "name.wav" file in Riffpad I got issue
There is extra junk at the end of the file.
Any one please give me the advice to solve this issue...