Embassy of Time

Really micromanaged audio programming (C++)

Recommended Posts

I have been looking at audio libraries for my game development in C++/OpenGL for a while now, but nothing truly grabs me. OpenAL is a good contender, but it seems flooded with weird special-purpose functions that just bloat the final file size. Either I need to pick it apart and pick and choose functions, or I need something more low-level.

What I basically need is something for generating and playing sound files, not importing existing ones (if it can do both, no problem, but...). I can do the math for a sine wave, for example, but I have no way of making the computer play it as a sound. Other sounds are generated in similar ways, but playing them AS sounds is still not happening. I would love some efficient innate function (Windows platform), or a very streamlined library for that purpose only. Any suggestions??

Share this post


Link to post
Share on other sites

SDL2 weighs only half a meg and has a pretty simple audio layer. DirectX is also the right tool for the job if Windows is the only platform you're interested in... though I haven't worked with its audio side since DX9, don't know what the DX12 interface looks like.

Share this post


Link to post
Share on other sites
On 12/9/2017 at 3:46 PM, Shaarigan said:

Write it yourself using the Waveform API or the newer WASAPI functions. I have done this for testing purposes some time ago and it works just by putting binary data into the channels

But how can I edit the data in the sound? Remember, I am not just uploading sound files, I am generating the sounds on the fly...

On 12/9/2017 at 7:47 PM, Wyrframe said:

SDL2 weighs only half a meg and has a pretty simple audio layer. DirectX is also the right tool for the job if Windows is the only platform you're interested in... though I haven't worked with its audio side since DX9, don't know what the DX12 interface looks like.

It's designed to eventually be multi-platform (I do the visuals entirely in OpenGL, for one), but some pieces will inevitably need platform adjustment. If the audio code is small and streamlined enough, no problem. Is there a good tutorial (or many) for SDL2??

Share this post


Link to post
Share on other sites

If you have had a look onto Waveform API or WASAPI you should have seen the WAVEHDR struct passed into the audio output channel. This struct contains a data pointer to certain raw wave data in memory and some other stuff. So where is the problem to create your data stream and pass it to the Wavefront API or WASAPI?

Share this post


Link to post
Share on other sites

You could obtain was header and then put data after it closing it into some class note that sound is much more than array of shorts one positive another negative then again positive then negative etc.

If you use Windows only then direct supports playing a set of bytes, or ask should support that too bass library supports that too anyway you need to sample data right etc.

Share this post


Link to post
Share on other sites

There are various APIs to simplify making sounds play etc but if you want *low level*, then most platforms offer the following scheme:

1) You get from the API some access to a primary sound output buffer (which may again be mixed with other stuff by the OS but you don't need to worry about this). In the case of e.g. a typical 16 bit stereo 44.1khz this might be a sequence of 'tiles' of memory which will be played in order, when it gets to the end it loops back and starts from the first tile again.

2) Your entire job for making audio would then to be to keep this sequence of tiles filled with audio data to play. Most APIs have something like a callback to tell you when need to fill a tile, as it can happen at any time, not just when your game thread is active - if you don't fill a tile on time you will get audio corruption and glitches.

As to what sound you want to play into these looping tiles it is up to you. It could be prerecorded music etc. In the usual case of sound effects for a game, you would make your own list of sounds that are currently playing, how far they are through, etc, and copy the relevant sound data across to the primary buffer when required. You can also add audio effects, reverb, delay, chorus etc depending on your audio chops.

Note that the size of each tile will determine the latency, smaller tiles there will be less gap between playing a sound in your game and it 'appearing' in the sound output, but means there will be more calls to the callback and more 'housekeeping' code. Having a larger overall primary buffer will mean less chance of starving the tiles and audio glitches.

