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