38

My degree was in audio engineering, but I'm fairly new to programming. I'd like to learn how to work with audio in a programming environment, partly so I can learn C++ better through interesting projects.

First off, is C++ the right language for this? Is there any reason I shouldn't be using it? I've heard of Soundfile and some other libraries - what would you recommend?

Finally, does anyone know of any good tutorials in this subject? I've learnt the basics of DSP - I just want to program it!

EDIT: I use Windows. I'd like to play about with real-time stuff, a bit like Max/MSP but with more control.

Skilldrick
  • 69,215
  • 34
  • 177
  • 229
  • To add to Neil's question - we presume you want to listen to the audio, and not just read/write files. Any solutions will be operating system specific. – Mark Ransom Apr 02 '09 at 20:05
  • If you're going to start with C++, I'd recommend openFrameworks.cc as it cushions the hard edges of C++ a bit while still letting you write in the language. – buildsucceeded Jul 15 '11 at 14:26
  • Minimal C audio Canon music synthesis example: https://stackoverflow.com/questions/2205070/programmatically-synthesizing-programming-music/52126471#52126471 – Ciro Santilli OurBigBook.com Sep 01 '18 at 09:26

16 Answers16

18

If you do decide to use C++, then The Synthesis Toolkit is worth noting. I use it for a schoolproject and it is very usable, developed at stanford university, crossplatform (win, mac and linux), free and opensource. An extract from the wikipedia page on it:

Versions of the STK instrument classes have been integrated into ChucK, Csound, Real-Time Cmix, Max/MSP (as part of PeRColate) and SuperCollider

They have a lot of testcode included + on the site are some tutorials to get started with their library. (But you do have to know some C++ of course)

STK has some classed to read/write audio files (and matlab files), realtime audio/midi io, some basic algorithms (usage based on similar functions out of matlab), ...


Another obvious option and probably THE most used environment to learn/test dsp stuff is Matlab (or free octave, but i havent used it before). I sometimes test stuff out in Matlab before implementing it in C++.


EDIT: In the past year I've been using JUCE which is a pretty cool C++ library centered around C++ audio programming, though its more leaning towards something like QT. One of their developers (Timur Doumler) has a nice talk about real time audio with C++ and JUCE on CppCon 2015, definitely worth checking out, even if you don't end up using JUCE: https://youtu.be/boPEO2auJj4

Another resource that might be interesting is the audio section of the awesome cpp github readme which contains a number of libraries related to audio

Emile Vrijdags
  • 1,550
  • 2
  • 15
  • 24
  • 2
    Matlab was my first experience of coding! I probably wouldn't be here now (on Stack Overflow that is!) if I hadn't been taught DSP in Matlab at Uni. I've still got an old copy - maybe I should play about with that first... good idea. – Skilldrick Apr 05 '09 at 20:53
  • I was a heavy Matlab user at work. I've been working on an Nsound library in C++ that's kinda matlab-like: https://www.youtube.com/watch?v=j4uLvl68PtI – Nick Nov 27 '14 at 20:02
16

It really depends on what kind of audio work you want to do, If you want to implement audio for a game, C++ is sure the right language. There are many libraries around, OpenAL is great, free and multiplatform. I also used DirectSound and Fmod with great sucess. Check them out, it all depends on your needs.

MissT
  • 780
  • 6
  • 14
  • 1
    The waveOutWrite win32 API is easier to work with than DirectSound in my experience, even when DirectSound is more powerful. (Also, DirectSound has been superseded by XACT, AFAIK). – Jasper Bekkers Apr 05 '09 at 17:35
  • 2
    Unfortunately unlike OpenGL, OpenAL is not really an open standard as it proprietary software maintained by Creative. It is also kind of meant for 3d computer games, what with its Listener, Sources and Buffers model (and distances, velocities). I'd say if you really want to get down to the core you should use the API of the operating system that you're working on (e.g. win32 API for Windows, CoreAudio API for OSX, not really sure about Linux). – rwols Jan 10 '13 at 12:32
