#WEBWONDERS : The world of web audio
A new year and yet another new theme for blog articles. After #GRIDGOODIES and #FREEBIEFRIDAY, this is a new theme we introduce with #WEBWONDERS. In these blogs, we explore the wonderful world of the browser operating system and uncover hidden or not so hidden treasures, tips and tricks.
So, in this blog, we let you explore the web audio API with a small code snippet that shows how you can create your own audio wave and have it played through the speakers of the device. The most straightforward is to create a sound through a sine wave with variable frequency. While technically, the web audio API comes with oscillator objects that could generate this, in this sample, we will use Pascal code for creating the buffer that will hold the sine wave. It is this buffer of floats (TJSFloat32Array) that will be played. The only part of the code where we need to use JavaScript is for the creation of the audio context. This is because there is a subtle difference between the creation on Chromium based browsers and webkit based browsers. So, basically the JavaScript code tries the webkit based creation if the Chromium based creation failed.
So, the Pascal function to do this is:
procedure playfreq(freq, volume: double); var ctx: TJSAudioContext; buf: TJSAudioBuffer; wave: TJSFloat32Array; i,len: integer; src: TJSAudioBufferSourceNode; sampleFreq: double; begin // connect to the browser window Audio Context. asm ctx = new (window.AudioContext || window.webkitAudioContext)(); end; // get the sample frequency the audio context can use len := round(ctx.sampleRate); // create a new buffer of floating point values wave := TJSFloat32Array.new(len); // determine the sine wave frequency in relation to the audio context sample frequency sampleFreq := ctx.sampleRate / freq; // create a buffer on the audio context buf := ctx.createBuffer(1, len, ctx.sampleRate); wave := buf.getChannelData(0); // fill the float array with the sine wave data taking frequency & volume in account for i := 0 to len - 1 do wave[i] := (volume /100) * sin(i/(samplefreq/(2*PI))); // create a buffer source object for the audio contect src := ctx.createBufferSource(); // assign the buffer holding the wave to the audio buffer source object src.buffer := buf; // connect the audio buffer source object to the audio context output src.connect(ctx.destination); // play the sample from position 0 src.start(0.0); end;
With this Pascal routine, it becomes simple to put two TWebTrackBar components on the form that allow to select the frequency and the volume and add a button to play the sound. With a frequency selectable between 20Hz en 20000Hz and volume between 0% and 100%, you have a little web application to test your ears frequency range or speaker frequency range, whatever fails first.
Curious about web technology? Or you have interesting challenges to accomplish in a web application, let us hear what you want to see covered in a next #WEBWONDERS blog!