Building upon what I learned back in April about mixing, I've managed to
get all my inputs into the same formats for output. I've made some
developments in getting stuff to correctly play individually, but mixing
is still beyond me.
playaiff()
Waits for semaphore audio_empty, then gets mutex. Then fills bleepbuffer
with 2-channel, 16-bit, 44100Hz float audio data from an AIFF chunk.
When the buffer is full, it puts up the audio_full semaphore and releases
the mutex. While there are still data to process, the global
bleep_playing is true. A thread is spawned for this whenever an AIFF
chunk must be played. It terminates when the chunk is done playing.
playmusic()
Calls either playmod() or playogg() depending on what kind of chunk has
been passed to it. Those two functions are the same as playaiff() except
they handle MODs or OGGs. While there are still data to process, the
global music_playing is true. A thread is spawned for this whenever a MOD
or OGG chunk must be played. It terminates when the chunk is done
playing.
mixer()
Waits for the audio_full semaphore, then gets mutex. If bleep_playing is
true and music_playing is false, convert bleepbuffer (floats) to
shortbuffer (shorts) and play shortbuffer with ao_play(). If
bleep_playing is false and music_playing is true, convert musicbuffer
(floats) to shortbuffer (shorts) and play shortbuffer with ao_play().
If both bleep_playing and music_playing are true, then step through
bleepbuffer[i] and add musicbuffer[i]. Convert bleepbuffer to shorts and
play shortbuffer. A thread is spawned for this on startup and runs until
the main thread terminates.
Now, the trouble.
If I start music in the form of a MOD chunk, then play an AIFF, I get a
distorted mix and then the music keeps going on cleanly. Subsequent AIFF
plays perform the same whether or not the MOD is playing.
If I start music in the form of an OGG chunk, then play an AIFF, I get a
distorted mix, then a harsh screech for a few more seconds, and then maybe
a segfault.
What is wrong with my mixer?
Here's the latest code:
https://github.com/DavidGriffith/frotz/blob/ao-curses/src/curses/ux_audio.c
These libraries are necessary: install libao, libvorbis, libncurses,
libmodplug, and libsamplerate.
Test program is at
http://661.org/if/story.zblorb
There are three buttons: red, green, and blue. Pressing these will cause
an AIFF to play. There is a Commodore 64 that plays an OGG. The Amiga
will play a MOD. Pressing the "off" button will turn off all sounds.
Just turning off the music maker won't work. That's another problem for
which I do not need assistance.
Red button: 2-channel, 16-bit, 44100Hz
Green button: 1-channel, 8-bit, 11025Hz
Blue button: 1-channel, 8-bit, 11025Hz
Tests are as follows:
! Pressing red, green, or blue buttons results in different noises.
PRESS RED BUTTON
You press the red button.
! quit and restart
TURN ON COMMODORE 64
You turn on the Commodore
64 and it immediately begins playing the tune
from the game Sanxion.
! At this point, pressing one of the colored buttons will cause a
! distorted mix and usually a segfault.
! quit and restart
TURN ON AMIGA
You turn on the Commodore Amiga
and it immedately begins playing an old
time MOD file.
PRESS BLUE BUTTON
You press the blue button.
! Here there is a distorted mix that runs a bit slower than it should.
! When the noise produced by the colored button completes, the MOD file
! music continues with no more distortion. Pressing a colored button
! again will result in the same distortion and then the MOD continues as
! before.
--
David Griffith
dave(a)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?