miodrag@multimania.com)
Copyright (C) 1998, 1999 Miodrag Vallat and others -- see file AUTHORS for complete list.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
The MikMod sound library is an excellent way for a programmer to add music and sound effects to an application. It is a powerful and flexible library, with a simple and easy-to-learn API.
Besides, the library is very portable and runs under a lot of Unices, as well as under OS/2. Third party individuals also maintain ports on other systems, including Windows (using DirectX), and BeOS.
MikMod is able to play a wide range of module formats, as well as digital sound files. It can take advantage of particular features of your system, such as sound redirection over the network. And due to its modular nature, the library can be extended to support more sound or module formats, as well as new hardware or other sound output capabilities, as they appear.
This chapter will describe how to quickly incorporate MikMod's power into your programs. It doesn't cover everything, but that's a start and I hope it will help you understand the library's philosophy.
If you have a real tutorial to put here, you're welcome ! Please send it to me...
MikMod's sound output is composed of several sound voices which are mixed, either in software or in hardware, depending of your hardware configuration. Simple sounds, like sound effects, use only one voice, whereas sound modules, which are complex arrangements of sound effects, use several voices.
MikMod's functions operate either globally, or at the voice level. Differences in the handling of sound effects and modules are kept minimal, at least for the programmer.
The sound playback is done by a sound driver. MikMod provides several sound drivers: different hardware drivers, and some software drivers to redirect sound in a file, or over the network. You can even add your own driver, register it to make it known by the library, and select it.
To use MikMod in your program, there are a few steps required:
Here's a program which meets all those conditions:
/* MikMod Sound Library example program: a skeleton */
#include <mikmod.h>
main()
{
/* register all the drivers */
MikMod_RegisterAllDrivers();
/* initialize the library */
MikMod_Init();
/* we could play some sound here... */
/* give up */
MikMod_Exit();
}
This program would be compiled with the following command line:(1)
cc -o example example.c -lmikmod -ldl
Although this programs produces no useful result, many things happen when you
run it. The call to MikMod_RegisterAllDrivers registers all the drivers
embedded in the MikMod library. Then, MikMod_Init chooses the more
adequate driver and initializes it. The program is now ready to produce sound.
When sound is not needed any more, MikMod_Exit is used to relinquish
memory and let other programs have access to the sound hardware.
Our program is not really useful if it doesn't produce sound. Let's suppose you've got this good old module, "Beyond music", in the file `beyond_music.mod'. How about playing it ?
To do this, we'll use the following code:
/* MikMod Sound Library example program: a simple module player */
#include <unistd.h>
#include <mikmod.h>
main()
{
MODULE *module;
/* register all the drivers */
MikMod_RegisterAllDrivers();
/* register all the module loaders */
MikMod_RegisterAllLoaders();
/* initialize the library */
md_mode|=DMODE_SOFT_MUSIC;
if(MikMod_Init()) {
fprintf(stderr,"Could not initialize sound, reason: %s\n",
MikMod_strerror(MikMod_errno));
return;
}
/* load module */
module = Player_Load("beyond_music.mod",64,0);
if (module) {
/* start module */
Player_Start(module);
while(Player_Active()) {
/* we're playing */
usleep(10000);
MikMod_Update();
}
Player_Stop();
Player_Free(module);
} else
fprintf(stderr,"Could not load module, reason: %s\n",
MikMod_strerror(MikMod_errno));
/* give up */
MikMod_Exit();
}
What's new here ? First, we've not only registered MikMod's device driver, but also the module loaders. MikMod comes with a large choice of module loaders, each one for a different module type. Since every loader is called to determine the type of the module when we try to load them, you may want to register only a few of them to save time. In our case, we don't matter, so we happily register every module loader.
Then, there's an extra line before calling MikMod_Init. We change the
value of MikMod's variable md_mode to tell the library that we want the
module to be processed by the software. In fact, there's no hardware device
able to directly play modules, so all modules must be handled by software
mixing.
We'll ensure that MikMod_Init was successful. Note that, in case of
error, MikMod provides the variable MikMod_errno, an equivalent of
the C library errno for MikMod errors, and the function
MikMod_strerror, an equivalent to strerror.
Now onto serious business ! The module is loaded with the Player_Load
function, which takes the name of the module file, and the number of voices
afforded to the module. In this case, the module has only 4 channels, so 4
voices, but complex Impulse Tracker modules can have a lot of voices (as they
can have as many as 256 virtual channels with new note actions). Since empty
voices don't cost time to be processed, it is safe to use a big value, such as
64 or 128. The third parameter is the "curiosity" of the loader: if nonzero,
the loader will search for hidden parts in the module. However, only a few
module formats can embed hidden or non played parts, so we'll use 0 here.
Now that the module is ready to play, let's play it. We inform the player that
the current module is module with Player_Start. Playback starts,
but we have to update it on a regular basis. So there's a loop on the result
of the Player_Active function, which will tell us if the module has
finished. To update the sound, we simply call MikMod_Update.
After the module has finished, we tell the player its job is done with
Player_Stop, and we free the module with Player_Free.
MikMod is not limited to playing modules, it can also play sound effects, that is, module samples. It's a bit more complex than playing a module, because the module player does a lot of things for us, but here we'll get more control over what is actually played by the program. Let's look at an example:
/* MikMod Sound Library example program: sound effects */
#include <unistd.h>
#include <mikmod.h>
main()
{
int i;
/* sound effects */
SAMPLE *sfx1,*sfx2;
/* voices */
int v1,v2;
/* register all the drivers */
MikMod_RegisterAllDrivers();
/* initialize the library */
md_mode|=DMODE_SOFT_SNDFX;
if(MikMod_Init()) {
fprintf(stderr,"Could not initialize sound, reason: %s\n",
MikMod_strerror(MikMod_errno));
return;
}
/* load samples */
sfx1 = Sample_Load("first.wav");
if(!sfx1) {
MikMod_Exit();
fprintf(stderr,"Could not load the first sound, reason: %s\n",
MikMod_strerror(MikMod_errno));
return;
}
sfx2 = Sample_Load("second.wav");
if(!sfx2) {
Sample_Free(sfx1);
MikMod_Exit();
fprintf(stderr,"Could not load the second sound, reason: %s\n",
MikMod_strerror(MikMod_errno));
return;
}
/* reserve 2 voices for sound effects */
MikMod_SetNumVoices(-1,2);
/* get ready to play */
MikMod_EnableOutput();
/* play first sample */
v1=Sample_Play(sfx1,0,0);
for(i=0;i<5;i++) {
MikMod_Update();
usleep(100000);
}
/* half a second later, play second sample */
v2=Sample_Play(sfx2,0,0);
do {
MikMod_Update();
usleep(100000);
} while(!Voice_Stopped(v2));
MikMod_DisableOutput();
Sample_Free(sfx2);
Sample_Free(sfx1);
MikMod_Exit();
}
As in the previous example, we begin by registering the sound drivers and
initializing the library. We also ask for software mixing by modifying the
variable md_mode(2).
It's time to load our files, with the Sample_Load function. Don't forget
to test the return value -- it looks ugly here on such a small example, but
it's a good practice...
Since we want to play two samples, we have to use at least two voices for this,
so we reserve them with a MikMod_SetNumVoices call. The first parameter
sets the number of module voices, and the second parameter the number of sound
effect voices. We don't want to set the number of module voices here (it's part
of the module player's duty), so we use the value -1 to keep the current
value, and we reserve two sound effect voices.
Now we're ready to play, so we call MikMod_EnableOutput to make the
driver ready. Sound effects are played by the Sample_Play function.
You just have to specify which sample you want to play, the offset from which
you want to start, and the playback flags. More on this later. The function
returns the number of the voice associated to the sample.
We play the first sample for half a second, then we start to play the second
sample. Since we've reserved two channels, both samples play simultaneously. We
use the Voice_Stopped function to stop the playback: it returns the
current status of the voice argument, which is zero when the sample plays and
nonzero when it has finished. So the do loop will stop exactly when
the second sample is finished, regardless of the length of the first sample.
To finish, we get rid of the samples with Sample_Free.
Sound effects have some attributes that can be affected to control the playback.
These are speed, panning, and volume. Given a voice number, you can affect these
attributes with the Voice_SetFrequency, Voice_SetPanning and
Voice_SetVolume functions.
In the previous example, we'll replace the actual sound code, located between
the calls to MikMod_EnableOutput and MikMod_DisableOutput, with
the following code:
Sample_Play(sfx1,0,0);
for(i=0;i<5;i++) {
MikMod_Update();
usleep(100000);
}
v2=Sample_Play(sfx2,0,SFX_CRITICAL);
i=0;
do {
MikMod_Update();
usleep(100000);
v1=Sample_Play(sfx1,0,0);
Voice_SetVolume(v1,160);
Voice_SetFrequency(v1,(sfx1->speed*(100+i))/100);
Voice_SetPanning(v2,(i++&1)?PAN_LEFT:PAN_RIGHT);
} while(!Voice_Stopped(v2));
The first thing you'll notice, is the SFX_CRITICAL flag used to play the
second sample. Since the do loop will add another sample every 100
milliseconds, and we reserved only two voices, the oldest voice will be
cut each time this is necessary. Doing this would cut the second sample in the
second iteration of the loop. However, since we flagged this sound as
"critical", it won't be cut until it is finished or we stop it with a
Voice_Stop call. So the second sample will play fine, whereas the first
sample will be stopped every loop iteration.
Then, we choose to play the first sample a bit lower, with
Voice_SetVolume. Volume voices range from 0 (silence) to 256. In
this case we play the sample at 160. To make the sound look weird, we also
change its frequency with Voice_SetFrequency. The computation in the
example code makes the frequency more and more high (starting from the sample
frequency and then increasing from 1% each iteration).
And to demonstrate the Voice_SetPanning function, we change the panning
of the second sample at each iteration from the left to the right. The argument
can be one of the standard panning PAN_LEFT, PAN_RIGHT,
PAN_MIDDLE and PAN_SURROUND(3), or a numeric value between 0 (PAN_LEFT) and
255 (PAN_RIGHT).
This chapter describes the various parts of the library and their uses.
If your program is dynamically linked with the MikMod library, you should check which version of the library you're working with. To do this, the library defines a few constants and a function to help you determine if the current library is adequate for your needs or if it has to be upgraded.
When your program includes mikmod.h, the following constants are
defined:
LIBMIKMOD_VERSION_MAJOR is equal to the major version number of
the library.
LIBMIKMOD_VERSION_MINOR is equal to the minor version number of
the library.
LIBMIKMOD_REVISION is equal to the revision number of the library.
LIBMIKMOD_VERSION is the sum of LIBMIKMOD_VERSION_MAJOR shifted 16 times, LIBMIKMOD_VERSION_MINOR shifted 8 times, and
LIBMIKMOD_REVISION.
So your program can tell with which version of the library it has been compiled this way:
printf("Compiled with MikMod Sound Library version %ld.%ld.%ld\n",
LIBMIKMOD_VERSION_MAJOR,
LIBMIKMOD_VERSION_MINOR,
LIBMIKMOD_REVISION);
The library defines the function MikMod_GetVersion which returns the
value of LIBMIKMOD_VERSION for the library. If this value is greater than or
equal to the value of LIBMIKMOD_VERSION for your program, your program will
work; otherwise, you'll have to inform the user that he has to upgrade the
library:
{
long engineversion=MikMod_GetVersion();
if (engineversion<LIBMIKMOD_VERSION) {
printf("MikMod library version (%ld.%ld.%ld) is too old.\n",
(engineversion>>16)&255,
(engineversion>>8)&255,
(engineversion)&255);
printf("This programs requires at least version %ld.%ld.%ld\n",
LIBMIKMOD_VERSION_MAJOR,
LIBMIKMOD_VERSION_MINOR,
LIBMIKMOD_REVISION);
puts("Please upgrade your MikMod library.");
exit(1);
}
}
MikMod defines several data types to deal with modules and sample data. These types have the same memory size on every platform MikMod has been ported to.
These types are:
CHAR is a printable character. For now it is the same as the
char type, but in the future it may be wide char (Unicode) on some
platforms.
SBYTE is a signed 8 bit number (can range from -128 to 127).
UBYTE is an unsigned 8 bit number (can range from 0 to 255).
SWORD is a signed 16 bit number (can range from -32768 to 32767).
UWORD is an unsigned 16 bit number (can range from 0 to 65535).
SLONG is a signed 32 bit number (can range from -2.147.483.648 to
2.147.483.647).
ULONG is an unsigned 32 bit number (can range from 0 to
4.294.967.296).
BOOL is a boolean value. A value of 0 means false, any other value
means true.
Although MikMod does its best to do its work, there are times where it can't. For example, if you're trying to play a corrupted file, well, it can't.
A lot of MikMod functions return pointers or BOOL values. If the pointer
is NULL or the BOOL is 0 (false), an error has occurred.
MikMod errors are returned in the variable MikMod_errno. Each possible
error has a symbolic error code, beginning with MMERR_. For example, if
MikMod can't open a file, MikMod_errno will receive the value
MMERR_OPENING_FILE.
You can get an appropriate error message to display from the function
MikMod_strerror.
There is a second error variable named MikMod_critical. As its name
suggests, it is only set if the error lets the library in an unstable state.
This variable can only be set by the functions MikMod_Init,
MikMod_SetNumVoices and MikMod_EnableOutput. If one of these
functions return an error and MikMod_critical is set, the library is left
in the uninitialized state (i.e. it was not initialized, or MikMod_Exit
was called).
If you prefer, you can use a callback function to get notified of errors. This
function must be prototyped as void MyFunction(void). Then, call
MikMod_RegisterHandler with your function as argument to have it notified
when an error occurs. There can only be one callback function registered, but
MikMod_RegisterHandler will return you the previous handler, so you can
chain handlers if you want to.
To initialize the library, you must register some sound drivers first. You can
either register all the drivers embedded in the library for your platform with
MikMod_RegisterAllDrivers, or register only some of them with
MikMod_RegisterDriver. If you choose to register the drivers manually,
you must be careful in their order, since MikMod_Init will try them in
the order you registered them. The MikMod_RegisterAllDrivers function
registers the network drivers first (for playing sound over the network), then
the hardware drivers, then the disk writers, and in last resort, the nosound
driver. Registering the nosound driver first would not be a very good
idea...
You can get some printable information regarding the registered drivers with
MikMod_InfoDriver; don't forget to call free on the returned
string when you don't need it anymore.
After you've registered your drivers, you can initialize the sound playback
with MikMod_Init. If you set the variable md_device to zero, which
is its default value, the driver will be autodetected, that is, the first driver
in the list that is available on the system will be used; otherwise only
the driver whose order in the list of the registered drivers is equal to
md_device will be tried. If your playback settings, in the variables
md_mixfreq and md_mode, are not supported by the device,
MikMod_Init will fail.
You can then choose the number of voices you need with
MikMod_SetNumVoices, and activate the playback with
MikMod_EnableOutput.
Don't forget to call MikMod_Update as often as possible to process the
sound mixing. If necessary, fork a dedicated process to do this.
If you want to change playback settings, most of them can't be changed on the
fly. You'll need to stop the playback and reinitialize the driver. Use
MikMod_Active to check if there is still sound playing; in this case,
call MikMod_DisableOutput to end playback. Then, change your settings
and call MikMod_Reset. You're now ready to select your number of voices
and restart playback.
When your program ends, don't forget to stop playback and call
MikMod_Exit to leave the sound hardware in a coherent state.
Currently, MikMod only supports uncompressed mono WAV files as samples. You can
load a sample by calling Sample_Load with a filename, or by calling
Sample_LoadFP with an open FILE* pointer. These functions return
a pointer to a SAMPLE structure, or NULL in case of error.
The SAMPLE structure has a few interesting fields:
speed contains the frequency of the sample.
volume contains the volume of the sample, ranging from 0 (silence)
to 64.
panning contains the panning position of the sample.
Altering one of those fields will affect all voices currently playing the
sample. You can achieve the same result on a single voice with the functions
Voice_SetFrequency, Voice_SetVolume and Voice_SetPanning.
You can also make your sample loop by setting the fields loopstart and
loopend and or'ing flags with SF_LOOP. To compute your loop
values, the field length will be useful. However, you must know that
all the sample length are expressed in samples, i.e. 8 bits for an 8 bit sample,
and 16 bit for a 16 bit sample... Test flags for the value
SF_16BITS to know this.
If the common forward loop isn't enough, you can play with some other flags:
SF_BIDI will make your sample loop "ping pong" (back and forth), and
SF_REVERSE will make it play backwards.
To play your sample, use the Sample_Play function. This function
will return a voice number which enable you to use the Voice_xx
functions.
The sample will play until another sample takes over its voice (when you play
more samples than you reserved sound effect voices), unless it has been flagged
as SFX_CRITICAL. You can force it to stop with Voice_Stop, or you
can force another sample to take over this voice with Voice_Play;
however Voice_Play doesn't let you flag the new sample as critical.
Non looping samples will free their voice channel as soon as they are finished;
you can know the current playback position of your sample with
Voice_GetPosition. If it is zero, either the sample has finished playing
or it is just beginning; use Voice_Stopped to know.
When you don't need a sample anymore, don't forget to free its memory with
Sample_Free.
As for the sound drivers, you have to register the module loaders you want to
use for MikMod to be able to load modules. You can either register all the
module loaders with MikMod_RegisterAllLoaders, or only a few of them with
MikMod_RegisterLoader. Be careful if you choose this solution, as the
15 instrument MOD loader has to be registered last, since loaders are called in
the order they were register to identify modules, and the detection of this
format is not fully reliable, so other modules might be mistaken as 15
instrument MOD files.
You can get some printable information regarding the registered loaders with
MikMod_InfoLoader; don't forget to call free on the returned
string when you don't need it anymore.
Note that, contrary to the sound drivers, you can register module loaders at any time, it doesn't matter.
For playlists, you might be interested in knowing the module title first, and
Player_LoadTitle will give you this information. Don't forget to
free the returned text when you don't need it anymore.
You can load a module either with Player_Load and the name of the
module, or with Player_LoadFP and an open FILE* pointer. These
functions also expect a maximal number of voices, and a curiosity flag. Unless
you have excellent reasons not to do so, choose a big limit, such as 64 or even
128 for complex Impulse Tracker modules. Both functions return a pointer to an
MODULE structure, or NULL if an error occurs.
You'll find some useful information in this structure:
numchn contains the number of module "real" channels.
numvoices contains the number of voices reserved by the player for
the real channels and the virtual channels (NNA).
numpas and numpat contain the number of song positions and
song patterns.
numins and numsmp contain the number of instruments and
samples.
songname contains the song title.
modtype contains the name of the tracker used to create the song.
comment contains the song comment, if it has one.
sngtime contains the time elapsed in the module, in
2^-10 seconds (not exactly a millisecond).
sngspd and bpm contain the song speed and tempo.
Now that the module is loaded, you need to tell the module player that you want
to play this particular module with Player_Start (the player can only
play one module, but you can have several modules in memory). The playback
begins. Should you forget which module is playing, Player_GetModule will
return it to you.
You can change the current song position with the functions
Player_NextPosition, Player_PrevPosition and
Player_SetPosition, the speed with Player_SetSpeed and
Player_SetTempo, and the volume (ranging from 0 to 128) with
Player_SetVolume.
Playback can be paused or resumed with Player_TogglePause. Be sure to
check with Player_Paused that it isn't already in the state you want !
Fine player control is achieved by the functions Player_Mute,
Player_UnMute and Player_ToggleMute which can silence or resume
a set of module channels. The function Player_Muted will return the
state of a given channel. And if you want even more control, you can get the
voice corresponding to a module channel with Player_GetChannelVoice and
act directly on the voice.
Modules play only once, but can loop indefinitely if they are designed to do so.
You can change this behavior with the wrap and loop of the
MODULE structure; the first one, if set, will make the module restart
when it's finished, and the second one, if set, will prevent the module from
jumping backwards.
You can test if the module is still playing with Player_Active, and you
can stop it at any time with Player_Stop. When the module isn't needed
anymore, get rid of it with Player_Free.
This chapter describes in more detail all the functions and variables provided by the library. See section Type Definitions for the basic type reference.
The following variables are set by the library to return error information.
int MikMod_errno
BOOL MikMod_critical
MikMod_errno is different from zero.
If the value of MikMod_critical is zero, the error wasn't fatal and the
library is in a stable state. However, if it is nonzero, then the library can't
be used and has reseted itself to the uninitialized state. This often means
that the mixing parameters you choose were not supported by the driver, or that
it doesn't has enough voices for your needs if you called
MikMod_SetNumVoices.
The following variables control the sound output parameters and their changes take effect immediately.
UBYTE md_musicvolume
UBYTE md_pansep
UBYTE md_reverb
UBYTE md_sndfxvolume
UBYTE md_volume
The following variables control more in-depth sound output parameters. Except
for some md_mode flags, their changes do not have any effect until you
call MikMod_Init or MikMod_Reset.
UWORD md_device
MDRIVER* md_driver
MikMod_Init and
after MikMod_Exit). This variable is for information only, you should
never attempt to change its value. Use md_driver and MikMod_Init
(or MikMod_Reset) instead.
UWORD md_mixfreq
UWORD md_mode
Only the useful fields are described here; if a structure field is not described, you must assume that it's an internal field which must not be modified.
The MDRIVER structure is not meant to be used by anything else than the
core of the library, but its first four fields contain useful information for
your programs:
CHAR* Name
CHAR* Description
UBYTE HardVoiceLimit
UBYTE SoftVoiceLimit
The MODULE structure gathers all the necessary information needed to
play a module file, regardless of its initial format.
The fields described in this section contain general information about the module and should not be modified.
CHAR* songname
CHAR* modtype
CHAR* comment
UWORD flags
numvoices field is
valid.
UBYTE numchn
UBYTE numvoices
maxchan parameter
of the Player_Loadxx functions.
UWORD numpos
UWORD numpat
UWORD numins
UWORD numsmp
INSTRUMENT* instruments
SAMPLE* samples
The fields described here control the module playback and can be modified at any time, unless otherwise specified.
UBYTE initspeed
UBYTE inittempo
UBYTE initvolume
UWORD panning[]
numchn values are
defined.
UBYTE chanvol[]
numchn values are defined.
UWORD bpm
Player_SetTempo to change its value.
UBYTE sngspd
Player_SetSpeed to change its value.
UBYTE volume
Player_SetVolume to change its value.
BOOL extspd
BOOL panflag
BOOL wrap
UBYTE reppos
BOOL loop
BOOL fadeout
UWORD patpos
SWORD sngpos
Player_NextPosition, Player_PrevPosition or
Player_SetPosition instead.
ULONG sngtime
Although the INSTRUMENT structure is intended for internal use, you
might need to know its name:
CHAR* insname
The SAMPLE structure is used for sound effects and module samples as
well. You can play with the following fields:
SWORD panning
ULONG speed
UBYTE volume
UWORD flags
ULONG length
ULONG loopstart
ULONG loopend
The following errors are currently defined:
xx_Loadxx function, or for write access from the disk writer drivers.
setrlimit function to do this if it needs to load very huge
samples.
MMERR_OUT_OF_MEMORY.
Generic driver errors
md_device) is out of range.
AudioFile driver specific errors
AIX driver specific errors
HP-UX driver specific errors
Open Sound System driver specific errors
SGI driver specific errors
Sun driver specific errors
OS/2 driver specific errors
MikMod_Update will be ignored when sound output is disabled.
MikMod_DisableOutput, MikMod_EnableOutput.
void MikMod_DisableOutput(void)
MikMod_Update will be ignored when sound output is disabled.
MikMod_Active, MikMod_EnableOutput.
BOOL MikMod_EnableOutput(void)
MikMod_Update will be ignored when sound output is disabled.
MikMod_Active, MikMod_DisableOutput.
MikMod_Init, MikMod_Reset.
(maj<<16)|(min<<8)|(rev),
where `maj' is the major version number, `min' is the minor version
number, and `rev' is the revision number.
NULL if no drivers are registered.
malloc; the caller must free it when it is
no longer necessary.
MikMod_RegisterDriver, MikMod_RegisterAllDrivers.
NULL if no loaders are registered.
malloc; the caller must free it when it is
no longer necessary.
MikMod_RegisterLoader, MikMod_RegisterAllLoaders.
MikMod_Exit, MikMod_Reset.
void MikMod_RegisterAllDrivers(void)
MikMod_InfoDriver, MikMod_RegisterDriver.
void MikMod_RegisterAllLoaders(void)
MikMod_InfoLoader, MikMod_RegisterLoader.
void MikMod_RegisterDriver(struct MDRIVER* newdriver)
MDRIVER structure identifying the driver.
MikMod_Init.
If you want to register all the available drivers, use
MikMod_RegisterAllDrivers instead.
MikMod_InfoDriver, MikMod_RegisterAllDrivers.
MikMod_handler_t MikMod_RegisterErrorHandler(MikMod_handler_t newhandler)
NULL if there was none.
MikMod_handler_t is defined as void(*function)(void), this means
your error function has the following prototype:
void MyErrorHandler(void)
void MikMod_RegisterLoader(struct MLOADER* newloader)
MLOADER structure identifying the loader.
Player_Load
or Player_LoadFP. If you want to register all the available module
loaders, use MikMod_RegisterAllLoaders instead.load_m15) should always be registered
last.
MikMod_InfoLoader, MikMod_RegisterAllLoaders.
MikMod_player_t MikMod_RegisterPlayer(MikMod_player_t newplayer)
MikMod_player_t is defined as void(*function)(void), this means
your player function has the following prototype:
void MyPlayer(void)bpm value is the tempo of the module and can
change from its initial value when requested by the module.
MikMod_player_t oldroutine;
void MyPlayer(void)
{
oldroutine();
/* your stuff here */
...;
}
main()
{
...
/* Register our player */
oldroutine=MikMod_RegisterPlayer(MyPlayer);
...
}
md_device and md_mixfreq, or one of the md_mode flags
which require sound reinitialization. Sound playback will continue as soon as
the driver is ready.
MikMod_Exit, MikMod_Init.
BOOL MikMod_SetNumVoices(int musicvoices,int samplevoices)
-1 for any of the parameters will retain the current number
of reserved voices.MikMod_Init, MikMod_Reset.
Voice_xx functions,
you should do this before calling MikMod_Update.
char* MikMod_strerror(int errno)
Player_Paused, Player_TogglePause, Player_Start, Player_Stop
void Player_Free(MODULE* module)
Player_Load, Player_LoadFP.
int Player_GetChannelVoice(int channel)
Voice_SetPanning, Voice_SetVolume, Player_Mute, Player_ToggleMute, Player_Unmute.
MODULE* Player_GetModule(void)
MODULE being played, or NULL if no module is
playing.
Player_Stop, Player_Start.
MODULE* Player_Load(CHAR* filename,int maxchan,BOOL curious)
MODULE structure, or NULL if an error occurs.
MMERR_MED_SYNTHSAMPLES, and synthsounds are mapped to an empty sample.
Player_Free, Player_LoadFP, Player_LoadTitle, Player_Start.
MODULE* Player_LoadFP(FILE* file,int maxchan,BOOL curious)
MODULE structure, or NULL if an error occurs.
MMERR_MED_SYNTHSAMPLES, and synthsounds are mapped to an empty sample.
Player_Free, Player_Load, Player_LoadTitle, Player_Start.
MODULE* Player_LoadTitle(CHAR* filename)
NULL if either the module has no title
or an error has occurred.
malloc; the caller must free it when it
is no longer necessary.
Player_Load, Player_LoadFP.
void Player_Mute(SLONG operation,...)
MUTE_INCLUSIVE, the two channel numbers delimit the
range and are part of the range ; otherwise, if the operation is
MUTE_EXCLUSIVE, they are outside of the range.
/* mute channel 10 */
Player_Mute(10);
/* mute channels 2 to 5 */
Player_Mute(MUTE_INCLUSIVE,2,5);
/* mute channels 7 to 9 */
Player_Mute(MUTE_EXCLUSIVE,6,10);
Player_Muted, Player_ToggleMute, Player_Unmute.
BOOL Player_Muted(UBYTE channel)
Player_Mute, Player_ToggleMute, Player_Unmute.
void Player_NextPosition(void)
Player_PrevPosition, Player_SetPosition.
Player_TogglePause.
void Player_PrevPosition(void)
Player_NextPosition, Player_SetPosition.
void Player_SetPosition(UWORD position)
Player_NextPosition, Player_PrevPosition.
void Player_SetSpeed(UWORD speed)
Player_SetTempo.
void Player_SetTempo(UWORD tempo)
Player_SetSpeed.
void Player_SetVolume(SWORD volume)
void Player_Start(MODULE* module)
Player_Stop.
Player_Start.
void Player_ToggleMute(SLONG operation,...)
MUTE_INCLUSIVE, the two channel numbers delimit the
range and are part of the range ; otherwise, if the operation is
MUTE_EXCLUSIVE, they are outside of the range.
/* toggle mute on channel 10 */
Player_ToggleMute(10);
/* toggle mute on channels 2 to 5 */
Player_ToggleMute(MUTE_INCLUSIVE,2,5);
/* toggle mute on channels 7 to 9 */
Player_ToggleMute(MUTE_EXCLUSIVE,6,10);
Player_Mute, Player_Muted, Player_Unmute.
Player_xx functions still have effect when the module is paused.
Player_Paused, Player_Start, Player_Stop.
void Player_Unmute(SLONG operation,...)
MUTE_INCLUSIVE, the two channel numbers delimit the
range and are part of the range ; otherwise, if the operation is
MUTE_EXCLUSIVE, they are outside of the range.
/* unmute channel 10 */
Player_Unmute(10);
/* unmute channels 2 to 5 */
Player_Unmute(MUTE_INCLUSIVE,2,5);
/* unmute channels 7 to 9 */
Player_Unmute(MUTE_EXCLUSIVE,6,10);
Player_Mute, Player_Muted, Player_ToggleMute.
void Sample_Free(SAMPLE* sample)
Sample_Load, Sample_LoadFP.
SAMPLE* Sample_Load(CHAR* filename)
SAMPLE structure, or NULL if an error has occurred.
Sample_Free, Sample_LoadFP.
SAMPLE* Sample_LoadFP(FILE* file)
SAMPLE structure, or NULL if an error has occurred.
Sample_Free, Sample_Load.
SBYTE Sample_Play(SAMPLE* sample,ULONG start,UBYTE flags)
SFX_CRITICAL, for critical
sound effects which must not be interrupted.
Voice_Stop to force the end of a critical sample.
MikMod_SetNumVoices, Voice_Play, Voice_SetFrequency, Voice_SetPanning, Voice_SetVolume, Voice_Stop.
SLONG Voice_GetPosition(SBYTE voice)
Sample_Play, Voice_Play.
void Voice_Play(SBYTE voice,SAMPLE* sample,ULONG start)
Sample_Play, Voice_SetFrequency, Voice_SetPanning, Voice_SetVolume.
ULONG Voice_RealVolume(SBYTE voice)
Voice_SetVolume.
Sample_Play, Voice_Play, Voice_SetVolume.
void Voice_SetFrequency(SBYTE voice,ULONG frequency)
Sample_Play, Voice_Play, Voice_SetPanning, Voice_SetVolume, Voice_Stop.
void Voice_SetPanning(SBYTE voice,ULONG panning)
PAN_LEFT) and 255 (PAN_RIGHT). Center
is 127 (PAN_CENTER. Surround sound can be enabled by specifying the
special value PAN_SURROUND.
Sample_Play, Voice_Play, Voice_SetFrequency, Voice_SetVolume, Voice_Stop.
void Voice_SetVolume(SBYTE voice,UWORD volume)
Sample_Play, Voice_Play, Voice_SetFrequency, Voice_SetPanning, Voice_Stop.
Voice_Stop, the function Voice_Stopped will
return nonzero (true) for the voice. If you want to silence the voice without
stopping the playback, use Voice_SetVolume(voice,0) instead.
Sample_Play, Voice_Play, Voice_SetFrequency, Voice_SetPanning, Voice_SetVolume.
BOOL Voice_Stopped(SBYTE voice)
Voice_Stop.
MikMod presents a large choice of module loaders, for the most common formats as well as for some less-known exotic formats.
load_669
load_amf
load_dsm
load_far
load_imf
load_it
load_med
load_m15
load_mod
load_mtm
load_stm
load_stx
load_s3m
load_ult
load_xm
Currently, the only file type than can be loaded as a sample is the RIFF WAVE file. Stereo or compressed WAVE files are not supported yet.
These drivers send the generated sound over the network to a server program, which sends the sound to the real sound hardware. The server program can be on the same machine than your program, but MikMod does not have access to the hardware. Network drivers only support software mixing.
drv_AF
drv_esd
These drivers access to the sound hardware of the machine they run on. Depending on your Unix flavor, you'll end with one or more drivers from this list:
drv_aix
drv_alsa
drv_dart
drv_hp
drv_os2l
drv_os2s
drv_oss
drv_sgi
drv_sun
These drivers work on any machine, since the generated sound is not sent to hardware, but written in a file. Disk writer drivers only support software mixing.
drv_raw
drv_wav
These drivers are of little interest, but are handy sometimes.
drv_stdout
drv_raw disk writer.drv_nos
This document was generated on 14 Febuary 1999 using the texi2html translator version 1.51.