10

Is C++ the right language? That depends entirely on the context. If you need to plug your code into another application, framework or whatever else, you probably have to use whatever language that framework is made for.

If you're making your own free-standing app? Probably not. There are several reasons why I'd suggest you go with another language:

  • C++ isn't well suited for beginners. If your goal is to learn programming through these projects, go with a language that is more amenable to "learning by doing". C++ is full of pitfalls and things that "seem to work", until one day they don't. Add to this a horribly complex syntax and some pretty complex idioms and techniques you have to master to work around quirks of the language that simply are non-issues in pretty much any other language, and you have a good source of bugs and frustrations, and not much more.
  • C++ has no concept of "audio". C++ doesn't come with any kind of support for recording, processing or playing audio, loading or saving audio files or anything else. Most modern languages have some form of audio support built into the standard language (at least the ability to load and play mp3 files and other such basics). In C++, all of this will have to be done through third-party libraries and OS-specific code.

If you have a real choice in language, I'd say go for something like Python or C#. They're easier to learn, come with a lot more functionality out of the box, and make it a lot harder to shoot yourself in the foot. I wouldn't recommend C++ to someone who isn't already an experienced programmer.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • 6
    Just remember that audio-processing is a generally realtime process in which you have to preform complicated (FFT) calculations in an order of milliseconds because you need to queue up the audio. If you're too late you'll hear noticeable artifacts. – Jasper Bekkers Apr 05 '09 at 17:41
5

Check out Audacity. It is a cross-platform (Linux, OS X, and Windows) open-source audio editor written in C++. I don't know what level your GUI skills are at, but the code that deals with audio work should be fairly easy to distinguish from the wxWidgets (GUI) code.

Chris Lutz
  • 73,191
  • 16
  • 130
  • 183
4

Lots of good suggestions in here. In addition I'd suggest looking at the Jack Audio Toolkit, the JUCE framework, and learn how to port the C code from synthesis libraries like Csound. The "Audio Programming Book" is good too for that.

Re C vs C++, I think you'll find that in audio work, the C++ part is often really just chrome for code management. The DSP bits are all low level procedural math on signals, so it's likely to be C calls and it really doesn't matter for that side of things whether you use C or C++. A lot of C++ audio projects are essentially just C in the audio guts.

hth!

Iain Duncan
  • 1,738
  • 16
  • 17
3

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.

sness
  • 456
  • 4
  • 4
  • 1
    The current links for the website and documentation are http://marsyas.info and http://marsyas.info/doc/ – Pascal Jul 12 '18 at 15:45
2

C might be a better choice than C++ for audio, particularly if you want to do any DSP.

  • Most practical audio and DSP reference books use C for code examples
  • Most audio/DSP libraries are written in C (or at least have a C API)
  • C++ greatly increases the learning curve compared to C but doesn't add a lot of benefit for audio/DSP work (OOP is not particularly relevant for low-level/real-time code)

There's nothing "wrong" with learning C++ of course and it won't stop you understanding and using C code (since C++ is mostly a superset of C) - it's just that you'll be up and running a lot quicker with C, and you can always move on to C++ later if you decide to.

Paul R
  • 208,748
  • 37
  • 389
  • 560
2

To answer your second question, you should check out this book: Designing Audio Effect Plug-Ins in C++: With Digital Audio Signal Processing Theory by Will Pirkle.

The book goes through some basic DSP and walks you through how to make audio plugins. You'll code in C++ but it won't be hard because the book suggest you download a framework, RACKAFX, which handles all GUI events. All you'll have to do is focus on writing the formulas and storing the data in the right channels.

Good luck!

ThePhantom05
  • 139
  • 1
  • 1
  • 11
1

If you already have some DSP knowledge, these tutorials show how to turn DSP code into a finished program, including GUI controls. It starts with a simple distortion and then moves on to synthesis etc.
Basically you write code that can be built either as a standalone .exe or as a VST plugin for hosts like Cubase or Ableton Live.

