C++ can be a great language to do audio processing in, I use the Marsyas framework, a cross-platform package that lets you do complicated tasks in audio signal processing, music information retrieval and machine learning really easily. It's also really fast, and you can do lots of complicated tasks in real time, unlike many other packages. In tests we've run, Marsyas can be hundreds of times faster than Matlab.
To get you started, here's some code. Let's say you wanted to play an audio file, for this, you'd create a network in Marsyas that looks like:
- Series
- SoundFileSource
- Gain
- AudioSink
Marsyas uses an implict patching model, which is kind of like the explicit patching that you see in Max/MSP, but you don't have to draw wires between objects, you just put them in containers, and the wires are created automatically. The Series object above holds a SoundFileSource, which you feed an audio file, then passes it to a Gain, which allows you to change the volume of the audio, and then feeds it into an AudioSink, which plays the audio file on your speakers.
The C++ to create this network is dead simple:
MarSystem* playbacknet = mng.create("Series", "playbacknet");
playbacknet->addMarSystem(mng.create("SoundFileSource", "src"));
playbacknet->addMarSystem(mng.create("Gain", "gt"));
playbacknet->addMarSystem(mng.create("AudioSink", "dest"));
// Set the SoundFileName
playbacknet->updctrl("SoundFileSource/src/mrs_string/filename",inAudioFileName);
// Turn on the audio output
playbacknet->updctrl("AudioSink/dest/mrs_bool/initAudio", true);
while (playbacknet->getctrl("SoundFileSource/src/mrs_bool/notEmpty")->isTrue()) {
playbacknet->tick();
}
The first four lines create the MarSystem that processes your audio. The Series object, which contains everything else, is created first, and then the SoundFileSource, Gain and AudioSink are added to it.
The next line sets the filename of the SoundFileSource, you would give it the name of the .wav, .au, .aiff or .mp3 file that you wanted to process here.
You then turn on the AudioSource, which tells your sound card to start playing sound by updating the "initAudio" control of the AudioSource. The while loop then loops as long as the SoundFileSource has audio data.
You can see that this simple example is really easy to do, but the real power of Marsyas is when you want to do more complicated tasks. For example, to do an FFT, you would just do:
MarSystem* net = mng.create("Series", "net");
net->addMarSystem(mng.create("SoundFileSource", "src"));
net->addMarSystem(mng.create("Spectrum", "spectrum"));
net->addMarSystem(mng.create("PowerSpectrum", "powerspectrum"));
while (playbacknet->getctrl("SoundFileSource/src/mrs_bool/notEmpty")->isTrue()) {
cout << net->getctrl("mrs_realvec/processedData")->to<mrs_realvec>() << endl;
}
To estimate the fundamental frequency of an audio source you would do something like:
MarSystem* net = mng.create("Series", "series");
net->addMarSystem(mng.create("AudioSource", "src"));
net->addMarSystem(mng.create("AubioYin", "yin"));
while (playbacknet->getctrl("SoundFileSource/src/mrs_bool/notEmpty")->isTrue()) {
cout << net->getctrl("mrs_realvec/processedData")->to<mrs_realvec>() << endl;
}
This last one will read in audio in realtime from your soundcard and will run the powerful YIN pitch detection algorithm on it. Sweet, eh?
For lots more code, check out the Marsyas website, especially check out the documentation.