MATH201/content/scripts/playaudio.js

190 lines
4.9 KiB
JavaScript
Raw Permalink Normal View History

2023-12-06 22:48:05 -07:00
var slider = document.getElementById("sliderHarmonics");
var textHarmonics = document.getElementById("textHarmonics");
var sliderFreq = document.getElementById("sliderFreq")
var textFreq = document.getElementById("textFreq");
var playing = document.getElementById("playButton");
textHarmonics.innerHTML = slider.value; // Display the default slider value
textFreq.innerHTML=sliderFreq.value
var isPlaying = false;
var real = new Float32Array(110);
var imag = new Float32Array(110);
var cspec = document.getElementById('spectrum'),
ctxspec = cspec.getContext("2d");
cspec.height = 200;
cspec.width = 500;
sliderFreq.oninput = function() {
textFreq.innerHTML=this.value;
osc.frequency.value=this.value;
}
// Update the current slider value (each time you drag the slider handle)
slider.oninput = function() {
textHarmonics.innerHTML = this.value;
if (isPlaying){
var numCoeffs = this.value; // The more coefficients you use, the better the approximation
//var real = new Float32Array(numCoeffs+10);
//var imag = new Float32Array(numCoeffs+10);
//real[0] = 0.5;
//for (var i = 1; i < numCoeffs; i++) { // note i starts at 1
// imag[i] = 1 / (i * Math.PI);
//}
for (var i = 1; i <= 110; i++) {
real[i]=0;
}
for (var i = 1; i <= numCoeffs; i++) { // note i starts at 1
real[2*i] = (2/Math.PI) *( 1/(2*i+1)-1/(2*i-1) );
}
osc.frequency.value = textFreq.innerHTML;
//var imag= new Float32Array([0,0,0,0,0]); // sine
//var real = new Float32Array(imag.length); // cos
var customWave = context.createPeriodicWave(real, imag); // cos,sine
osc.setPeriodicWave(customWave);
//isPlaying = false;
// osc.stop();
//playSound(this.value);}
}}
//setup audio context
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new window.AudioContext();
//create nodes
var osc; //create in event listener so we can press the button more than once
var masterGain = context.createGain();
var analyser = context.createAnalyser();
//routing
masterGain.connect(analyser);
analyser.connect(context.destination);
//draw function for canvas
function drawWave(analyser, ctx) {
var buffer = new Float32Array(1024),
w = ctx.canvas.width;
ctx.strokeStyle = "#D44"; //reddish color
ctx.setTransform(1,0,0,-1,0,100.5); // flip y-axis and translate to center
ctx.lineWidth = 2;
ctxspec.strokeStyle = "#44D" //blueish color
ctxspec.setTransform(1,0,0,1,0,100.5);
ctxspec.lineWidth = 2;
var wspec=ctxspec.canvas.width;
(function loop() {
analyser.getFloatTimeDomainData(buffer);
var prevValue=999;
var currentValue=999;
for (var i=10; i<1024; i++){
currentValue=buffer[i];
if (currentValue>prevValue && currentValue>-0.05 && currentValue<0.05){
break;
}
prevValue=currentValue;
}
ctx.clearRect(0, -100, w, ctx.canvas.height);
ctx.beginPath();
ctx.moveTo(0, buffer[i] * 90);
for (var x = i; x < w+i; x += 2) ctx.lineTo(x-i+2, buffer[x] * 90);
ctx.stroke();
//spectrum stuff:
//real=getReal();
//console.log(real);
ctxspec.clearRect(0, -100, wspec, ctxspec.canvas.height);
ctxspec.beginPath();
ctxspec.moveTo(0, 80);
for (var j=0; j<100; j++){
ctxspec.lineTo(j*10,real[j]*400+80);
}
ctxspec.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 as background
ctx.moveTo(0, 100.5);
ctx.lineTo(c.width, 100.5);
ctx.stroke();
c.style.backgroundImage = "url(" + c.toDataURL() + ")";
$('button').on('mousedown', function() {
if (playing.innerHTML==="Pause sound"){
playing.innerHTML="Play the sound";
isPlaying = false;
osc.stop();
}else{
playing.innerHTML="Pause sound";
playSound(textHarmonics.innerHTML);
}});
});
function playSound(h){
var c = document.getElementById('scope'),
ctx = c.getContext("2d");
osc = context.createOscillator();
//osc settings
var numCoeffs = h; // The more coefficients you use, the better the approximation
//real[0] = 0.5;
//for (var i = 1; i < numCoeffs; i++) { // note i starts at 1
// imag[i] = 1 / (i * Math.PI);
//}
for (var i = 1; i <= 110; i++) {
real[i]=0;
}
for (var i = 1; i <= numCoeffs; i++) { // note i starts at 1
real[2*i] = (2/Math.PI) *( 1/(2*i+1)-1/(2*i-1) );
}
//var imag= new Float32Array([0,0,0,0,0]); // sine
//var real = new Float32Array(imag.length); // cos
var customWave = context.createPeriodicWave(real, imag); // cos,sine
osc.setPeriodicWave(customWave);
osc.frequency.value = textFreq.innerHTML;
osc.connect(masterGain);
osc.start();
isPlaying = true;
drawWave(analyser, ctx);
}