[LAD] mixing music and sound effects using libao

dave at 661.org dave at 661.org
Fri May 1 08:34:33 UTC 2015


On Fri, 1 May 2015, Hermann Meyer wrote:

> Am 01.05.2015 um 00:17 schrieb dave at 661.org:
>> On Thu, 30 Apr 2015, Hermann Meyer wrote:
>>> Hi
>>> It seems libao is able to do this. Attached is the example code from the 
>>> libao side, roughly hacked in a second thread to play to signals 
>>> simultaneous. Works stable here.
>> 
>> This has trouble opening the second device:
>> 
>> ALSA lib pcm_dmix.c:1018:(snd_pcm_dmix_open) unable to open slave
>> Error opening device2.
>> 
>> I'm using Debian Wheezy amd64 without Pulseaudio.  Maybe Debian's default 
>> setup for ALSA is wrong?  There are no /etc/asound.conf or ~/.asoundrc 
>> files.
>> 
> Well, here is debian/sid with pulse/jack running. Indeed, it didn't work with 
> plain ALSA, . .

Apparently using libao like this depends on the underlying driver being 
capable of doing mixing.  Back to the drawing board...  What I need to 
figure out boils down to a basic premise and two tasks:

The premise: There are two buffers of audio which must be mixed.

The tasks:
1) Add enough silent tracks to the audio chunk with fewer channels 
and get the tracks in the right places.

2) Cleanly mix two chunks of audio.

I don't know how to do these.

For the benefit of the curious, here's what I'm up to in greater detail:

"Music" is played from OGG or MOD files[1].  "Sound-effects" are played 
from AIFF files.  One music may be mixed with one sound-effect.  No other 
mixing is allowed.

My project[2] spawns a "mixer" thread on startup and waits for data to be 
put in a music buffer or a sound-effect buffer.  For each sound effect or 
background music piece, a thread is spawned which decodes the audio file, 
fills the appropriate buffer, raises a semaphore, waits for an empty 
buffer, and repeats until done.  They may told to stop early by setting 
bleep_playing or music_playing globals to FALSE.

When the mixer gets its semaphore, it sets the ao_sample_format pointer 
appropriately, calls ao_open_live(), then plays the buffer with ao_play().
It then sets a semaphore indicating the buffer(s) are empty and goes back 
to sleep.

The audio files can be of any legal sample size, sample rate, and channel 
count.  Libsndfile, libmodplug, and libvorbis ensure that the data are all 
16-bits at 44100 Hz.  The next two steps are to add silent channels to the 
audio chunk with the smallest channel count and then to mix the results. 
I could use some help with these last two tasks.

[1] Files are actually chunks embedded in a single IFF file.  Another 
library, irrelevant to this discussion, gives me FILE pointers to what I 
want.

[2] https://github.com/DavidGriffith/frotz

-- 
David Griffith
dave at 661.org

A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?


More information about the Linux-audio-dev mailing list