New to SDL_Mixer (revving engine sound)

Hello !

  • Is it still true that only WAV files can be
    used for samples? I suppose it would be possible to use SDL_sound for
    decoding other formats to memory, and then having libMikMod load it from
    there…

I think you can also load OGGs as Samples.

CU

[…]

Looking at the documentation, a few questions pop up:

* Is it still true that only WAV files can be
used for samples? I suppose it would be
possible to use SDL_sound for decoding other
formats to memory, and then having libMikMod
load it from there...

.WAV is the only filetype that can be used as a sample, but the
streamed formats are entirely another story. Pitch shifting on
streamed players is rather difficult and you might have to resort to
system-specific code for doing that.

That sounds strange… What’s system specific about resampling? It
sounds like these streams actually bypass the normal mixing engine or
something.

Anyway, I’ll just read the source and see what I find…

* It appears that the "Player" is a singleton,
which would mean that only one module can be
played at a time. Is there a way around this?
(For crossfading, using music as sound effects
and stuff like that.)
   Speaking of which; what, if anything, does
SDL_sound do about this?

SDL_sound wraps both MikMod and ModPlugTracker. It’s possible that
ModPlugTracker’s library might handle this. Not an ideal solution
IMHO since you have two music players loaded in simultaneously.

Well, the correct solution would obviously be to fix libMikMod and/or
ModPlug, so SDL_sound doesn’t have to worry about global state
conflicts, but I have no idea how much work that would be. As long as
we’re not dealing with lower level resources with further global
state issues, it’s theoretically just a matter of moving global
variables into a state struct and adjusting the API accordingly.

* I can't seem to find a pitch/transpose control
for the Player. Not exactly essential for
music (though some games in the 8 bit days
did transpose the music), but nice if you want
to use music formats for sound effects.

I think it only will transpose individual samples using the
Voice_SetFrequency() function but I haven’t tried it. Have a look
at http://mikmod.raphnet.net/doc/libmikmod-3.1.10/docs/mikmod.html
for the specific documentation on the Voice_SetFrequency() function.
(Just scroll down from the Sample Functins link.)

Well, it’s a Voice call, so I don’t see how you could even reference
a “music context” with it. (And there seems to be only one “music
context” anyway, pretty much like in SDL_mixer…)

My idea was more along the lines of providing something very light
weight and modular, with few, if any dependencies. Smaller and
simpler than SDL_mixer, with no explicit music or decoding support
at all. Something that does one thing, and does it well.

I would certainly welcome such a library becuase I am writing a
program that compiles ProTracker music modules into C source and am
having to make it system-specific to the Amiga-like operating
systems that support AHI drivers because it would be so redundant
with SDL_mixer and MikMod around.

It appears that the basic idea with AHI is to provide an abstract and
enhanced version of Paula. (Good old days…! :slight_smile: The API pretty much
reflects how you’d go about programming the chip “to the metal”, but
obviously, the abstraction allows emulation over other hardware,
voice virtualization and stuff like that.

The main difference with the API I have in mind is less focus on
hardware acceleration, and more focus on ease of use and useful
features.

The situation with hardware mixing is pretty much the same as in early
days of 3D acceleration. No standard language for custom DSP code
(corresponding to pixel shaders), many platforms lack driver or API
support, many systems lack hardware mixing entirely etc.

Of course, the API won’t necessarily rule out hardware acceleration,
but if you want effects to sound the same everywhere, want to drop in
custom effects, or need accurate timing and/or reliable inter-voice
synchronization, you’re pretty much guaranteed to be dropped back to
full software processing anyway. And if you don’t need effects and
stuff, you don’t really need hardware mixing, unless you’re on very
low end hardware and/or need insane numbers of voices…

That said, I suppose one could support AHI other APIs as well as SDL
audio, to make use of hardware mixing where available. It would work
as long as no master effects or similar are used - and such things
are probably no option anyway on platforms that really need hardware
mixing for speed. Just optionally dropping the effects is a lot less
work than supporting a different API, so it still helps portability.

There are several other libs (SDL_sound, libsndfile, various codec
libs etc…) that specialize in decoding/playing various types of
files and streams. Just plug one of these in if you need music.
The interesting part is that these would stream through the New
Mixer, giving you pitch control, effects and stuff, just as for
sound effects.

I think this is the problem with getting stuff to work on platform
independent libraries like SDL. I don’t know what Windows is like
or ALSA on Linux or Mac. I use SDL because there is little money to
be made on Amiga-like OSs with AHI drivers.

Well, they all have one thing in common: The only type of audio you
can count on is fixed rate stereo output. Anything beyond that is
only available on certain hardware, if at all accessible through
standard APIs.

The (original) Amiga is rather unique with it’s four (more or less)
independent hardware mixed DMA voices… (Well, every Live! and
Audigy and many other cards do that too - but it’s hard, if at all
possible to access it in any useful way, and even basic pitch control
is hardware specific, as most cards have resampling ratio
restrictions.)

If you wanted to port the AHI source code it would make my life
simpler but I doubt it would replace ALSA or some of the better
supported driver/mixer formats. The AHI source code is at
http://arp2.berlios.de/ahi/ if you’re interested. (The AROS version
is x86, the original AmigaOS 2.x-3.x version is
68000-based, and the AmigaOS 4.0 and MorphOS versions are PowerPC.)

