I've finished integrating your code into the Chiron library, although
it doesn't work perfectly yet.
https://cixar.com/tracs/javascript/browser/trunk/src/sk89q.therisenrealm.com
The frequency generator I "noted" on your blog wasn't correct. The
rectified code is here:
https://cixar.com/tracs/javascript/browser/trunk/src/sk89q.therisenrealm.com/wav.js#L62
I liked the hexdump feature soo much that I implemented it with line
representations in the core library. I used Chiron's iterator tools.
https://cixar.com/tracs/javascript/browser/trunk/src/boost.js?rev=383#L446
It looks like this on the console:
>>> log(dump(sinWav(440, 1)))
52 49 46 46 3E 00 00 00 57 41 56 45 66 6D 74 20 "RIFF>\x00\x00\x00WAVEfmt "
10 00 00 00 01 00 01 00 B8 0F 00 00 70 1F 00 00
"\x10\x00\x00\x00\x01\x00\x01\x00\xb8\x0f\x00\x00p\x1f\x00\x00"
02 00 10 00 64 61 74 61 0A 00 00 00 00 00 57 6A
"\x02\x00\x10\x00data\n\x00\x00\x00\x00\x00Wj"
A2 89 69 19 14 5A "\xa2\x89i\x19\x14Z"
To improve the output of the dump, I modified my escape routine to
escape non-printable characters lower than 256 as byte encodings
instead of word encodings. All of the non-printable-characters were
written out as full unicode escapes before. I considered encoding
numbers lower than 64 as octal escapes, but decided not to since
Python's repr function doesn't.
I also integrated the base64 encoder you found by Tyler Atkins into
the main library since it was correct in more cases than the library I
ported from Wikipedia. It would be nice to get a reference to the
original source with its license explicated. It also calls the
quality of the corresponding decode function into question, so it
would be nice to know whether he wrote one of those too. I modified
most routines I found to use variadic Array.push and Array.join
instead of incremental string concatenation since that technique
doesn't depend on the JavaScript implementation to optimize String +=.
https://cixar.com/tracs/javascript/browser/trunk/src/crypt/base64.js#L25
I added some unit tests and demos.
This one plays and hexdumps a chirp:
http://modulesjs.com/nightly/src/run.html?sk89q.therisenrealm.com/demo/dump.js
https://cixar.com/tracs/javascript/browser/trunk/src/sk89q.therisenrealm.com/demo/dump.js
Here's a demo for verifying pitch accuracy. It plays A440 repeatedly.
http://modulesjs.com/nightly/src/run.html?sk89q.therisenrealm.com/demo/440.js
https://cixar.com/tracs/javascript/browser/trunk/src/sk89q.therisenrealm.com/demo/440.js
Here's one that plays the chromatic scale:
http://modulesjs.com/nightly/src/run.html?sk89q.therisenrealm.com/demo/chromatic.js
https://cixar.com/tracs/javascript/browser/trunk/src/sk89q.therisenrealm.com/demo/chromatic.js
Here's a unit test that verifies the accuracy of the frequency
function using your pitch table as an oracle:
http://modulesjs.com/nightly/src/run.html?sk89q.therisenrealm.com/test/frequency.js
https://cixar.com/tracs/javascript/browser/trunk/src/sk89q.therisenrealm.com/test/frequency.js
I also ported your demo, but there's a bug at the moment. The
relative pitches are mostly correct, but the octaves shift, sometimes
into upper bands where the sampling rate causes the wave to transform
to random pitches.
http://modulesjs.com/nightly/src/sk89q.therisenrealm.com/demo/reprise.html
Kris