These videos show the system in action, complete with the visualisation generated by the control software.
Here's the current system, with 8 drives:
Older videos (2 floppy drives)
More videos can be found in this playlist: https://www.youtube.com/playlist?list=PLVN9s9mCy-V2a_03OcOd3xxcG50dWm-ed
I plan to record more soon!
Click "read more" for details on how it works.
Main control software:
All instruments are controlled via a central Java program. This program was by far what took the most effort in this project, as it has to parse MIDI files, make adjustments through an interface, and send instructions to the various instruments to play their parts while providing a synthesia-style music visualisation in real time. There are many features in place to make use of it's limited number of instruments to make the song sound as good as possible.
The interface, as shown in the picture, lets the user load up a MIDI file and view it. On the top left, each MIDI track/channel can be mapped to an instrument (for example only HDD A) or group of instruments (for example any floppy drive). Multiple tracks/channels can be mapped to instruments or groups, and the software will manage this according to a priority system, explained a bit later.
A slight problem with this orchestra is that each instrument can only play 1 note at a time, with the exception of the 3D printer which can play 3 simultaneously (one per axis). Most MIDI files will have more than one note playing at once per channel, like when playing chords, so the software provides ways to cut down the amount of notes. Options like "latest" will, when given new notes to play, sacrifice the oldest note being "held" to play the latest one instead. "max 2" will play the current highest and lowest note, "max 1" will play the center note of any set of notes that need to be played, and "max 3" is a combination of max 1 and 2.
When assigning multiple notes to a single instrument, you may also hit the limit of notes for that instrument. To prevent the song from sounding bad, there is also a priority system. channels with a "high" priority are important notes, usually the main melody, that must be played, while "medium" and "low" can be left out if it isn't possible to play them.
While mapping and editing the song, the "regen" button can be pressed to see what the song would looks like with the currently selected changes and what notes would be left out, so you can make sure the important parts of the song are still there. And of course, you can also play the song from the interface.
3D printer control:
Before I started this project, there were scripts like MIDI2CNC that converted MIDI files to instructions 3D printers could use to play music. However, there was one major flaw with that system: "stop" is literally not in a 3D printer's dictionary, or at least, "stop for X milliseconds" or similar.
This meant that whenever there was a part in the song where there were no notes played, it would just flat out skip to when the next note was to be played. This made the song sound bad, and syncing it up with other instruments impossible.
The solution was to make my control software act as the 3D printer control software as well. It runs in "ping pong" mode, only giving instructions once it's done (because we don't want to rush ahead in the song). When a pause happens, or rather when the printer doesn't need to be sent any notes, the control program simply refuses to give the printer the next command, forcing the printer to stay still and do nothing until it's meant to play the note.
Notes are of course played by making the printer move to positions at certain speeds in such a way that in order to move there at that speed, the printer's stepper motors would each need to step at a specific frequency. The frequency of each axis is set to match the frequency of the notes it needs to play, and you have music. The floppy drives work on a similar principle, but a lot simpler.
Floppy and percussion control:
The printer has a little control board that accepts commands from the PC and will take care of moving the steppers, which I then exploit to make music. Unfortunately, controlling the floppy and HDDs is not as simple. Of course I can't wire them to my PCs motherboard and control it like that, no sane OS would let me control the speed, and definitely not let me slam the write head into the side of the drive! That's what my little control board is for.
I used a Fubarino which I won in an earlier Hackaday contest. It accepts commands through Serial and takes care of running the floppy drives at a certain frequencies so the controller program doesn't need to micromanage the drives.
Floppy drives are incredibly easy to control. Only 3 control pins are really needed to move the drive: enable (which turns on the light), direction (which controls which way the head will move), and step (which moves the stepper 1 step on a pulse). The Fubarino simply steps the drives when needed, occasionally reversing the direction when it reaches the end. The only modification done to the drives was the removal of the top metal plate, to allow for better sound.
HDDs as percussion aren't as easy to control, as they have a complicated controller that again, would never allow me to slam the read head into the side of the drive to make a drum-like sound. So I just tore those off, and replaced all that complicated control logic with a single transistor driving the coil that moves the head, and mounted it on a breadboard.
The Fubarino accepts commands from the main control program over Serial. The protocol was designed to be very fast and low-latency, with percussion instruments taking only 1 byte and changing the note on a floppy drive taking up to 4 bytes. I could post the details of the protocol, but it's nothing too interesting.
The control software also tries to lessen the amount of commands it needs to send for floppies by checking if there aren't already floppy drives playing the necessary notes based off of what it has already transmitted, and lets those drives continue playing those notes, changing as little floppy drives as possible for faster response time.