Using the Web Audio API to Make a Modem
martinmelhus.com
martinmelhus.com
This was what I came up with: https://github.com/Ravenstine/airsocket
Note it's extreme crappiness is due to a combination of my inexperience and also my desire to build as many parts from scratch as possible. The Web Audio API is only used to play audio, but the oscillator and decoding functions were written by me. It barely works. It's probably better to go full Web Audio all the way since I'm sure there's hardware acceleration(particularly with AnalyserNode). The author's method of encoding bytes is also far superior to what I came up with.
I wish such an article was published when I was trying to devise my own audio modem. He does an excellent job going over every step and explaining what's going on. Documentation and tutorials around Web Audio used to be too convoluted, with basic examples too few and far between.
It's the basis of pretty much all modern radio based telecommuncation protocols(WiFi/3G/LTE/etc).
Basic FEC can go a long way, esp if your packet sizes are large, latency is high or you have a lot of channel congestion.
[edit]
To give you an idea how awesome FEC can be quite a few ham operators do EME(Earth->Moon->Earth) contacts via JT65 with FEC[2].
[1] https://en.wikipedia.org/wiki/Forward_error_correction
[2] https://en.wikipedia.org/wiki/Earth%E2%80%93Moon%E2%80%93Ear...
You can try it here https://quiet.github.io/quiet-js
Is that example page new? That's brilliant. Your ultrasonic transmission seems to work pretty consistently.
A while ago, I made audio measurements of the built-in speakers on the iPhone 7 Plus - https://imgur.com/gallery/DRbu5
The iPhone's extension is not entirely atypical of such devices, and leaves you with a reliable passband of 500 Hz to 10 kHz - above and below those frequencies, you're getting too much noise.
If you're airgapping with audio cables, you'll have a reliable passband of 20 - 20 000 Hz or thereabouts, with some caveats for built-in audio on devices such as a Raspberry Pi that fizzle out at 15 kHz.
As noted by brian-armstrong's comment, you'll only get reliable near-ultrasonic airgapping over a wired connection.
After stumbling over a really cool Web Audio API synthesizer I wanted to play around with the API myself. I used my work situation for inspiration, but I just wanted a fun pet project and didn't really bother to deep dive into the theory of modems. Hence the naive implementation and lack of error correction.
So, do I actually use this at work? Truth be told, I've only ever used it to show of to my collegues. USB-drives are way more practical in every situation where I might want to use this. But the modem is able to provide the tool I set out to make: to copy ascii text between two computers!
Glad to see that you guys liked it!
You might laugh, but we do have an API for sending DTMF tones in WebRTC..
I'm still not convinced that this API is actually useful for any application that needs to play sound or music, but it definitely seems to have the "interesting synthesizer experiments" segment covered.
https://github.com/steffest/BassoonTracker
https://github.com/mbitsnbites/soundbox
https://github.com/pgregory/wetracker
Also, I wrote a WebExtension that lets you apply pan and gain to audio in YouTube videos (and other videos that are not cross-domain) using Web Audio https://addons.mozilla.org/en-US/firefox/addon/soundfixer/
On the web, "deprecated" doesn't mean you can't use it. It can take a long time for "officially deprecated by the standards" to become "I can't use it anymore" (obsoleted).
The replacement is the "AudioWorklet" interface and the purpose is to fix those exact synchronization issues. I wouldn't expect ScriptProcessorNode to disappear from the browser until the replacement is actually rolled out.
The Web Audio API started as the Audio Data API in Firefox, which was nothing but a buffer to blast samples into, then the Web Audio API was a refinement/competing standard above that extremely simplistic API (I adapted a Javascript-based .mod player to use AudioData instead of sticking an <audio> tag in the page circa 2011).
You've been able to generate and play back samples in browser (without Flash) for ~6-7 years now, they're simply making official changes to the underlying API in the hopes of improving it. "Deprecated" is just bureaucracy.
Again, I've written actual code with both. With all due respect, I'm not sure what parallel universe you're from. (Do they spell it Berenstein on your side?)
I can pull up my Github commit from 2014 and look at where I changed my moz-compatible > dynamicAudio.write(modPlayer.getSamples(bufferLength));
to
>var processor = audioContext.createScriptProcessor(bufferSize, 0, 2); > [......] >processor.connect(audioContext.destination);
etc, and it still played sound.
If you're unaware how Amiga .mod/.xm works, it is a REQUIREMENT that you can provide raw samples to the output source, because the samples are embedded into the file.
You can feed samples to the browser and have it play them, right here, right now, just like you've been able to for years. If you don't like the status of ScriptProcessor as deprecated and think AudioWorklet sucks, that's a whole separate issue, but you can feed samples now and you'll STILL be able to feed samples when AudioWorklet obsoletes ScriptProcessor.
>Web Audio was a competing API
I already mentioned it was a competing standard in my comment.
>They shipped it without a standardization process
The Audio Data API was one dude hacking on Firefox (David Humphreys) and then other people got interested. One of the requirements of the standards process is that there are multiple implementations in the wild. You need to throw it in your browser if you want it to ever be standardized.
And they DID standardize it early on. You can go read old copies of the W3C standard submitted by Google.
I was sad to see Mozilla's version go away but browser vendors eventually decided it was the losing implementation - including Mozilla.
Mozilla didn't HAVE to submit to the whims of others, they could have dug in their heels if they thought their version was better (see: The Video tag, and everyone who just so happens to be part of the MPEG-LA patent pool saying no to a patent-unencumbered, open video standard baked in to the browser)
I suppose Web Audio API is just badly named.
Although in case of "this corporate computer is air gapped", I wonder what corp policies that little project violated.
[0] Sender (highly hardware specific): https://review.coreboot.org/cgit/coreboot.git/tree/src/drive...
[1] Receiver: https://review.coreboot.org/cgit/coreboot.git/tree/util/spkm...
For others to experiment with, there is also quiet-js that is similar: https://github.com/quiet/quiet-js
Here's the live demo of it https://quiet.github.io/quiet-js
1. https://chrome.google.com/webstore/detail/google-tone/nnckeh...
The encoder (sound playback) works in Chrome and Firefox, but the decoder (microphone recording) works in Chrome but not Firefox. Also, the encoder/decoder can't handle non-ASCII text; maybe it is only grabbing the low 8 bits of each UTF-16 code unit.
Why is the computer unable to be connected to the internet?
Why are you pasting so much code from stack overflow to visual studio?
Cool implementation - should try ultrasonic...
If we actually needed to download a file (say, an open source project, or some tutorial or documentation), we'd download it there and run a command that emailed it to us. The email would arrive in Notes with the attachment stripped off for virus checking. Some time later, we'd get another email saying that the attachment had been scanned and was available in another Notes database.
It wasn't the best learning environment.
It might be useful / fun to implement a 2-wire-protocol or other IoT protocol. I'm thinking you should be able to implement up to 2-wire given the R and L channels of the headphones.
Good luck patching THAT hole.