javascript - custom wave forms in web audio API -
i'm working through awesome article: https://jackschaedler.github.io/circles-sines-signals/dft_introduction.html
i want use web audio api's periodicwave object implement demo:
however, when set periodic wave these settings:
var real = new float32array([0,0,1,0,1]); var imag = new float32array(real.length); var customwave = context.createperiodicwave(real,imag); osc.setperiodicwave(customwave);
i output wave looks this:
here full code: http://jsbin.com/zaqojavixo/4/edit see waveform, please press play sound few times.
i believe these should match up, here questions:
- am missing fundamental theory here or implementing incorrectly? periodicwave object supposed same thing illustrated in article?
- if taking wrong approach, how implement diagram in web audio api? have been able match below connecting 2 different sine waves of different frequencies same gain node - how different using periodicwave object?
- i'm new dsp , web audio api - suggested reading appreciated!
- secondarily, in example, have push 'play sound' button couple of times before correct data drawn canvas - analyser seems behind oscillator, though analyser.getfloattimedomaindata() called after start oscillator thoughts on what's going on here?
edit: noted in comments, graph upside down (on canvas 0,0 upper left corner).
note first array defines cosine terms, second sine terms:
the
real
parameter represents array of cosine terms (traditionally terms). in audio terminology, first element (index 0) dc-offset of periodic waveform. second element (index 1) represents fundamental frequency. third element represents first overtone, , on. first element ignored , implementations must set 0 internally.the
imag
parameter represents array of sine terms (traditionally b terms). first element (index 0) should set 0 (and ignored) since term not exist in fourier series. second element (index 1) represents fundamental frequency. third element represents first overtone, , on.
you see expected waveform "reversed" (drawn upside down @julian pointing out in answer - fixed below):
(i inlined code here arrays swapped around:)
updated fixed drawing issues in original code
//setup audio context window.audiocontext = window.audiocontext || window.webkitaudiocontext; var context = new window.audiocontext(); //create nodes var osc; //create in event listener can press button more once var mastergain = context.creategain(); var analyser = context.createanalyser(); //routing mastergain.connect(analyser); analyser.connect(context.destination); var isplaying = false; //draw function canvas function drawwave(analyser, ctx) { var buffer = new float32array(1024), w = ctx.canvas.width; ctx.strokestyle = "#777"; ctx.settransform(1,0,0,-1,0,100.5); // flip y-axis , translate center ctx.linewidth = 2; (function loop() { analyser.getfloattimedomaindata(buffer); ctx.clearrect(0, -100, w, ctx.canvas.height); ctx.beginpath(); ctx.moveto(0, buffer[0] * 90); (var x = 2; x < w; x += 2) ctx.lineto(x, buffer[x] * 90); ctx.stroke(); if (isplaying) requestanimationframe(loop) })(); } //button trigger $(function() { var c = document.getelementbyid('scope'), ctx = c.getcontext("2d"); c.height = 200; c.width = 600; // make 0-line permanent background ctx.moveto(0, 100.5); ctx.lineto(c.width, 100.5); ctx.stroke(); c.style.backgroundimage = "url(" + c.todataurl() + ")"; $('button').on('mousedown', function() { osc = context.createoscillator(); //osc settings osc.frequency.value = 220; var imag= new float32array([0,0,1,0,1]); // sine var real = new float32array(imag.length); // cos var customwave = context.createperiodicwave(real, imag); // cos,sine osc.setperiodicwave(customwave); osc.connect(mastergain); osc.start(); isplaying = true; drawwave(analyser, ctx); }); $('button').on('mouseup', function() { isplaying = false; osc.stop(); }); });
button {position:fixed;left:10px;top:10px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>play sound</button> <canvas id='scope'></canvas>
Comments
Post a Comment