If all this sounds complex, then that is what the various sound 'engine' APIs offer you, perhaps a bit less control but it does all this stuff for you. If you understand how audio works though it is pretty simple stuff (I personally haven't done 3d sound or doppler and a few things like that though), and it makes porting to a different platform a doddle.

Share this post


Link to post
Share on other sites

DirectSound is what you are looking for. Its fully lowlevel and you can create/modify your sound samples however you want.

But you have to mix and video-syncronize yourself - compensate for bad latency. Also there are not much tutorials out there, the only thing i know is this (which is quite good):

https://www.youtube.com/watch?v=UuqcgQxpfO8&list=PLEMXAbCVnmY4UakJTODzmY-6rSPKkuLr5

Share this post


Link to post
Share on other sites
40 minutes ago, Finalspace said:

DirectSound is what you are looking for. Its fully lowlevel and you can create/modify your sound samples however you want.

But you have to mix and video-syncronize yourself - compensate for bad latency. Also there are not much tutorials out there, the only thing i know is this (which is quite good):

https://www.youtube.com/watch?v=UuqcgQxpfO8&list=PLEMXAbCVnmY4UakJTODzmY-6rSPKkuLr5

DirectSound was also essentially deprecated as of 2011 and modern OSs may not support all of its features. XAudio2 was its replacement.

Share this post


Link to post
Share on other sites

(sorry about the late reply, things have happened, some of them very interesting)

I have been dabbling with the Waveform and similar APIs before, but I keep feeling like they are to rigid. This might just be me, since audio is not a field I ever did much programming in. If there are good tutorials on things like those I have described, I am very interested in knowing!!

As for DirectSound / XAudio, it's a part of DirectX as I understand it, and that always bugs me. Is it possible to use it completely detached from DirectX, preferably without even importing any of the graphical libraries (I use OpenGL, for the platform portability)?

Share this post


Link to post
Share on other sites
16 minutes ago, Embassy of Time said:

 

As for DirectSound / XAudio, it's a part of DirectX as I understand it, and that always bugs me. Is it possible to use it completely detached from DirectX, preferably without even importing any of the graphical libraries (I use OpenGL, for the platform portability)?

For xaudio2, it only rely's on xaudio2.lib as far as i'm aware.

Share this post


Link to post
Share on other sites
21 hours ago, Embassy of Time said:

I have been dabbling with the Waveform and similar APIs before, but I keep feeling like they are to rigid. This might just be me, since audio is not a field I ever did much programming in. If there are good tutorials on things like those I have described, I am very interested in knowing!!

Rigid? How can you feel constrained by an API that lets you fill a buffer with arbitrary samples and play them? Are you attempting something impossible like going back in time and altering sample buffers that have already been sent to playback? Are you disoriented because a relatively low-level interfaces forces you to do all mixing, synthesis etc. on your own with little or no help? Are you in trouble with some specific task?

 

21 hours ago, Embassy of Time said:

As for DirectSound / XAudio, it's a part of DirectX as I understand it, and that always bugs me. Is it possible to use it completely detached from DirectX, preferably without even importing any of the graphical libraries (I use OpenGL, for the platform portability)?

i'm sure these libraries are adequately organized into many modules, both in the actual DLLs and in header files for C and C++ and in namespaces for C++ and C#, and you'll be able to leave out unneeded parts.  And even if you accidentally linked your program with something pointless, it would be very unlikely to cause trouble with OpenGL. 

 

Share this post


Link to post
Share on other sites
1 hour ago, LorenzoGatti said:

Rigid? How can you feel constrained by an API that lets you fill a buffer with arbitrary samples and play them? Are you attempting something impossible like going back in time and altering sample buffers that have already been sent to playback? Are you disoriented because a relatively low-level interfaces forces you to do all mixing, synthesis etc. on your own with little or no help? Are you in trouble with some specific task?

No, I just think I never got the right angle on the API. All I found were examples on loading up a file and playing it as-is. Even something like storing it for later replay seemed byzantine to figure out, so at some point, I just assumed it was too rigid. Do you have some tutorials or the like that show me the better side of the API, because I would love some?

Share this post


Link to post
Share on other sites

xaudio obviously isn't multi platform, if that's what you're asking. It works on Xbox (afaik), Windows, and that's it.

You could try https://www.fmod.com/ with an indie licence.

Anyway, whatever audio lib you use, it'll probably work on top of the native audio layer of the OS. Say, OpenAL Soft will work on top of ALSA/PulseAudio on Linux, WASAPI/DirectSound (or whatever else they have) on Windows, and so on.

So if you go below OpenAL level, you get into platform specific code.

Share this post


Link to post
Share on other sites
8 hours ago, Embassy of Time said:

No, I just think I never got the right angle on the API. All I found were examples on loading up a file and playing it as-is

Since you want to perform all the audio synthesis yourself, the API is pretty much irrelevant. All you'd need of the XAudio2 API, for example, would be this.

Its up to you to actually fill the buffer with useful audio data, of course.

Share this post


Link to post
Share on other sites

Here are some real time audio frameworks that might be of interest to you:

https://github.com/thestk/rtaudio

http://www.portaudio.com/

And a synthesis library I just found: http://maximilian.strangeloop.co.uk/

I've given RTAudio a test run, and they have an example that sets up a audio stream callback, and generates a saw wave. This sounds like something you're looking for, and it's very straight forward to setup. Also is crossplatform.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now