server-side tone synth with node

I thought I’d work on another Raspberry Pi 3 project and this time was looking to expand my repertoire for server-side audio.  I suppose I was imagining an application in which you’d carry the Pi along with you using a USB-based power bank and plugging in your headphones, controlling the interface via your cellphone’s browser, let’s say.

Platform

Logically then this would need to be a Node.js—based webserver which could synthesize a sine wave tone with a specified frequency on both left/right audio outputs on the server itself (rather than streaming it back to the client browser).  I chose the Raspian image for the microSD card because, as a Debian modification, it’s likely the closest to the standard Ubuntu flavor of Linux which I work with the most.

Open Source

Searching the npm space I found nothing useful, to be honest. It’s rare when the open source world fails to deliver but this was one of those times. I was going to need to innovate on this one. There are many repositories out there which use the browser’s window object but that just wasn’t available here on the server. I installed module after module only to find that one of its dependencies relied upon that same pesky window object. So each time, I had to perform another npm remove --save whatever from my project to return things back to “square one”.

This research took a little longer than I’d hoped for but it turns out that Raspian out-of-box includes the Open Sound System (OSS) aspi-utils collection and its speaker-test program can be used in a terminal to generate tones from both speakers. Okay, so now how do you run terminal programs from JavaScript?

Starting External Programs From Node

It turns out that Node has an internal module called child_process which allows you to spawn (run) something you might normally invoke from the command line. It took some reading but I was able to navigate the documentation and to start a speaker-test session with the necessary arguments. One task down, (one to go).

Stopping External Programs From Node

Fortunately, Node also has an internal module process with a kill command to stop a running process.

Implementation

It takes a bit of state management: the webserver needs to remember if you’ve started a process, what its process ID is and whether or not you’ve now stopped it. A proper open source project would support systems other than Linux but this is the starting point and this wouldn’t work, say, with a Windows-based computer using the PowerShell module control, for example.

Since this wasn’t an exercise in UX design the interface couldn’t really be any simpler. It’s your basic Express-generated website with the Pug view engine and a simple pull-down list for selecting some preset frequencies. Submitting your tone choice POSTs back to the same index page; selecting the Stop button POSTs to a virtually-routed /stop routine which then redirects back to the original index page.

Source Code

Check it out if you’re curious. I’ll likely be using this same technique to create a more self-contained module for managing external programs.

github.com/OutsourcedGuru/heal

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s