Research done by:
Judy Franklin & Veronica Morales
CMIX is a package of sound-processing, synthesizing, modification and mixing programs that can be used to manipulate pre-recorded sound or create any sound. RTcmix adds real-time capabilities to CMIX, in addition to the ability of reading sound data through TCP sockets as well as a scorefile. It is also written in C++ and takes advantage of the object-oriented paradigm. With RTcmix, output can be sent directly to speakers, unlike CMIX which needed the output saved to a sound file first (this is optional in RTcmix). It can do this because it incorparates a scheduler that dynamically calls the RTcmix instruments.
Installation is straight-foward with a thorough INSTALL file located in the root level folder. The most important item is to make sure that makefile.conf is pointing to the right directory. Also, some compiler errors may occur, depending on which compiler you are using. For our compiler, some C files needed the addition of stdlib.h for proper compilation. For more info on installation look here.
When downloading, be sure to grab the three available packages: insts.jg-3.0.5.tar.gz, insts.mch-3.0.5.tar.gz, and insts.std-3.0.5.tar.gz. Here you will find all the instruments. The RTcmix-3.0.5.tar.gz only comes with 3 basic instruments.
Lastly, most of the material on RTcmix refers the user to an instrument TEMPLATE, for those wanting to create their own instruments. This is found in the docs/sample_code/ folder.
For a complete write-up on RTcmix, visit:
Computer Music Center, Columbia University,
or, for information on CMIX
The CMIX home page
We touched on many aspects of RTcmix. For one, we wanted to install and use the package to experience music synthesis/effects processing on the Linux operating system. We also wanted to get to know RTcmix and use the real-time and sockets options in the creation of an instrument that could generate a bass line given chord information.
We began our work by exploring the interfaces (RTcmix2.0.interfaces.tar.gz package) written for RTcmix. The interfaces use network sockets to send commands to CMIX. They are written in C and use an RTcmix API to communicate with CMIX. Other information on interfaces include:
cmix -c -n -i
c: real time control enabled
n: no init script
i: interactive mode (tells rt to become multithreaded w/separate socket parsing and scheduling threads)
After working with the interfaces package, we explored MIC input to an instrument. The README files state that all that is necessary to receive input from a microphone is to include a call to rtinput("AUDIO") in the scorefile. In our system we found that this did not suffice. An additional call to set_option("full_duplex_on") before the call to rtsetparams(44100, 1) was necessary. This call sets up the proper flags for rtsetparams to open the audio ports. The resulting score file looks like this:
makegen(1, 24, 1000, 0,0, 2,1, 5,1, 7,0)
makegen(2, 10, 1000, 1)
AM(0, 0, 30, 1, 14)
AM(8, 0, 30, 10, 187)
AM(16, 0, 30, 1, 280)
Satisfied that RTcmix worked well in our system, we proceeded with instrument creation. We decided that we wanted to use the STRUM instrument to generate the bass line sound. Here we learned how STRUM creates its sound. Among other functions, it uses a function called randfill.c that generates frequency numbers to reuse with the rest of the strum functions. This function is called everytime START ( a STRUM sub instrument) is called and uses a random number generator for the numbers. The result is that when you pass START a pitch to be played more that once, the pitches do not sound the same. For our purposes, we needed same pitches to have the same sound no matter how many times we called START. To fix this, we created filefill.c and modified randfill.c, START.C and START.h .
We gave START.C an optional argument. The flag tells START.C if it is the first time it is being called in this scorefile. If it is, then START.C calls randfill.c to generate the numbers and save them to a file. If it is not, then it calls filefill.c to read the numbers from the file (assumed local). This fix works well, making STRUM create the pitch equally each time it is called.
The scorefile, which reads chords from a file and plays them along with the bass line, can be seen here. It makes use of 3 Minc functions we created: getchordinfo.c, getdur.c, and getpitch.c which are responsible for retrieving the chords from the file and breaking them up for their information, i.e. duration, pitch. The chord information is stored in an array of struct chords declared in ugens.h, which can be accessed externally.
Play a sound file created with this instrument.
With this problem out of the way, our next task was to make STRUM an instrument that can take input from the microphone. The following constructs are general for all instruments that take input from MIC:
The first argument is the inskip which needs to be 0 for input from a microphone.
In function "run", add the following:
in = new float[RTBUTSAMPS * inputchans];
With these changes to STRUM, samples of input from the MIC are now stored in the "in" array and can be used in any way.
The next step was to develop an instrument that would create the bass line given certain arguments, instead of having the bass line created in the score file as above. The instrument, BASSLINE.C & BASSLINE.h, receives as input the start time, index number of the current chord to play a bass line to, and the tempo. The instrument handles the timing depending on the chord duration accessed from the array of struct chords. A sample score file that plays this instrument is here.
Play a sound file created with this instrument.
Once START.C was able to take input from the microphone, and we had an instrument that produced a bass line, we worked on integrating the Fast Fourier Transform function provided with RTcmix into this instrument. The fft works within a function called hist.c that can be used on the command line. It takes a sound file as a command line parameter and provides information on it. Our interest was in pinpointing the fundamental frequency of a pitch passed in through the microphone so that we may dynamically adjust the bass line to whatever pitch was played through the input.
We first created an instrument that implemented the fft algorithm on some input. The input was provided by a midi keyboard plugged into the computer's MIC jack (we tried the line jack but that did not appear to function properly). The Fast Fourier Transform parts of hist.c were pulled out and used in the instrument FFTINST.C & FFTINST.h. It takes your basic instrument input, i.e. outskip, inskip, duration, amplitude, in channels (optional) and stereo spread (optional), but rather than creating a sound or some effect, it simply takes the keyboard input and runs it through the fft algorithm, separating the frequencies and sending to stdout the fundamental and some partial frequencies. The fundamental is not always precise, but it gets very close ( < 10 Hz difference).
The final step was to combine FFTINST and BASSLINE so that the bass line creation be dependent on the pitch received through input from the keyboard. The instrument, FFTBASS.C & FFTBASS.h, uses all of the FFTINST code since it is important to have the right number of samples to feed to the fft algorithm and FFTINST accomplishes this well. The timing of FFTBASS however is off in terms of when the pitches in the bass line are played. The instrument computes the number of pitches needed in the bass line, according to whether we have a whole or half chord. However, the timing of these pitches is off, meaning that the issue of tempo is not well addressed.