The biggest problem is that it does things that “normal” audio APIs
these days don’t, so it pretty much ends up looking like a software
mixer/sound engine API, rather than a sound drivern API.

It would certainly be possible to implement it over ALSA, SDL audio,
DirectSound or whatever, but as there seems to be quite a bit of
AmigaOS specifics that need to be removed from the API, I’m not sure
there is much point…

I just thought that I would point out MikMod since it’s portable and
LGPL, AHI is also GPL/LGPL for the current parts respectively. I
don’t know how hard it is to write a wrapper functionity for a sound
driver but I’ll be using the AHI drivers for my Music Compiler
nonetheless.

As long as the semantics and feature sets match, it’s usually pretty
straightforward.

Looking at the AHI low level API, I don’t think it should be much of a
problem to have your code talk to this “New Mixer” thing, or to use
AHI as an alternate backend to the default software-over-SDL-audio
thing.

I’ll eagerly await any portable solutions you can come up with. I’m
not an expert on sound but I’m pretty well initiated with how things
are done on the Amiga. Drop me an email or post here and I’ll try
to help out any way I can.

What I’m most interested in at this point is which features you need.

After some browsing of the AHI docs, it seems like I’ll pretty much
provide a superset of the low level API. Not quite sure about the
waveform/stream handling, though. There are a few basic models that
might be relevant here:

1. Synchronous streaming callbacks. Pretty much the
   same deal as SDL audio; one callback for each
   output buffer - except here, you'd get one
   callback for each voice, asking for the number
   of *input* samples needed to render the next
   buffer. That is, these callbacks will be asked
   for buffers of varying size depending on voice
   pitch. (The point is to keep the CPU load as
   constant as possible across audio output
   buffers. Though this may not be essential in
   your average game, it is critical in low latency
   applications that use any significant percentage
   of the CPU time.) The API may allow callbacks to
   optionally return pointers instead of copying
   data.
      This works for everything (this is the way
   all serious low level audio APIs are designed),
   but may not be the easiset way of just getting
   some sounds played.

2. Engine managed sounds. You will need to upload
   sounds to the mixer, pretty much like you upload
   textures to OpenGL. You tell the mixer to start
   and stop sounds by making calls from the
   application main thread, or from within mixer
   driven callbacks, the former being asynchronous
   and the latter being synchronous and potentially
   sample accurate.
      Easy to use and suitable for most things
   except real time synthesis and streaming.

3. Asynchronous buffer queue streaming. The
   application pushes buffers of arbitrary sizes
   onto a (per voice) queue where the mixer picks
   them up and plays them one by one.
      Suitable for streaming from a decoder running
   in a background thread, but not of much use for
   low latency sound.

All three models allow callbacks to be used to make real time
decisions when reaching the end of a sound, at regular (sample
accurate) intervals and things like that, to implement looping,
envelopes etc. (This is where you’d hook in a music player that wants
to “play” the mixer, rather than mixing on it’s own.)

