/* midasdll.c
*
* MIDAS DLL programming interface
*
* $Id: midasdll.c,v 1.6 1997/01/16 19:57:19 pekangas Exp $
*
* Copyright 1996,1997 Housemarque Inc.
*
* This file is part of the MIDAS Sound System, and may only be
* used, modified and distributed under the terms of the MIDAS
* Sound System license, LICENSE.TXT. By continuing to use,
* modify or distribute this file you indicate that you have
* read the license and understand and accept it fully.
*/
#if defined(__NT__) || defined(__WINDOWS__)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include "midas.h"
/* This is a kluge, but necessary as Watcom C sucks: */
#if defined(DLL_EXPORT)
#define EXPORT_IN_MIDASDLL_H
#endif
#include "midasdll.h"
RCSID(const char *midasdll_rcsid = "$Id: midasdll.c,v 1.6 1997/01/16 19:57:19 pekangas Exp $";)
/* Channel numbers used with gmpPlaySong(): */
static unsigned midasSDChannels[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31 };
static int lastError;
static int MIDASthread = 0;
#ifdef __WIN32__
static volatile int DLLinUse = 0;
#endif
static int midasFxInit, midasStrInit;
_FUNC(int) MIDASgetLastError(void)
{
return lastError;
}
_FUNC(char*) MIDASgetErrorMessage(int errorCode)
{
return errorMsg[errorCode];
}
/****************************************************************************\
*
* Function: BOOL MIDASstartup(void)
*
* Description: Sets all configuration variables to default values and
* prepares MIDAS for use. This function must be called before
* ANY other MIDAS function, including MIDASinit and
* MIDASsetOption. After this function has been called,
* MIDASclose can be called at any point, regarless of whether
* MIDAS has been initialized or not.
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASstartup(void)
{
MIDASthread = 0;
midasFxInit = 0;
midasStrInit = 0;
midasSetDefaults();
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASdetectSD(void)
*
* Description: Attempts to detect a Sound Device. Sets the global variable
* midasSD to point to the detected Sound Device or NULL if no
* Sound Device was detected
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASdetectSD(void)
{
int dsd;
int error;
static int dResult;
midasSD = NULL; /* no Sound Device detected yet */
midasSDNumber = -1;
dsd = 0; /* start from first Sound Device */
/* search through Sound Devices until a Sound Device is detected: */
while ( (midasSD == NULL) && (dsd < NUMSDEVICES) )
{
/* attempt to detect current SD: */
if ( (error = (*midasSoundDevices[dsd]->Detect)(&dResult)) != OK )
{
lastError = error;
return FALSE;
}
if ( dResult == 1 )
{
midasSDNumber = dsd; /* Sound Device detected */
/* point midasSD to this Sound Device: */
midasSD = midasSoundDevices[dsd];
}
dsd++; /* try next Sound Device */
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL midasInit(void);
*
* Description: Initializes MIDAS Sound System
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASinit(void)
{
int error;
static int dResult;
midasEMSInit = 0;
mUseEMS = 0;
if ( midasSDNumber == -1 ) /* has a Sound Device been selected? */
{
/* attempt to detect Sound Device */
if ( !MIDASdetectSD() )
{
return FALSE;
}
if ( midasSD == NULL )
{
lastError = errSDFailure;
return FALSE;
}
}
else
{
/* use selected Sound Device: */
midasSD = midasSoundDevices[midasSDNumber];
/* Sound Device number was forced, but if no I/O port, IRQ, DMA or
sound card type has been set, try to autodetect the values for this
Sound Device. If detection fails, use default values: */
if ( (midasSDPort == -1) && (midasSDIRQ == -1) &&
(midasSDDMA == -1) && (midasSDCard == -1) )
if ( (error = midasSD->Detect(&dResult)) != OK )
{
lastError = error;
return FALSE;
}
}
if ( midasSDPort != -1 ) /* has an I/O port been selected? */
midasSD->port = midasSDPort; /* if yes, set it to Sound Device */
if ( midasSDIRQ != -1 ) /* SD IRQ number? */
midasSD->IRQ = midasSDIRQ; /* if yes, set it to Sound Device */
if ( midasSDDMA != -1 ) /* SD DMA channel number? */
midasSD->DMA = midasSDDMA;
if ( midasSDCard != -1 ) /* sound card type? */
midasSD->cardType = midasSDCard;
#if defined (__DOS__) && (!defined(NOTIMER))
/* initialize TempoTimer: */
if ( (error = tmrInit()) != OK )
{
lastError = error;
return FALSE;
}
midasTMRInit = 1; /* TempoTimer initialized */
#endif
/* initialize Sound Device: */
if ( (error = midasSD->Init(midasMixRate, midasOutputMode)) != OK )
{
lastError = error;
return FALSE;
}
midasSDInit = 1; /* Sound Device initialized */
#if defined (__DOS__) && (!defined(NOTIMER))
/* start playing sound using the timer: */
if ( (error = tmrPlaySD(midasSD)) != OK )
{
lastError = error;
return FALSE;
}
midasTMRPlay = 1;
#endif
/* Initialize Generic Module Player: */
if ( (error = gmpInit(midasSD)) != OK )
{
lastError = error;
return FALSE;
}
midasGMPInit = 1;
/* Initialize Sound Effects library: */
if ( (error = fxInit(midasSD)) != OK )
{
lastError = error;
return FALSE;
}
midasFxInit = 1;
#ifdef SUPPORTSTREAMS
/* Initialize stream player library: */
if ( (error = strInit(midasSD)) != OK )
{
lastError = error;
return FALSE;
}
midasStrInit = 1;
#endif
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASclose(void)
*
* Description: Uninitializes MIDAS Sound System
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASclose(void)
{
int error;
#if defined(__WIN32__) || defined(__LINUX__)
/* Stop playing thread: */
if ( MIDASthread )
MIDASstopBackgroundPlay();
#endif
#if defined (__DOS__) && (!defined(NOTIMER))
/* if music is being played with timer, stop it: */
if ( midasTMRMusic )
{
if ( (error = gmpSetUpdRateFunct(NULL)) != OK )
{
lastError = error;
return FALSE;
}
if ( (error = tmrStopMusic(midasPlayerNum)) != OK )
{
lastError = error;
return FALSE;
}
midasTMRMusic = 0;
}
#endif
#ifdef SUPPORTSTREAMS
/* Uninitialize stream player if initialized: */
if ( midasStrInit )
{
if ( (error = strClose()) != OK )
{
lastError = error;
return FALSE;
}
midasStrInit = 0;
}
#endif
/* Uninitialize sound effect library if initialized: */
if ( midasFxInit )
{
if ( (error = fxClose()) != OK )
{
lastError = error;
return FALSE;
}
midasFxInit = 0;
}
/* If music is being played, stop it: */
if ( midasGMPPlay )
{
if ( (error = gmpStopSong(midasPlayHandle)) != OK )
{
lastError = error;
return FALSE;
}
midasGMPPlay = 0;
}
/* If Generic Module Player has been initialized, uninitialize it: */
if ( midasGMPInit )
{
if ( (error = gmpClose()) != OK )
{
lastError = error;
return FALSE;
}
midasGMPInit = 0;
}
/* if Sound Device channels are open, close them: */
if ( midasSDChans )
{
if ( (error = midasSD->CloseChannels()) != OK )
{
lastError = error;
return FALSE;
}
midasSDChans = 0;
midasChannels = 0;
}
#if defined (__DOS__) && (!defined(NOTIMER))
/* if sound is being played, stop it: */
if ( midasTMRPlay )
{
if ( (error = tmrStopSD()) != OK )
{
lastError = error;
return FALSE;
}
midasTMRPlay = 0;
}
#endif
/* if Sound Device is initialized, uninitialize it: */
if ( midasSDInit )
{
if ( (error = midasSD->Close()) != OK )
{
lastError = error;
return FALSE;
}
midasSDInit = 0;
midasSD = NULL;
}
#if defined (__DOS__) && (!defined(NOTIMER))
/* if TempoTimer is initialized, uninitialize it: */
if ( midasTMRInit )
{
if ( (error = tmrClose()) != OK )
{
lastError = error;
return FALSE;
}
midasTMRInit = 0;
}
#endif
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASclose(void)
*
* Description: Uninitializes MIDAS Sound System
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(char*) MIDASgetVersionString(void)
{
return MVERSTR;
}
/****************************************************************************\
*
* Function: BOOL MIDASopenChannels(int numChans);
*
* Description: Opens Sound Device channels for sound and music output.
*
* Input: int numChans Number of channels to open
*
* Notes: Channels opened with this function can be used for sound
* playing, and modules played with midasPlayModule() will be
* played through the last of these channels. This function is
* provided so that the same number of channels can be open
* the whole time throughout the execution of the program,
* keeping the volume level constant. Note that you must ensure
* that you open enough channels for all modules, otherwise
* midasPlayModule() will fail.
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASopenChannels(int numChans)
{
int error;
midasChannels = numChans;
/* open Sound Device channels: */
if ( (error = midasSD->OpenChannels(numChans)) != OK )
{
lastError = error;
return FALSE;
}
midasSDChans = 1;
/* set amplification level if forced: */
if ( midasAmplification != -1 )
{
if ( (error = midasSD->SetAmplification(midasAmplification)) != OK )
{
lastError = error;
return FALSE;
}
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDAScloseChannels(void);
*
* Description: Closes Sound Device channels opened with midasOpenChannels().
* Do NOT call this function unless you have opened the sound
* channels used yourself with midasOpenChannels().
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDAScloseChannels(void)
{
int error;
/* Close Sound Device channels: */
if ( (error = midasSD->CloseChannels()) != OK )
{
lastError = error;
return FALSE;
}
midasSDChans = 0;
midasChannels = 0;
return TRUE;
}
/****************************************************************************\
*
* Function: MIDASmodule MIDASloadModule(char *fileName)
*
* Description: Loads a module into memory
*
* Input: char *fileName module file name
*
* Returns: Module handle if successful, NULL if failed
*
\****************************************************************************/
_FUNC(MIDASmodule) MIDASloadModule(char *fileName)
{
static fileHandle f;
static char buf[64];
int error;
static gmpModule *module;
/* Check the module type and use the correct module loader
(fixme, hardwired types and poor detection) */
if ( (error = fileOpen(fileName, fileOpenRead, &f)) != OK )
{
lastError = error;
return FALSE;
}
if ( (error = fileRead(f, buf, 48)) != OK )
{
fileClose(f);
lastError = error;
return FALSE;
}
if ( (error = fileClose(f)) != OK )
{
lastError = error;
return FALSE;
}
if ( mMemEqual(buf, "Extended Module:", 16) )
{
/* It's a FastTracker module: */
error = gmpLoadXM(fileName, 1, NULL, &module);
}
else
{
if ( mMemEqual(buf+44, "SCRM", 4) )
{
/* It's a Scream Tracker 3 module */
error = gmpLoadS3M(fileName, 1, NULL, &module);
}
else
{
/* None of the above - we'll assume it's a Protracker module,
the loader will fail if this is not the case */
error = gmpLoadMOD(fileName, 1, NULL, &module);
}
}
if ( error != OK )
{
lastError = error;
return NULL;
}
return (MIDASmodule) module;
}
/****************************************************************************\
*
* Function: BOOL MIDASplayModule(MIDASmodule module,
* int numEffectChannels)
*
* Description: Starts playing a Generic Module Player module loaded to memory
*
* Input: gmpModule *module Pointer to loaded module structure
* int numEffectChns Number of channels to open for sound
* effects. Ignored if sound channels
* have already been opened with
* midasOpenChannels().
*
* Returns: TRUE if successful, FALSE if not
*
* Notes: The Sound Device channels available for sound effects are the
* _first_ numEffectChns channels. So, for example, if you use
* midasPlayModule(module, 3), you can use channels 0-2 for sound
* effects. If you already have opened channels with
* midasOpenChannels(), the module will be played with the last
* possible channels, so that the first channels will be
* available for sound effects. Note that if not enough channels
* are open this function will fail.
*
\****************************************************************************/
_FUNC(BOOL) MIDASplayModule(MIDASmodule module, int numEffectChannels)
{
short numChans;
int error;
int firstChannel;
gmpModule *gmpmod = (gmpModule*) module;
numChans = gmpmod->numChannels;
/* Open Sound Device channels if not already open: */
if ( midasChannels == 0 )
{
if ( (error = midasSD->OpenChannels(numChans + numEffectChannels))
!= OK )
{
lastError = error;
return FALSE;
}
midasSDChans = 1;
firstChannel = numEffectChannels;
/* set amplification level if forced: */
if ( midasAmplification != -1 )
{
if ( (error = midasSD->SetAmplification(midasAmplification))
!= OK )
{
lastError = error;
return FALSE;
}
}
}
else
{
if ( midasChannels < numChans )
{
lastError = errNoChannels;
return FALSE;
}
firstChannel = midasChannels - numChans;
}
/* Start playing the whole song in the module using the last Sound Device
channels: */
if ( (error = gmpPlaySong(gmpmod , -1, -1, -1, -1,
&midasSDChannels[firstChannel], &midasPlayHandle)) != OK )
{
lastError = error;
return FALSE;
}
midasGMPPlay = 1;
#if defined (__DOS__) && (!defined(NOTIMER))
/* Start playing using the timer: */
if ( (error = tmrPlayMusic(&gmpPlay, &midasPlayerNum)) != OK )
{
lastError = error;
return FALSE;
}
if ( (error = gmpSetUpdRateFunct(&tmrSetUpdRate)) != OK )
{
lastError = error;
return FALSE;
}
midasTMRMusic = 1;
#endif
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASstopModule(gmpModule *module)
*
* Input: gmpModule *module the module which is being played
*
* Description: Stops playing a module and uninitializes the Module Player.
* If sound channels were NOT opened through midasOpenChannels(),
* but by letting midasPlayModule() open them, they will be
* closed. Sound channels opened with midasOpenChannels() are NOT
* closed and must be closed separately.
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASstopModule(MIDASmodule module)
{
int error, i;
gmpModule *gmpmod = (gmpModule*) module;
#if defined (__DOS__) && (!defined(NOTIMER))
/* Stop playing music with timer: */
if ( (error = gmpSetUpdRateFunct(NULL)) != OK )
{
lastError = error;
return FALSE;
}
if ( (error = tmrStopMusic(midasPlayerNum)) != OK )
{
lastError = error;
return FALSE;
}
midasTMRMusic = 0;
#endif
/* Stop playing the module: */
if ( (error = gmpStopSong(midasPlayHandle)) != OK )
{
lastError = error;
return FALSE;
}
midasGMPPlay = 0;
midasPlayHandle = NULL;
/* If Sound Device channels were not opened with midasOpenChannels(),
close them: */
if ( midasChannels == 0 )
{
if ( (error = midasSD->CloseChannels()) != OK )
{
lastError = error;
return FALSE;
}
midasSDChans = 0;
}
else
{
/* Sound Device channels were originally opened with
midasOpenChannels(). Now stop sounds from the channels used by
the Module Player: */
for ( i = (midasChannels - gmpmod->numChannels); i < midasChannels;
i++ )
{
if ( (error = midasSD->StopSound(i)) != OK )
{
lastError = error;
return FALSE;
}
if ( (error = midasSD->SetVolume(i, 0)) != OK )
{
lastError = error;
return FALSE;
}
}
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASfreeModule(MIDASmodule module)
*
* Description: Deallocates a module loaded with MIDASloadModule();
*
* Input: DWORD module module handle
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASfreeModule(MIDASmodule module)
{
int error;
if ( (error = gmpFreeModule((gmpModule*) module)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASstartBackgroundPlay(DWORD pollRate)
*
* Description: Starts playing music in the background
*
* Input: DWORD pollRate polling rate (in Hz - polls per
* second)
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASstartBackgroundPlay(DWORD pollRate)
{
#if defined(__WIN32__) || defined(__LINUX__)
DWORD pollPeriod;
/* Calculate delay between polls - default is 20ms, otherwise calculate
delay based on rate, and divide by two to make sure polling is done
at least often enough */
if ( !pollRate )
pollPeriod = 20;
else
pollPeriod = 1000 / pollRate / 2;
StartPlayThread(pollPeriod);
MIDASthread = 1;
#else
pollRate = pollRate;
#endif
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASstopBackgroundPlay(void)
*
* Description: Stops playing music in the background
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASstopBackgroundPlay(void)
{
#if defined(__WIN32__) || defined(__LINUX__)
if ( !MIDASthread )
return TRUE;
StopPlayThread();
MIDASthread = 0;
#endif
return TRUE;
}
#if defined(__WIN32__) || defined(__LINUX__)
/****************************************************************************\
*
* Function: BOOL MIDASpoll(void)
*
* Description: Polls the sound and music player manually
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASpoll(void)
{
PollMIDAS();
return TRUE;
}
#endif /* #if defined(__WIN32__) || defined(__LINUX__) */
/****************************************************************************\
*
* Function: BOOL MIDASsetOption(int option, int value);
*
* Description: Sets a MIDAS option
*
* Input: int option option (see enum MIDASoptions)
* int value value for the option
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetOption(int option, int value)
{
switch ( option )
{
case MIDAS_OPTION_MIXRATE:
midasMixRate = value;
return TRUE;
case MIDAS_OPTION_OUTPUTMODE:
midasOutputMode = value;
return TRUE;
case MIDAS_OPTION_MIXBUFLEN:
mBufferLength = value;
return TRUE;
case MIDAS_OPTION_MIXBUFBLOCKS:
mBufferBlocks = value;
return TRUE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: MIDASsample MIDASloadRawSample(char *filename, int sampleType,
* int loopSample)
*
* Description: Loads a raw sound effect sample
*
* Input: char *filename sample file name
* int sampleType sample type
* int loopSample 1 if sample should be looped
*
* Returns: MIDAS sample handle, NULL if failed
*
\****************************************************************************/
_FUNC(MIDASsample) MIDASloadRawSample(char *fileName, int sampleType,
int loopSample)
{
int error;
static unsigned sampleHandle;
/* Load the sample: */
if ( (error = fxLoadRawSample(fileName, sampleType, loopSample,
&sampleHandle)) != OK )
{
lastError = error;
return 0;
}
return sampleHandle;
}
/****************************************************************************\
*
* Function: BOOL MIDASfreeSample(MIDASsample sample)
*
* Description: Deallocates a sample
*
* Input: MIDASsample sample sample to be deallocated
*
* Returns: TRUE if succesful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASfreeSample(MIDASsample sample)
{
int error;
if ( (error = fxFreeSample(sample)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetAutoEffectChannels(unsigned firstChannel,
* unsigned numChannels)
*
* Description: Sets the range of channels that can be used for automatic
* sound effect channels
*
* Input: unsigned firstChannel first channel to use
* unsigned numChannels number of channels to use
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetAutoEffectChannels(unsigned firstChannel,
unsigned numChannels)
{
unsigned *numbers;
int error;
unsigned i;
unsigned n;
/* Allocate memory for channel number table: */
if ( (error = memAlloc(numChannels * sizeof(unsigned), (void**) &numbers))
!= OK )
{
lastError = error;
return FALSE;
}
/* Fill the table with the channel numbers: */
n = firstChannel;
for ( i = 0; i < numChannels; i++ )
numbers[i] = n++;
/* Set the channels: */
if ( (error = fxSetAutoChannels(numChannels, numbers)) != OK )
{
memFree(numbers);
lastError = error;
return FALSE;
}
/* Free the number table: */
if ( (error = memFree(numbers)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: MIDASsamplePlayHandle MIDASplaySample(MIDASsample sample,
* unsigned channel, int priority, unsigned rate,
* unsigned volume, int panning)
*
* Description: Plays a sound effect sample
*
* Input: MIDASsample sample sample to be played
* unsigned channel channel the sample should be played
* on, MIDAS_CHANNEL_AUTO for automatic
* selection
* int priority sample playing priority, the higher
* the value the higher the priority
* unsigned rate initial sample rate
* unsigned volume initial volume
* int panning initial panning position
*
* Returns: Sample playing handle or NULL if failed
*
\****************************************************************************/
_FUNC(MIDASsamplePlayHandle) MIDASplaySample(MIDASsample sample,
unsigned channel, int priority, unsigned rate, unsigned volume,
int panning)
{
int error;
static unsigned playHandle;
if ( (error = fxPlaySample(channel, sample, priority, rate, volume,
panning, &playHandle)) != OK )
{
lastError = error;
return 0;
}
/* KLUGE! Add 1 to the handle to make sure NULL is an illegal handle: */
return playHandle + 1;
}
/****************************************************************************\
*
* Function: BOOL MIDASstopSample(MIDASsamplePlayHandle sample)
*
* Description: Stops playing a sample
*
* Input: MIDASsamplePlayHandle sample sample playing handle
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASstopSample(MIDASsamplePlayHandle sample)
{
int error;
if ( (error = fxStopSample(sample-1)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetSampleRate(MIDASsamplePlayHandle sample,
* unsigned rate)
*
* Description: Changes the sample rate for a sound effect sample that is
* being played
*
* Input: MIDASsamplePlayHandle sample sample to change
* unsigned rate new rate
*
* Returns: TRUE if succesful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetSampleRate(MIDASsamplePlayHandle sample, unsigned rate)
{
int error;
if ( (error = fxSetSampleRate(sample-1, rate)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetSampleVolume(MIDASsamplePlayHandle sample,
* unsigned volume)
*
* Description: Changes the volume for a sound effect sample that is being
* played
*
* Input: MIDASsamplePlayHandle sample sample to change
* unsigned volume new volume
*
* Returns: TRUE if succesful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetSampleVolume(MIDASsamplePlayHandle sample,
unsigned volume)
{
int error;
if ( (error = fxSetSampleVolume(sample-1, volume)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetSamplePanning(MIDASsamplePlayHandle sample,
* int panning)
*
* Description: Changes the panning position of a sound effect sample that is
* being played
*
* Input: MIDASsamplePlayHandle sample sample to change
* int panning new panning position
*
* Returns: TRUE if succesful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetSamplePanning(MIDASsamplePlayHandle sample,
int panning)
{
int error;
if ( (error = fxSetSamplePanning(sample-1, panning)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetSamplePriority(MIDASsamplePlayHandle sample,
* int priority)
*
* Description: Changes the playing priority of a sound effect sample that is
* being played
*
* Input: MIDASsamplePlayHandle sample sample to change
* int priority new playing priority
*
* Returns: TRUE if succesful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetSamplePriority(MIDASsamplePlayHandle sample,
int priority)
{
int error;
if ( (error = fxSetSamplePriority(sample-1, priority)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASgetPlayStatus(MIDASplayStatus *status)
*
* Description: Gets current module playing status
*
* Input: MIDASplayStatus *status pointer to status structure
*
* Returns: TRUE if successful, FALSE if not.
* Module playing status will be written to *status
*
\****************************************************************************/
_FUNC(BOOL) MIDASgetPlayStatus(MIDASplayStatus *status)
{
static gmpInformation *gmpInfo;
int error;
/* Check that we really are playing something: */
if ( midasPlayHandle == NULL )
{
status->position = status->pattern = status->row = 0;
return TRUE;
}
/* Get information from GMPlayer: */
if ( (error = gmpGetInformation(midasPlayHandle, &gmpInfo)) != OK )
{
lastError = error;
return FALSE;
}
/* Copy them: */
status->position = gmpInfo->position;
status->pattern = gmpInfo->pattern;
status->row = gmpInfo->row;
status->syncInfo = gmpInfo->syncInfo;
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetPosition
*
* Description: Sets module playback position
*
* Input: int newPosition new position
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetPosition(int newPosition)
{
int error;
if ( midasPlayHandle == NULL )
return TRUE;
if ( (error = gmpSetPosition(midasPlayHandle, newPosition)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetMusicVolume
*
* Description: Sets module playback volume
*
* Input: unsigned volume new volume
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetMusicVolume(unsigned volume)
{
if ( midasPlayHandle == NULL )
return TRUE;
midasPlayHandle->masterVolume = volume;
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASgetModuleInfo(MIDASmodule module,
* MIDASmoduleInfo *info)
*
* Description: Gets information about a module
*
* Input: MIDASmodule module MIDAS module handle
* MIDASmoduleInfo *info pointer to module info structure
*
* Returns: TRUE if successful, FALSE if not. Module information is
* written to *info.
*
\****************************************************************************/
_FUNC(BOOL) MIDASgetModuleInfo(MIDASmodule module, MIDASmoduleInfo *info)
{
gmpModule *gmpMod = (gmpModule*) module;
if ( module == NULL )
{
lastError = errInvalidArguments;
return FALSE;
}
mMemCopy(info->songName, gmpMod->name, 32);
info->songName[31] = 0;
info->songLength = gmpMod->songLength;
info->numInstruments = gmpMod->numInsts;
info->numPatterns = gmpMod->numPatts;
info->songLength = gmpMod->songLength;
info->numChannels = gmpMod->numChannels;
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASgetInstrumentInfo(MIDASmodule module, int instNum,
* MIDASinstrumentInfo *info);
*
* Description: Gets information about an instrument in a module
*
* Input: MIDASmodule module MIDAS module handle
* int instNum instrument number
* MIDASinstrumentInfo *info pointer to destination info struct
*
* Returns: TRUE if successful, FALSE if not. Instrument information is
* written to *info.
*
\****************************************************************************/
_FUNC(BOOL) MIDASgetInstrumentInfo(MIDASmodule module, int instNum,
MIDASinstrumentInfo *info)
{
gmpModule *gmpMod = (gmpModule*) module;
if ( (module == NULL) || (((unsigned) instNum) >= gmpMod->numInsts) )
{
lastError = errInvalidArguments;
return FALSE;
}
mMemCopy(info->instName, gmpMod->instruments[instNum]->name, 32);
info->instName[31] = 0;
return TRUE;
}
#ifdef SUPPORTSTREAMS
/****************************************************************************\
*
* Function: MIDASstreamHandle MIDASplayStreamFile(unsigned channel,
* char *fileName, unsigned sampleType, unsigned sampleRate,
* unsigned bufferLength, int loopStream)
*
* Description: Starts playing a digital audio stream from a file
*
* Input: unsigned channel channel to play the stream on
* char *fileName stream file name
* unsigned sampleType stream sample type
* unsigned sampleRate stream sampling rate
* unsigned bufferLength stream buffer length in milliseconds
* int loopStream 1 if stream should be looped
*
* Returns: Stream handle or NULL if failed
*
\****************************************************************************/
_FUNC(MIDASstreamHandle) MIDASplayStreamFile(unsigned channel,
char *fileName, unsigned sampleType, unsigned sampleRate,
unsigned bufferLength, int loopStream)
{
int error;
strStream *stream;
if ( (error = strPlayStreamFile(channel, fileName, sampleType, sampleRate,
bufferLength, loopStream, &stream)) != OK )
{
lastError = error;
return NULL;
}
return (MIDASstreamHandle) stream;
}
/****************************************************************************\
*
* Function: BOOL MIDASstopStream(MIDASstreamHandle stream)
*
* Description: Stops playing a stream
*
* Input: MIDASstreamHandle stream stream to be stopped
*
* Returns: TRUE if succesful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASstopStream(MIDASstreamHandle stream)
{
int error;
if ( (error = strStopStream((strStream*) stream)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: MIDASstreamHandle MIDASplayStreamPolling(unsigned channel,
unsigned sampleType, unsigned sampleRate,
unsigned bufferLength);
*
* Description: Starts playing a stream in polling mode. Use
* MIDASfeedStreamData() to feed the stream data to the player
*
* Input: unsigned channel channel number for the stream
* unsigned sampleType stream sample type
* unsigned sampleRate stream sampling rate
* unsigned bufferLength stream buffer length in milliseconds
*
* Returns: Stream handle or NULL if failed
*
\****************************************************************************/
_FUNC(MIDASstreamHandle) MIDASplayStreamPolling(unsigned channel,
unsigned sampleType, unsigned sampleRate, unsigned bufferLength)
{
int error;
strStream *stream;
if ( (error = strPlayStreamPolling(channel, sampleType, sampleRate,
bufferLength, &stream)) != OK )
{
lastError = error;
return NULL;
}
return (MIDASstreamHandle) stream;
}
/****************************************************************************\
*
* Function: unsigned MIDASfeedStreamData(MIDASstreamHandle stream,
unsigned char *data, unsigned numBytes, BOOL feedAll)
* Description: Feeds sample data to a stream that is being played in polling
* mode.
*
* Input: MIDASstreamHandle stream Stream playing handle
* uchar *data pointer to stream data
* unsigned numBytes number of bytes of data to feed. Note!
* This must be a multiple of the stream
* sample size
* BOOL feedAll TRUE if all data should be fed in all
* circumstances. The function will block
* the current thread if this flag is 1
* until all data is fed.
*
* Returns: The number of bytes of sample data that was actually fed.
*
\****************************************************************************/
_FUNC(unsigned) MIDASfeedStreamData(MIDASstreamHandle stream,
unsigned char *data, unsigned numBytes, BOOL feedAll)
{
int error;
unsigned numFed;
int iFeedAll;
if ( feedAll )
iFeedAll = 1;
else
iFeedAll = 0;
if ( (error = strFeedStreamData((strStream*) stream, data, numBytes,
iFeedAll, &numFed)) != OK )
{
lastError = error;
return 0;
}
return numFed;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetStreamRate(MIDASstreamHandle stream,
* unsigned rate)
*
* Description: Changes the playback rate of a stream
*
* Input: MIDASstreamHandle stream Stream playing handle
* unsigned rate New playback sample rate, in Hz
*
* Returns: TRUE if succesful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetStreamRate(MIDASstreamHandle stream, unsigned rate)
{
int error;
if ( (error = strSetStreamRate((strStream*) stream, rate)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetStreamVolume(MIDASstreamHandle stream,
* unsigned volume)
*
* Description: Changes the playback volume of a stream
*
* Input: MIDASstreamHandle stream Stream playing handle
* unsigned volume New volume
*
* Returns: TRUE if succesful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetStreamVolume(MIDASstreamHandle stream, unsigned volume)
{
int error;
if ( (error = strSetStreamVolume((strStream*) stream, volume)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
/****************************************************************************\
*
* Function: BOOL MIDASsetStreamPanning(MIDASstreamHandle stream,
* int panning)
*
* Description: Changes the panning position of a stream
*
* Input: MIDASstreamHandle stream Stream playing handle
* int panning New panning position
*
* Returns: TRUE if succesful, FALSE if not
*
\****************************************************************************/
_FUNC(BOOL) MIDASsetStreamPanning(MIDASstreamHandle stream, int panning)
{
int error;
if ( (error = strSetStreamPanning((strStream*) stream, panning)) != OK )
{
lastError = error;
return FALSE;
}
return TRUE;
}
#endif /* #ifdef SUPPORTSTREAMS */
#ifdef __WIN32__
int PASCAL WEP(short nParameter)
{
/* The DLL is being unloaded by a process */
/* Stop playing in a thread: */
if ( MIDASthread )
{
MIDASstopBackgroundPlay();
}
/* Close MIDAS - this can safely be done many times: */
MIDASclose();
DLLinUse = 0;
return 1;
}
/* The DLL main: */
int APIENTRY LibMain(HANDLE hdll, DWORD reason, LPVOID reserved)
{
switch ( reason )
{
case DLL_PROCESS_ATTACH:
/* The DLL is loaded by a process. Check that the DLL is not in
use by some other process, and if not, mark that we are in use
and set to default config: */
if ( DLLinUse )
return 0; /* Only one program can use MIDAS */
DLLinUse = 1;
MIDASstartup();
break;
case DLL_PROCESS_DETACH:
/* The DLL is being unloaded by a process */
/* Stop playing in a thread: */
if ( MIDASthread )
{
MIDASstopBackgroundPlay();
}
/* Close MIDAS - this can safely be done many times: */
MIDASclose();
DLLinUse = 0;
break;
/* We aren't interested in thread creation */
}
return 1;
}
#endif /* #ifdef __WIN32__ */
/*
* $Log: midasdll.c,v $
* Revision 1.6 1997/01/16 19:57:19 pekangas
* Removed a couple of Visual C warnings
*
* Revision 1.5 1997/01/16 19:43:55 pekangas
* Removed a warning
*
* Revision 1.4 1997/01/16 18:41:59 pekangas
* Changed copyright messages to Housemarque
*
* Revision 1.3 1997/01/16 18:26:27 pekangas
* Added numerous new functions
*
* Revision 1.2 1996/12/07 22:19:56 pekangas
* No change
*
* Revision 1.1 1996/09/25 18:38:02 pekangas
* Initial revision
*
*/