Tuesday, November 29, 2016

DJ Hard Drive Turn Table Part 3 - Playing Audio

So now the turn table is writing output to the serial connection off of the Arduino. This is very good. But what good is it if we can't play audio with it? That's what this part is all about: translating the signals from the turntable into audio modulations that we can hear. In this case, we're speeding up and slowing down a audio track. Let's get started!

This code works for Linux. I imagine with the proper configuration you can make it run on Windows, but I could not get the code to compile on Bash for Ubuntu for Windows and I didn't feel like porting it all the way over to native Windows. So I just went ahead and fired up a Ubuntu VM.

This was actually a really interesting step in the setup process. How can I pass the Arduino data through to the Ubuntu VM? This was actually really easy. Once I figured out which serial port my Windows Host had assigned to the Arduino, it was only a matter of making VirtualBox forward the data.


Now that that was all set up and good to go, I started the VM and typed in cat /dev/ttyS0 and spun the platter. I was able to get the 1s and 2s on the screen without having to specify the baud rate or anything like that. It just kinda figured it out all by itself. Great!

So, next, I looked for some sound libraries. I found OpenAL which seems to be the goto for audio programing in C. So I installed the needed libraries (don't forget libalut-dev!) and found an example online that simply played a WAV file. I started from the example found here. Most of the audio logic is from that wonderful example and I'm not sure if I could have done it without it. I just cleaned it up to match my code style and added the speed modifier. It compiled and played the file. Good. So the next step was to add logic that controlled the speed based on the frequency of ticks received from the serial device. This was just a matter of doing a non-blocking read from the serial device.

Basically, every time we get a tick, we find the time since the last tick and set the speed to be inversely proportional to that gap. In the time we don't get a tick, we try to get back to a center speed of 1 by steps of "reflex". The higher the reflex, the faster the speed will return to 1. Mine is so low because I wanted to reduce the inherent jitter that comes with this method. I may put some effort into interpolation to make it smoother for the next episode.

Anyway, here's the code to make it happen. It comes with the makefile because you need to make sure you link to the audio, thread, and math libraries. Make sure the serial device is correct. Yours might not be /dev/ttyS0 especially if you're not in a VM. It might even be a ttyUSB device. Who knows.

And here's a video of it working! One direction goes faster and one direction goes slower. Next episode I'll either make the motor spin by itself (which will make sense when I make the backwards direction actually reverse the track) or package everything up into a nice little unit. But until then, enjoy this very short demo:


No comments:

Post a Comment