All models have their uses, though 2 and 3 are higher level models
that can be implemented over 1, whereas the other way around is not
possible without additional buffering and latency problems.

Model 2 seems to be the obvious, easy to use choice for pretty much
everything but real time synthesis (ie hacking your own virtual
analog oscillators and stuff) and streaming from non real time safe
decoders. So, I suppose the main focus of the API should be on that
model, but I think there will be trouble if the other two models
aren’t somehow accessible.

Model 1 is useful when you want to plug in some code that would
normally use SDL audio or a similar low level audio API directly.
Publishing this interface allows integrating such code with the
mixer, without additional latency.

Model 3 is handy when using IFFT based decoders and the like; sources
that won’t safely run inside a low latency real time thread. Indeed,
it can be implemented over 1, but then again, building it into the
mixer shouldn’t add much code, and it would make it easier for non
audio hackers to do things the proper way.

Thoughts? What did I miss?

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Friday 19 January 2007 21:38, Samuel Crow wrote:

Well, this is as close as ‘grep’ gets in libmikmod 3.2.0-beta2:

TODO: mp3 support ? cdda support ? suggestions welcome.

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Friday 19 January 2007 21:59, Torsten Giebl wrote:

Hello !

  • Is it still true that only WAV files can be
    used for samples? I suppose it would be possible to use SDL_sound
    for decoding other formats to memory, and then having libMikMod
    load it from there…

I think you can also load OGGs as Samples.

David Olofson a ?crit :

