The Programs of the Week the Taxman Cometh
This Week’s Program: Apr 11 - Apr 15
I’ve got some new subscribers (👋) and you folks will want to read last week’s entry to catch up on what I’ve been working on.
Good. This week I had every intention of getting sonic-sketches
running in a production environment. I had no idea how much eldritch
computing I would end up doing.
9fb31f700ca7fbfa0bddf7bd8acaf4cb7f92bf88
Innocuous enough. I set up the drummachine to use the core.async based
clock-signal
. Big whoop.
😖
Things took a turn here and it’s not really reflected in the code at all. There’s a commit where I fix a typo but that’s the only artifact of a bunch of work chasing down how exactly I’ll run this thing in the cloud.
I had in my head it would be neat to try out
AWS Lambda for this. This is just a
simple command-line program that generates a song and uploads it to
S3. I start digging into running Clojure on Lambda. It’s
certainly possible. I’m
not familiar at all with Lambda so it looks like you just need
yourself a -handler
function and you’re set. I read up and track
down some libraries that show off better ways of dealing with
processing AWS events in Clojure and I keep seeing people say things
along the lines of “that increased start-up time to get Clojure
running on the JVM tho” and I thought what’s the big deal? Only then
did I realize that Lambda charges based on how many milliseconds your
program runs. This is a dealbreaker because my program has to start up
Overtone and then play a song. Lambda isn’t going to work.
After that exploration (which kind of took the better part of an
afternoon), it became clear that I would need a real server to run
this on. Time to get sonic-sketches
running on Linux…
The first thing I try to do is figure out how to package my program up
in an uberjar — a big package wrapping up both my program and its
dependencies. This doesn’t work. I do a whole lot of reading about
AOT compilation in Clojure
and Lein and tweak my project.clj
in all kinds of subtle and
repetitive ways. Something about how Overtone uses native libraries to
link to SuperCollider. For those who are interested in this journey
this discussion on
overtone#140 did
manage to help out, involving compiling the uberjar without AOT and
then compiling the main class and adding that to the jar later. That
worked, but my goodness that’s convoluted. I resolved that I would
just have my source code on the box and lein trampoline run
because
that works reliably. The uberjar exploration took the better part of a
morning.
I was going to use HashiCorp’s newer Otto project to manage my development and deployment. Love those HashiCorp folks, they have so many cool tools!
Otto doesn’t have a supported “app type” for Clojure so I went with “custom” which is meant to point to a Vagrantfile. This wasn’t working until I found otto#158 which points out a schema change not reflected in the documentation.
1a03673bc453d5e57724cde6ef8aed68e8bcc3e5
Adds a major mode to my Emacs config for working with the HashiCorp Configuration Language.
607afce251df3252e9c7761fc1fc7a5beeaa5f47
Adds an Otto Appfile and Vagrantfile to the project.
Running otto dev
does not sync my project to the vagrant
directory
on the virtual machine which is what I’ve come to expect with
Vagrant. Otto does not treat the Vagrantfile as a “templatized file”
as it claims to do in the documentation. I punt on Otto and decide
I’ll just stick with Vagrant for now.
dabb87a13fb5bfcc05f3f15d117eabff95a2071f
I set up my Vagrant box to use hashicorp/precise64 because that’s what it uses in all of the documentation and I’d prefer to stay far away from anything that would push me to have an opinion about Linux distros. I have no opinion on Linux distros and I’d like to keep it that way (Arch seems prtty cool tho). I provision the box to have OpenJDK 7 (I guess Precise Pangolin doesn’t care too much for Java 8) and download lein onto the box. Cool I have a Clojure environment now.
lein run
doesn’t work in my Vagrant
environment. Unsurprising. Something about those native libs and
jack
.
😱
I then decide I’m going to try to set up my virtual machine to support audio. I thought 💭 “Heck I’m making audio I might as well ensure that I can hear the thing this machine is doing how else will I know if it works?” I don’t know why I thought this but I explored it and my god it just about did me in.
First of all I had to have Vagrant make sure that VirtualBox knew that this machine needed to support audio. After some googling and documentation reading, I found this handy bit of Vagrant configuration:
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--audio", "coreaudio", "--audiocontroller", "ac97"]
end
This allows VirtualBox to emulate a soundcard on the virtual machine and route it into Apple’s coreaudio. I think that’s what this does, at least.
Then, I start searching for ways to play a sound from within the
Vagrant machine. I read about two utilities: aplay
and
speaker-test
. Where do I get these utilities? I read on that these
are part of the alsa-utils
package. ALSA is the
Advanced Linux Sound Architecture. Apparently it’s used by
Linux to play sounds. There’s also
Open Sound System
(or OSS) and
PulseAudio. I
bring these up because when searching for “play audio on Ubuntu” all of
these topics appear and all of them are confusing and nothing makes
sense to me. All of these maybe conflict with each other (or don’t)
but all of them will do something sinister to your system that forces
you to dive into system configuration files as root to untangle. I
have no idea what I’m doing.
aplay -l
Shows that I have no sound card.
sudo aplay -l
Oh actually I do have sound cards. I have to add the vagrant user to
the audio
group. Cool. No sound plays. Oh, apparently there’s an
alsa-mixer
that controls system mixing and volume. I just need to
turn the volume up! alsa-mixer
is a curses program. I have no idea
what I’m doing. I google around and learn that even though I thought I
turned the volume up, the channels were still muted. What channels
need to be turned up and unmuted? I’m googling and googling and
googling and I have so many tabs open and I need to use the ac97
audio controller in VirtualBox and amixer
allows you to control
volume without the curses interface and finally…
fbef7f98ff4210d3c0a9a85aba9d3889478fb978
Finally I am able to play a wav file with aplay
in my Vagrant
machine that I can hear through the headphones plugged into my host
Macbook Pro.
It dawns on me now that I probably didn’t need to do that. I’m generating wav files why do I need to play them?
Also, lein run
still doesn’t work.
I guess I need to install the JACK Audio Connection Kit as mentioned in the Overtone wiki.
jackd
won’t start for a variety of reasons. Googling and trials and
errors continue.
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket
This is because jackd thinks it needs X11 to run. I have no idea what the above environment variable is doing but it does something. There’s something wrong with the “security policies in the configuration file” and adding
<policy group="audio">
<allow own="org.freedesktop.ReserveDevice1.Audio0"/>
</policy>
to the /etc/dbus-1/system.d
configs at last results in jackd
starting. I have no idea what I’m doing.
I vagrant destroy
and vagrant up
in a loop over and over because I
keep stopping daemons that shouldn’t have been stopped. I can’t
apt-get install jackd2
in my Vagrantfile provisioning because this
big curses dialog box opens up in the middle of installation asking me
something about a realtime kernel and that makes the output totally
wack.
311e6274968f0c90480bbdda7c4a47c3a7fdb00b
lein run
still doesn’t work. I create a separate Overtone project
from scratch to see what I can get to work inside a REPL.
SEVERE: Unable to load native libs c and scsynth. Please try an
external server with (use 'overtone.core)
Severe.
user=> (boot-external-server)
--> Booting external SuperCollider server...
--> Connecting to external SuperCollider server: 127.0.0.1:16931
Exception in thread "Thread-10" java.io.IOException: Cannot run
program "scsynth" (in directory "."): error=2, No such file or
directory
This is where I am now. I am determined to make this work. If you are reading this and you have experience running Overtone or SuperCollider on Linux please get at me. I am tempted to rack a Mac Mini somewhere but I’d really rather not. I want to get my program to run in a Linux environment so I can host it in the cloud to generate music. I want to make a Vagrantfile (or a Dockerfile if it comes to that) for others to use so that they can run Overtone projects in the cloud.
I have no idea what I’m doing.
I have no idea what I’m learning.
There’s some kind of moral to this story or lesson to be learned but I have no idea what that is.
🤔 Mark