top of page
Search

[63] Pretty Cool Modulation

  • Writer: Conlan Walker
    Conlan Walker
  • Dec 29, 2022
  • 3 min read

The audio engine should be done at this point. It currently has just about every feature I want, and I haven't really found any real unwanted behavior with it.


To start the work week off, I immediately changed the .mua header. The biggest change made was the replacement of dataSize, which is now in the same 16 byte space as numSamples, which makes things easier to see when viewed with a hex editor:

ree

I also made a few changes to muaReadFile(), as shown here:

ree


I wanted my audio engine to support every common form of PCM audio data, whether it be floats, or 8->32 bit signed and unsigned integers. The best way I've found to enable this is to internally convert all samples to floats. Here's a test which demonstrates conversion of an input audio stream of unsigned 8-bit samples:

ree


A struct is used to store and handle audio clip info, in the form of AudioElement.

ree

An array of these things is used to facilitate proper mixing of audio. Each element in this array I call a track. If the data portion of an AudioElement in the array is NULL, that "track" is considered inactive.








If there are no inactive (aka available) tracks to be found, audio clips can't be queued for playback. I made a diagram to demonstrate how this works, shown below:

ree

The numbers (y axis) correspond to track slot numbers. Those bars with the dots are depictions of audio clips, with varying durations. The red and green spots in the timeline show whether or not you can queue more audio clips at each point.

If track 1 is occupied, it will try track 2, then 3, and so on until it


either finds a vacant track, or it runs out of tracks to check. There are 4 tracks shown here, but in practice it's set to 32 total tracks, as that should cover any reasonable application (it can be set to more or less, but 32 seems good enough for what I want to do).



Here's a list of the current list of audio functions, as shown in kaudio.h:

ree


Now for the tests where you can actually hear something. I have two to show this time.

The initialization procedure is pretty much just the boilerplate SDL audio one, except the userdata section of the audio spec is tied to the number of active tracks for any given invocation of the audio callback.

ree

The first test I did involves a few things, which includes mixing of two audio tracks, clips that can loop forever, as well as changing the volume of those two tracks over time.

ree

Here are the two individual tracks being mixed and looped as heard in the video below:

Most of these tests (including this one) use music/sounds from Yume 2kki.





This is due to the (generally) short length of its songs, and wide variety of sample rates and PCM data types. Also, most songs are supposed to seamlessly loop, which is a .mua feature.

This next image performs basically the same action, but it instead uses the interface functions, rather than directly manipulating the audio track struct array:

ree


The next one is a stress test to see what happens when audio clips are spam-queued.

ree

For the test, I set the total tracks to 4, like the diagram. This means that there should be no more than 4 audio clips playing at once, and those 4 shouldn't be cut-off at any point before they finish.

I also used the Tim Allen grunt here because it was funny.





The current feature list I could come up with is as follows:

  • Channel-independent adjustable volume

  • Channel-independent volume gradients (volume change over a specified time span)

  • Variable audio speed

  • Universal sample rate conversion via linear interpolation

  • Variable looping of audio clips

  • Adjustable device sample rate, stream buffer size, and track count

  • Management of active tracks

  • Hard clipping of stream buffer

  • Support for most PCM audio data types

There might be more, but I can't pull any more off the top of my head.


ree

To finish this post, here's a printout of the current line count for everything as it stands now.


Next week I'll look into using libmikmod to handle music, as I'd like to only use this audio engine for things like short sound effects.

(I'm hoping that there's no device conflicts with mikmod and SDL audio to worry about.)

 
 
 

Comments


bottom of page