basteln
  • 2,483
  • 2
  • 19
  • 20
1

Dont listen to me! I might be wrong!

I do not program C++, but agree with Jalf in it being difficult for beginners, there are lots of things that have to be done manually that other languages will do for you automatically, such as memory allocation, garbage collection etc. they are also right in saying that C++ does not know audio, and that other languages have audio capabilities built in from scratch. However, generally, most of these are fairly basic capabilties: opening and playing files, sending the playhead to different parts of the file, adjust panning and volume, maybe extracting eq data.

But...Im guessing that you want to get a little deeper and actually shape the sound, whether through synthesis or effects, and that you want to make these things instead of just add them. I would encourage you to look at VST and VSTi, but this is c++ area (JUCE library, awesome awesome awesome), and hard hard work, but if you want to make your own product, then it might be the way. otherwise, as others have suggested CSound, Max, Cycling, and maybe Processing might be of interest. software like Reaktor allow you to patch together modular componenets with a lot less (if any) coding.

go and have a look at some of the forums on KVRAudio, there are a few heroes there who developed old classic freeware like Hammerhead, and then other indie software like Fruity Loops, Rebirth, Tuareg, Audiomulch etc.

I think learning about VST and C++ is the best, but it will be a long road with pain and anguish, and unless you wish to create a stand alone piece of software or a plugin for another piece of software (apart from Csound etc), it will be dissapointing.

I think.

Assembler
  • 794
  • 1
  • 8
  • 24
0

Depending on your needs, maybe R is a easier language. I'm using it for one year now, it does statistical analysis, graphs, maps and sound analysis too. With png, tuneR and seewave libraries you need one line to read a .wav, other to get the matrix of data, and other to put it into a png image or see it on screen. The points of being designed to analyze data and being easier to use are two advantages for me. For instance, R numbers tables and arrays starting from 1, not 0 like most programming languages. It makes our human brain much more comfortable with the already complicated scripts. I think you should take a look at it: http://www.r-project.org/

Good luck!

Community
  • 1
  • 1
Rodrigo
  • 4,706
  • 6
  • 51
  • 94
0

If you already learnt the basics of DSP, I would recommend Analog Devices Blackfin Processors. You can use both C and C++, and they provide a number of Audio examples to get you started. They supply enough code to read audio into the board, process it, and play it back out.

From this you can apply any types of filters or other processing you wish. I used the BF533 Ez-Kit Lite in combination with a serial LCD Panel to make an Audio Equalizer for a project once. Was a great learning experience and a lot of fun!

Sean
  • 2,453
  • 6
  • 41
  • 53
0

I don't have all that much experience in creating audio apps for myself - but if I was in your position I'd play around with creating VSTi's first (virtual studio technology instrument). As far as I know, Steinberg have released a C++ SDK for this and I reckon it would be a good starting point if you'd like to get into sound design applications

Ciaran
  • 1,878
  • 5
  • 18
  • 31
0

If you want to focus on the actual sound processing (as opposed to all the crud that GUI applications are saddled with), I'd check out CSound. That gives you a textfile based langugae that allows you to build almost any audio device virtually from what they call opcodes, but also you have the source code which you can delve into to see the actual algorithms that the opcodes represent.

U62
  • 4,355
  • 1
  • 24
  • 37
-1

On windows look up tutorials on DirectSound.

On Linux there are a variety of libraries and methods to access sound cards, the easiest of which is simply open a file to the device, and use ioctrl to set the speed, etc.

If you give more information on the environment, we might have better recommendations.

-Adam

Adam Davis
  • 91,931
  • 60
  • 264
  • 330
-2

You can use a .wav file using some command.

That command is PlaySound("C:\\SOUNDS\\example.WAV", NULL, SND_ASYNC);

Tristan
  • 3,301
  • 8
  • 22
  • 27