added support for custom forier formulas
This commit is contained in:
parent
541827e168
commit
f0368c806b
|
@ -175,40 +175,37 @@ $$\bar{f}(x)=\frac{2}{\pi}+\frac{2}{\pi}\sum_{k=1}^\infty\left( \frac{1}{2k+1}-\
|
||||||
Even with 10 terms, we get a pretty good approximation:
|
Even with 10 terms, we get a pretty good approximation:
|
||||||
![fouriercosineofsin.png](drawings/fouriercosineofsin.png)
|
![fouriercosineofsin.png](drawings/fouriercosineofsin.png)
|
||||||
Here's a little script that generates an audible waveform of this Fourier series!
|
Here's a little script that generates an audible waveform of this Fourier series!
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<label for="real_coff">$a_n$ formula:</label>
|
||||||
<button id="playButton">Play the sound</button>
|
<input type="text" id="realc" name="real_coff" size="50" value="real[2&starn] = (2/Math.PI)&star( 1/(2&starn+1)-1/(2&starn-1) )">
|
||||||
|
</br>
|
||||||
|
<label for="imag_coff">$b_n$ formula:</label>
|
||||||
|
<input type="text" id="imagc" name="imag_coff" size="50" value="">
|
||||||
|
<button id="playButton">Play the sound</button>
|
||||||
|
</br>
|
||||||
<canvas id='scope'></canvas>
|
<canvas id='scope'></canvas>
|
||||||
|
|
||||||
<canvas id='spectrum'></canvas>
|
<canvas id='spectrum'></canvas>
|
||||||
|
|
||||||
<div class="slidecontainer">
|
<div class="slidecontainer">
|
||||||
<p>Number of harmonics: <span id="textHarmonics"></span></p>
|
<p>Number of harmonics: <span id="textHarmonics"></span></p>
|
||||||
<input type="range" min="0" max="100" value="50" style="width: 500px;" id="sliderHarmonics">
|
<input type="range" min="0" max="100" value="50" style="width: 500px;" id="sliderHarmonics">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="slidecontainer">
|
<div class="slidecontainer">
|
||||||
<p>Frequency: <span id="textFreq"></span></p>
|
<p>Frequency (for $n=1$): <span id="textFreq"></span></p>
|
||||||
<input type="range" min="0" max="440" value="220" style="width: 500px;" id="sliderFreq">
|
<input type="range" min="0" max="440" value="220" style="width: 500px;" id="sliderFreq">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="playaudio.js"></script>
|
<script src="playaudio.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
You can generate any arbitrary Fourier series with this. Try putting
|
||||||
|
imag[n] = (2*Math.PI/n)*(-1)**(n+1)+4/((n**3)*Math.PI)*((-1)**(n)-1)
|
||||||
|
|
||||||
|
for the $b_{n}$ formula and delete the $a_{n}$ formula. Now it will show the fourier sin series of $x^2$ we derived earlier!
|
||||||
|
you can also make some nasty sounds, try this one:
|
||||||
|
imag[Math.floor(n**1.1)] = (-1)**(n)*1/(2*n)+Math.random()/10
|
||||||
|
|
||||||
We have prepared ourselves now, now we start solving PDE's. He's encouraging us to attend the lectures in these last two weeks. He's making it sound like PDE's are hard.
|
We have prepared ourselves now, now we start solving PDE's. He's encouraging us to attend the lectures in these last two weeks. He's making it sound like PDE's are hard.
|
|
@ -3,6 +3,8 @@ var textHarmonics = document.getElementById("textHarmonics");
|
||||||
var sliderFreq = document.getElementById("sliderFreq")
|
var sliderFreq = document.getElementById("sliderFreq")
|
||||||
var textFreq = document.getElementById("textFreq");
|
var textFreq = document.getElementById("textFreq");
|
||||||
var playing = document.getElementById("playButton");
|
var playing = document.getElementById("playButton");
|
||||||
|
var real_coff = document.getElementById("realc")
|
||||||
|
var imag_coff = document.getElementById("imagc")
|
||||||
textHarmonics.innerHTML = slider.value; // Display the default slider value
|
textHarmonics.innerHTML = slider.value; // Display the default slider value
|
||||||
textFreq.innerHTML=sliderFreq.value
|
textFreq.innerHTML=sliderFreq.value
|
||||||
|
|
||||||
|
@ -22,7 +24,7 @@ var cspec = document.getElementById('spectrum'),
|
||||||
|
|
||||||
sliderFreq.oninput = function() {
|
sliderFreq.oninput = function() {
|
||||||
textFreq.innerHTML=this.value;
|
textFreq.innerHTML=this.value;
|
||||||
osc.frequency.value=this.value/2;
|
osc.frequency.value=this.value;
|
||||||
}
|
}
|
||||||
// Update the current slider value (each time you drag the slider handle)
|
// Update the current slider value (each time you drag the slider handle)
|
||||||
slider.oninput = function() {
|
slider.oninput = function() {
|
||||||
|
@ -38,12 +40,15 @@ slider.oninput = function() {
|
||||||
//}
|
//}
|
||||||
for (var i = 1; i <= 110; i++) {
|
for (var i = 1; i <= 110; i++) {
|
||||||
real[i]=0;
|
real[i]=0;
|
||||||
|
imag[i]=0;
|
||||||
}
|
}
|
||||||
for (var i = 1; i <= numCoeffs; i++) { // note i starts at 1
|
for (var n = 1; n <= numCoeffs; n++) { // note i starts at 1
|
||||||
real[2*i] = (2/Math.PI) *( 1/(2*i+1)-1/(2*i-1) );
|
//real[2*i] = (2/Math.PI) *( 1/(2*i+1)-1/(2*i-1) );
|
||||||
|
eval(real_coff.value);
|
||||||
|
eval(imag_coff.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
osc.frequency.value = textFreq.innerHTML/2;
|
osc.frequency.value = textFreq.innerHTML;
|
||||||
//var imag= new Float32Array([0,0,0,0,0]); // sine
|
//var imag= new Float32Array([0,0,0,0,0]); // sine
|
||||||
//var real = new Float32Array(imag.length); // cos
|
//var real = new Float32Array(imag.length); // cos
|
||||||
var customWave = context.createPeriodicWave(real, imag); // cos,sine
|
var customWave = context.createPeriodicWave(real, imag); // cos,sine
|
||||||
|
@ -81,8 +86,8 @@ function drawWave(analyser, ctx) {
|
||||||
ctx.strokeStyle = "#D44"; //reddish color
|
ctx.strokeStyle = "#D44"; //reddish color
|
||||||
ctx.setTransform(1,0,0,-1,0,100.5); // flip y-axis and translate to center
|
ctx.setTransform(1,0,0,-1,0,100.5); // flip y-axis and translate to center
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctxspec.strokeStyle = "#44D" //blueish color
|
|
||||||
ctxspec.setTransform(1,0,0,1,0,100.5);
|
//ctxspec.setTransform(1,0,0,1,0,100.5);
|
||||||
ctxspec.lineWidth = 2;
|
ctxspec.lineWidth = 2;
|
||||||
var wspec=ctxspec.canvas.width;
|
var wspec=ctxspec.canvas.width;
|
||||||
(function loop() {
|
(function loop() {
|
||||||
|
@ -106,11 +111,19 @@ function drawWave(analyser, ctx) {
|
||||||
//spectrum stuff:
|
//spectrum stuff:
|
||||||
//real=getReal();
|
//real=getReal();
|
||||||
//console.log(real);
|
//console.log(real);
|
||||||
ctxspec.clearRect(0, -100, wspec, ctxspec.canvas.height);
|
ctxspec.clearRect(0, 0, wspec, ctxspec.canvas.height);
|
||||||
ctxspec.beginPath();
|
ctxspec.beginPath();
|
||||||
ctxspec.moveTo(0, 80);
|
ctxspec.moveTo(0, 100);
|
||||||
|
ctxspec.strokeStyle = "#44D" //blueish color for cos
|
||||||
for (var j=0; j<100; j++){
|
for (var j=0; j<100; j++){
|
||||||
ctxspec.lineTo(j*10,real[j]*400+80);
|
ctxspec.lineTo(j*10,real[j]*-200+100);
|
||||||
|
}
|
||||||
|
ctxspec.stroke();
|
||||||
|
ctxspec.beginPath();
|
||||||
|
ctxspec.moveTo(0, 100);
|
||||||
|
ctxspec.strokeStyle = "#D44" //redish color for sine
|
||||||
|
for (var j=0; j<100; j++){
|
||||||
|
ctxspec.lineTo(j*10,imag[j]*-200+100);
|
||||||
}
|
}
|
||||||
ctxspec.stroke();
|
ctxspec.stroke();
|
||||||
if (isPlaying) requestAnimationFrame(loop)
|
if (isPlaying) requestAnimationFrame(loop)
|
||||||
|
@ -159,15 +172,18 @@ function playSound(h){
|
||||||
var numCoeffs = h; // The more coefficients you use, the better the approximation
|
var numCoeffs = h; // The more coefficients you use, the better the approximation
|
||||||
|
|
||||||
|
|
||||||
//real[0] = 0.5;
|
//real[0] = 2/Math.PI;
|
||||||
//for (var i = 1; i < numCoeffs; i++) { // note i starts at 1
|
//for (var i = 1; i < numCoeffs; i++) { // note i starts at 1
|
||||||
// imag[i] = 1 / (i * Math.PI);
|
// imag[i] = 1 / (i * Math.PI);
|
||||||
//}
|
//}
|
||||||
for (var i = 1; i <= 110; i++) {
|
for (var i = 1; i <= 110; i++) {
|
||||||
real[i]=0;
|
real[i]=0;
|
||||||
|
imag[i]=0;
|
||||||
}
|
}
|
||||||
for (var i = 1; i <= numCoeffs; i++) { // note i starts at 1
|
for (var n = 1; n <= numCoeffs; n++) { // note i starts at 1
|
||||||
real[2*i] = (2/Math.PI) *( 1/(2*i+1)-1/(2*i-1) );
|
//real[2*i] = (2/Math.PI) *( 1/(2*i+1)-1/(2*i-1) );
|
||||||
|
eval(real_coff.value);
|
||||||
|
eval(imag_coff.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,7 +197,7 @@ function playSound(h){
|
||||||
//var real = new Float32Array(imag.length); // cos
|
//var real = new Float32Array(imag.length); // cos
|
||||||
var customWave = context.createPeriodicWave(real, imag); // cos,sine
|
var customWave = context.createPeriodicWave(real, imag); // cos,sine
|
||||||
osc.setPeriodicWave(customWave);
|
osc.setPeriodicWave(customWave);
|
||||||
osc.frequency.value = textFreq.innerHTML/2;
|
osc.frequency.value = textFreq.innerHTML;
|
||||||
osc.connect(masterGain);
|
osc.connect(masterGain);
|
||||||
osc.start();
|
osc.start();
|
||||||
isPlaying = true;
|
isPlaying = true;
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
{{/* $content := $content | replaceRE "(\\$.*)\\*(.*\\$)" "$1$2" */}}
|
{{/* $content := $content | replaceRE "(\\$.*)\\*(.*\\$)" "$1$2" */}}
|
||||||
{{ $content := $content | replaceRE "\\*" "\\*"}}
|
{{ $content := $content | replaceRE "\\*" "\\*"}}
|
||||||
<!-- The above command replaces * with \* so that *'s inside equations dont get interpreted as emphasis or bold tags. Needed for the page on convolutions.>
|
<!-- The above command replaces * with \* so that *'s inside equations dont get interpreted as emphasis or bold tags. Needed for the page on convolutions.>
|
||||||
|
{{$content := $content | replaceRE "&star" "*"}}
|
||||||
|
<!-- The above command replaces &star with * so that I can write javascript multiplication in the .md notes, particularly for the Fourier series page. This is really messy.>
|
||||||
{{ $content := $content | replaceRE "\n" "\n\n" }}
|
{{ $content := $content | replaceRE "\n" "\n\n" }}
|
||||||
{{ $content := $content | replaceRE $matrixBreak "\\\\\\\\\\\\\\\\" }}
|
{{ $content := $content | replaceRE $matrixBreak "\\\\\\\\\\\\\\\\" }}
|
||||||
<!--The above command replaces a \\ in content/*.md files with a \\\\ yes it looks silly-->
|
<!--The above command replaces a \\ in content/*.md files with a \\\\ yes it looks silly-->
|
||||||
|
|
Loading…
Reference in New Issue