added support for custom forier formulas

This commit is contained in:
Sasserisop 2023-12-07 14:16:26 -07:00
parent 541827e168
commit f0368c806b
3 changed files with 46 additions and 31 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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-->