It appears that the basic idea with AHI is to provide an abstract and
enhanced version of Paula. (Good old days…! :slight_smile: The API pretty much
reflects how you’d go about programming the chip “to the metal”, but
obviously, the abstraction allows emulation over other hardware,
voice virtualization and stuff like that.

The main difference with the API I have in mind is less focus on
hardware acceleration, and more focus on ease of use and useful
features.

The situation with hardware mixing is pretty much the same as in early
days of 3D acceleration. No standard language for custom DSP code
(corresponding to pixel shaders), many platforms lack driver or API
support, many systems lack hardware mixing entirely etc.

Of course, the API won’t necessarily rule out hardware acceleration,
but if you want effects to sound the same everywhere, want to drop in
custom effects, or need accurate timing and/or reliable inter-voice
synchronization, you’re pretty much guaranteed to be dropped back to
full software processing anyway. And if you don’t need effects and
stuff, you don’t really need hardware mixing, unless you’re on very
low end hardware and/or need insane numbers of voices…

That said, I suppose one could support AHI other APIs as well as SDL
audio, to make use of hardware mixing where available. It would work
as long as no master effects or similar are used - and such things
are probably no option anyway on platforms that really need hardware
mixing for speed. Just optionally dropping the effects is a lot less
work than supporting a different API, so it still helps portability.

Thoughts? What did I miss?

There is an well-known API: OpenAL.> //David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --’


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

[…]

Thoughts? What did I miss?

There is an well-known API: OpenAL.

I’ve mentioned it already, and I’ve been reading up on it a bit. It
seems like there are some issues:
* It’s not small. (238 kB on AMD64, whereas
the idea was to get below 50 kB.)
* The API is overkill unless you really need 3D.
* It doesn’t provide any interfaces suitable
for low latency real time audio. (Buffer
queue streaming doesn’t cut it; wrong tool
for the job.)
* It doesn’t provide any means of accurately
timed control, suitable for music players
or detailed sound effect control. (AFAICT,
all control is asynchronous, and there are
no timestamps or anything anywhere.)
* It doesn’t seem to support custom voice or
master effect processing.

I don’t know about CPU usage… Is it seriously usable on Pentium
class CPUs? Will it run on anything handheld?

Maybe there are ways around some of these issues? Is there a lower
level API available for extensions…?

Not much to do about the size and API complexity though, and that
might rule it out right away for some users.

I don’t know… All I know is OpenAL isn’t the right tool for most
stuff I do with audio - but then again, I’m not your average “just
get some sound in there” game programmer.

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Saturday 20 January 2007 11:43, IoDream wrote:

David Olofson <david olofson.net> writes:

It appears that the basic idea with AHI is to provide an abstract and
enhanced version of Paula. (Good old days…! The API pretty much
reflects how you’d go about programming the chip “to the metal”, but
obviously, the abstraction allows emulation over other hardware,
voice virtualization and stuff like that.

The fact that it emulates timers by varying the output buffer size and calling
the hook function when it reaches the end of the sample is kind of intuitive.

Of course, the API won’t necessarily rule out hardware acceleration,
but if you want effects to sound the same everywhere, want to drop in
custom effects, or need accurate timing and/or reliable inter-voice
synchronization, you’re pretty much guaranteed to be dropped back to
full software processing anyway. And if you don’t need effects and
stuff, you don’t really need hardware mixing, unless you’re on very
low end hardware and/or need insane numbers of voices…

That said, I suppose one could support AHI other APIs as well as SDL
audio, to make use of hardware mixing where available. It would work
as long as no master effects or similar are used - and such things
are probably no option anyway on platforms that really need hardware
mixing for speed. Just optionally dropping the effects is a lot less
work than supporting a different API, so it still helps portability.

I suppose it’s possible, since AROS runs virtualized on several other
platforms and with AHI sound. The things I like about AHI are the way that
it supports “fake interrupts” to update the music code while creating a .WAV
output file.

If you wanted to port the AHI source code it would make my life
simpler but I doubt it would replace ALSA or some of the better
supported driver/mixer formats. The AHI source code is at
http://arp2.berlios.de/ahi/ if you’re interested. (The AROS version
is x86, the original AmigaOS 2.x-3.x version is
68000-based, and the AmigaOS 4.0 and MorphOS versions are PowerPC.)

The biggest problem is that it does things that “normal” audio APIs
these days don’t, so it pretty much ends up looking like a software
mixer/sound engine API, rather than a sound drivern API.

It would certainly be possible to implement it over ALSA, SDL audio,
DirectSound or whatever, but as there seems to be quite a bit of
AmigaOS specifics that need to be removed from the API, I’m not sure
there is much point…

When used with the SDI headers on the Aminet there’s a little bit more
compiler and platform independence for the low-level API for implementing
hook structures on all of the big-endian Amiga-like platforms. The
initialization code would change a lot though and the shut-down code.

I guess I was thinking of implementing the low-level API of AHI only. The
high-level code is only for backward-compatibility to the old audio.device
on the classic Amigas anyway.

I just thought that I would point out MikMod since it’s portable and
LGPL, AHI is also GPL/LGPL for the current parts respectively. I
don’t know how hard it is to write a wrapper functionity for a sound
driver but I’ll be using the AHI drivers for my Music Compiler
nonetheless.

As long as the semantics and feature sets match, it’s usually pretty
straightforward.

Looking at the AHI low level API, I don’t think it should be much of a
problem to have your code talk to this “New Mixer” thing, or to use
AHI as an alternate backend to the default software-over-SDL-audio
thing.

You’re probably right. I’d only have to convert all of my playback
frequencies from Hertz to the sampling frequencies and convert the timing
of all of the “fake interrupts” in the low-level interface to callbacks
from the mixing routine using a fixed playback rate.

One thing I like about AHI is that it abstracts the fixed playback frequency
from you enough that you can change your frequency ONCE in your code and
not on each individual function. For example, giving frequencies in Hertz
instead of Hertz*44100 if you’re using that frequency.

I’ll eagerly await any portable solutions you can come up with. I’m
not an expert on sound but I’m pretty well initiated with how things
are done on the Amiga. Drop me an email or post here and I’ll try
to help out any way I can.

What I’m most interested in at this point is which features you need.

[…]

Thoughts? What did I miss?

Thanks for taking me seriously. :slight_smile: My music compiler does use a lot of
Amiga-specific code but it could be modified to run on other platforms if
necessary. I’m afraid I won’t be able to offer much teamwork for your new
mixer since I have to get as much done on my compiler by March for the
Undergraduate Research Conference but I think you’ve got the right idea.

–Sam