Trabla: Flash & ActionScript3 - record WAV 16khz mono from Microphone example
Solving:
1. Create project folder structure
C:\micrecorder\
C:\micrecorder\app.fla
C:\micrecorder\src\MicRecorder.as
2. Connect app.fla to src.MicRecorder Class
3. Sources of MicRecorder.as
package src{
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.utils.ByteArray;
import flash.media.Microphone;
import flash.media.SoundCodec;
import flash.events.*;
import flash.events.SampleDataEvent;
import flash.utils.ByteArray;
import flash.net.FileReference;
import flash.utils.Endian;
public class MicRecorder extends MovieClip {
public static const BUTTON_WIDTH = 80;
public static const BUTTON_HEIGHT = 30;
// 2^5 - 1
public static const FLOAT_TO_INT:int = 32767;
public static const STRING_RECORD = 'Record';
public static const STRING_STOP = 'Stop';
private static const STRING_SAVE_WAV = 'Save WAV';
private var btnRecord:TextField = new TextField();
private var btnStopRecording:TextField = new TextField();
private var btnSaveWAVFile:TextField = new TextField();
//sound bytes from microphone 16khz
private var soundBytes:ByteArray = new ByteArray();
// sound bytes converted to WAV file ( with correct wav header)
private var wav:ByteArray = new ByteArray();
// file reference to save WAV audio of recorded sound
private var file:FileReference = new FileReference();
private var microphone:Microphone;
public function MicRecorder() {
var x = 10;
var y = 10;
btnRecord.htmlText = "<a href='event:null'> "+STRING_RECORD+"</a>";
btnRecord.width = BUTTON_WIDTH;
btnRecord.height = BUTTON_HEIGHT;
btnRecord.x = x;
btnRecord.y = y;
btnRecord.border = true;
btnRecord.selectable = false;
x = x + btnRecord.width + 10;
btnStopRecording.htmlText = "<a href='event:null'> "+STRING_STOP+"</a>";
btnStopRecording.width = BUTTON_WIDTH;
btnStopRecording.height = BUTTON_HEIGHT;
btnStopRecording.x = x;
btnStopRecording.y = y;
btnStopRecording.border = true;
btnStopRecording.selectable = false;
x = x + btnStopRecording.width + 10;
btnSaveWAVFile.htmlText = "<a href='event:null'> "+STRING_SAVE_WAV+"</a>";
btnSaveWAVFile.width = BUTTON_WIDTH;
btnSaveWAVFile.height = BUTTON_HEIGHT;
btnSaveWAVFile.x = x;
btnSaveWAVFile.y = y;
btnSaveWAVFile.border = true;
btnSaveWAVFile.selectable = false;
x = x + btnSaveWAVFile.width + 10;
//Init Event Listeners
btnRecord.addEventListener( MouseEvent.CLICK, record );
btnStopRecording.addEventListener( MouseEvent.CLICK, stopRecording );
btnSaveWAVFile.addEventListener( MouseEvent.CLICK, saveWavFile );
this.addChild( btnRecord );
this.addChild( btnStopRecording );
this.addChild( btnSaveWAVFile );
}//public function MicRecorder() {
public function record(e:MouseEvent):void
{
clearSoundData();
microphone = Microphone.getMicrophone();
microphone.codec = SoundCodec.SPEEX;
microphone.rate = 16;// - !!! ALWAYS 16KHz if encoding SPEEX!!!
microphone.encodeQuality = 10;
microphone.setLoopBack(false);
microphone.setUseEchoSuppression(true);
microphone.gain = 50;
microphone.setSilenceLevel(5, 1000);
microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, listen);
}//public function record(e:MouseEvent):void
public function stopRecording(e:MouseEvent):void
{
microphone.removeEventListener(SampleDataEvent.SAMPLE_DATA, listen);
}//public function stopRecording(e:MouseEvent):void
public function saveWavFile(e:MouseEvent):void
{
saveSound();
}//public function saveWavFile(e:MouseEvent):void
//Read sound data from microphone and save in soundBytes Array
public function listen(e:SampleDataEvent):void{
while(e.data.bytesAvailable)
{
var sample:Number = e.data.readFloat();
//sample - IEEE FLOAT 32 audio data - value range from -1 to 1
//Mono
soundBytes.writeFloat(sample);
//to Stereo uncomment line below
//soundBytes.writeFloat(sample);
}
}
//Clear all sound buffers
public function clearSoundData(){
soundBytes.clear();
wav.clear();
}//public function clearSoundData(){
//Creates wav file with header from captured microphone input
public function getWAV():ByteArray{
return encodeToWav(soundBytes);
}//public function getWAV():ByteArray{
//Saves WAV file of recorded microphone sound
public function saveSound(){
file.save(encodeToWav(soundBytes));
}//public function saveSound(){
public function encodeToWav( data:ByteArray ):ByteArray
{
var channels:uint = 1;
var BitsPerSample:uint = 16;
var SampleRate:uint = 16000;
var bytes: ByteArray = new ByteArray();
bytes.endian = Endian.LITTLE_ENDIAN;
bytes.writeUTFBytes( 'RIFF' );
bytes.writeInt( data.length );
bytes.writeUTFBytes( 'WAVE' );
//Subchunk1ID Contains the letters "fmt " (0x666d7420 big-endian form).
bytes.writeUTFBytes( 'fmt ' );
//Subchunk1Size. 16 for PCM
bytes.writeInt( 16 );
//formatValues other than 1 indicate some form of compression.
bytes.writeShort( 1 );
//channels
bytes.writeShort( channels );
//sample rate
bytes.writeInt( SampleRate );
//ByteRate == SampleRate * NumChannels * BitsPerSample/8
bytes.writeInt( SampleRate * channels * BitsPerSample / 8 );
//BlockAlign == NumChannels * BitsPerSample/8
//The number of bytes for one sample including all channels.
bytes.writeShort( channels * BitsPerSample / 8 );
bytes.writeShort( 16 );
bytes.writeUTFBytes( 'data' );
//Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8
bytes.writeUnsignedInt( data.length );
data.position = 0;
var length:int = data.length - 4;
while (data.position < length) {
bytes.writeShort(int(data.readFloat() * 32767));
}
bytes.position = 0;
return bytes;
}//public function encodeToWav( data:ByteArray ):ByteArray
}//public class MicRecorder extends MovieClip {
}//package src{
No comments:
Post a Comment