Among the precursors of today's automatic systems, we have the magnificient fairground organs used to accompany fairground rides and attractions in the 19th century. Without pretending to go into something as magisterial, we didn't resist the temptation to build an automatic instrument driven by a computer, based on Yoctopuce modules, to see where the difficulties would lay. Result: it's quite easy and it's not even that long to do. Supporting evidence in a video below!
Our aim was to build a barrel organ able to play MIDI files. Let's get it right: given the available time for this project (more or less 3 days), we privileged solutions that we master. We hope that mechanical instruments aesthetes and purists will forgive us...
Building stage
An organ is not very complex. It's a set of "flutes", each one in charge of a single note, into which air must be sent when we want to play the note. To build an automatic organ, we must have a reserve of air, slightly pressurized, and a mean to automatically open the air input valve of each pipe.
A set of 22 organ pipes
For the notes, we bought a set of 22 second-hand pipes, sold on the Internet at a very friendly price. The pipes were provided with a very useful wood stand, with a hollow basis enabling us to drive air into to each pipe.
Each pipe is connected through a solenoid to the main air dispenser. As regular pressure is critical for the notes to remain stable, we added a small precision pressure regulator to the air dispenser.
Diagram of our organ
The solenoids are driven with 24V and consume about 100mA. We can therefore drive them with three Yocto-MaxiCoupler, providing a total of 24 channels. The power supply is provided by a simple second-hand 24V wall charger. Our "instrument" being too cumbersome to stand on one of our desks, we added a YoctoHub-Wireless-SR to drive it remotely through the wifi network.
The electro-pneumatic command module
In the end, it took us only one day of work to assemble the whole and make our firsts tut-tut. Just enough to realize that our first priority was to tune the pipes to prevent the end of this project to turn into a real torture...
You tune an organ pipe by changing the shape of its opening, but also by lowering pressure with small holes in the air supply circuit.
When tuning our instrument, we discovered which notes were available. Barrel organs often don't have all the notes. Ours is no exception, there was only a major scale (i.e. the white keys of the piano), and even with a missing note in the middle. This adds a little twist to the project...
The finished organ, ready for its first performance
The command software
To play a note, you activate the corresponding solenoid for the duration of the note. The Yoctopuce library used to drive the Yocto-MaxiCoupler provides the Relay class to do this with a pulse(duration_in_milliseconds method. To know which pipe to play, we assigned each output of the Yocto-MaxiCoupler a logical name corresponding to the relative note it plays: the lower pipe is called tune00, the one two semitones higher tune02, and so on.
Here is how to play a major scale on our organ, in C++:
string errmsg;
YAPI::RegisterHub("192.168.1.71", errmsg);
//We use a YRelay object to drive each note
const char *tunes[8] = {"00","02","04","05","07","09","11","12"};
YRelay *notes[8];
for(int i = 0; i < 8; i++) {
notes[i] = YRelay::FindRelay("tune"+string(tunes[i]));
}
// we play a scale (each note for 500ms)
for(int i = 0; i < 8; i++) {
notes[i]->pulse(500); // the relay closes the valve after 500ms
YAPI::Sleep(500,errmsg); // we wait until the end of the note before
// playing the next one
}
It's not too bad, but playing each note one after the other, with a delay between each one is not ideal. If we want to play a chord, all the notes must start at the exact same time. So we are going to use a more subtle function, which programs a delayed pulse delayedPusle(delay,duration). Here is the new code which plays the scale:
for(int i = 0; i < 8; i++) {
notes[i]->delayedPulse(i*500, 500);
}
// The program has run, but the scale goes on...
Last refinement: we cannot program a pulse when another pulse is happening on the same relay. So we must in fact combine the two approaches: if the relay is idle, we use a delayedPulse and we go directly to the next note. Otherwise, we do a YAPI::Sleep to wait until the relay has finished its pulse, and we pre-program the next note on the same relay as soon as the pulse is over.
This is all you needed to know about the Yoctopuce library to automate our organ. The rest is only a question of music and MIDI files.
The MIDI reader
If for each note to be played we had to code by hand a call to delayedPulse, we wouldn't have gone far with this project. So we added to our program the possibility to read a piece to be played in the MIDI format. There are thousands of examples on Internet. To save time, we used the Midifile library written by Craig Stuart Sapp.
When the note sequence is stored, you need to assign each note an organ pipe. But as our instrument doesn't have all the notes, we had to code an automatic "arranger" that replaces missing notes by others which sound almost the same. Our arranger uses two methods: transposition (shifting the whole piece higher or lower) to minimize the number of missing notes, and harmonic substitution (replacing a note with another one sharing a maximum of common harmonics). If you want the details, ask us all you want or have a look at the source code...
Here is the result on Mozart's "Alla Turca", which ended our second day of work on this project:
Even further
It is obviously tempting to try all kinds of pieces on this instrument. We soon realized that they don't all sound good. Indeed, many pieces have orchestral harmonization with many instruments in parallel, which cannot be reduced on a so small instrument. Therefore, we added in our software a list of the distinct voices present in the MIDI file, with the possibility to deactivate them. At the same time, we automatically deactivated the percussion voice. We would have loved to add a pneumatic tambourine, but we simply didn't have time...
Sometimes, it's also possible to better the orchestral rendering by automatically shortening the notes depending on their MIDI volume. This enables us to make more discreet the accompanying lines, which tend to cover the melody as all the pipes play with the same force.
If you want to reproduce this experiment, you can find our software source code on GitHub.
To end in music, here's a little potpourri illustrating our realization: