actionscript 3 - Remove unvanted clicks in generated sound in AS3 -
i having following problem when generating sound wave in flash. generator part :
const sampling_rate:int = 44100; const two_pi:number = 2 * math.pi; const two_pi_over_sr:number = two_pi / sampling_rate; const sample_size:int = 8192 / 4; function generatesine(fq:number):bytearray { var bytes:bytearray = new bytearray(); var sample:number; var amp:number = 1; (var i:int=0; i<sample_size; i++) { sample = amp* math.sin(i * two_pi_over_sr * fq ); bytes.writefloat(sample); } bytes.position = 0; return bytes; }
and playback part:
function playbacksamplehandler(event:sampledataevent):void { var sample:number; (var i:int = 0; < sample_size && sounddata.bytesavailable; i++) { sample = sounddata.readfloat(); event.data.writefloat(sample); event.data.writefloat(sample); } } function onclickplay(e:mouseevent) { sounddata= new bytearray(); var sound:bytearray= new bytearray(); sound=generatesine(440); sounddata.writebytes(sound,0,sound.length); sounddata.position = 0; morphedsound.addeventlistener(sampledataevent.sample_data, playbacksamplehandler); soundchannel = morphedsound.play(); }
quick explanation: write values sine function bytearray , playback handler reads array , plays sound. write 1 8192/4 sample buffer.
problem: problem when there annoying clicks on end of sound, artifacts of sine wave being cut on value other 0. question how can avoid this?
bonus: know how can generate example 100 ms of sine wave when buffers in flash strict i.e. 2048 8192 ?
links: if helps code based on tutorial http://www.bit-101.com/blog/?p=2669 , own explorations.
you need preserve phase of sine wave occurs @ end of sample data processing. otherwise sine wave not continued smoothly , clicks speak of.
var totalsamples:int=0; function generatesine(fq:number):bytearray { var bytes:bytearray = new bytearray(); var sample:number; var amp:number = 1; (var i:int=0; i<sample_size; i++) { sample = amp* math.sin((i+totalsamples) * two_pi_over_sr * fq ); // uses stored phase ^^^ bytes.writefloat(sample); } totalsamples+=sample_size; // preserves phase between subsequent samples bytes.position = 0; return bytes;
}
update: i've noticed calling generator twice in row - awful. must never call function twice if need 1 result of work.
function onclickplay(e:mouseevent) { sounddata= generatesine(440); // why using writebytes if can use assignment? sounddata.position = 0; morphedsound.addeventlistener(sampledataevent.sample_data, playbacksamplehandler); soundchannel = morphedsound.play();
}
also, make sound end full (half-)wave of sound , remove last click need, use technique:
function generatesine(fq:number,cleanfinish:boolean=false):bytearray { var bytes:bytearray = new bytearray(); var sample:number; var amp:number = 1; (var i:int=0; i<sample_size; i++) { sample = amp* math.sin((i+totalsamples) * two_pi_over_sr * fq ); // uses stored phase ^^^ bytes.writefloat(sample); if (cleanfinish) if ((math.abs(sample)<(sampling_rate/fq/3))&&(i>sample_size-sampling_rate/fq)) break; // triggers drop if sampling last wave } totalsamples+=i; // preserves phase between subsequent samples bytes.position = 0; return bytes;
}
call function optional boolean parameter set true receive correctly terminated wave.
Comments
Post a Comment