/* dsmnsnd.c * * Mixing No Sound Sound Device * * $Id: dsmnsnd.c,v 1.2 1997/01/16 18:41:59 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. */ /* None of these functions can fail and practically none of them does anything. */ #include "lang.h" #ifdef __WIN32__ #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif #include "mtypes.h" #include "errors.h" #include "sdevice.h" #include "dsm.h" RCSID(const char *dsmnsnd_rcsid = "$Id: dsmnsnd.c,v 1.2 1997/01/16 18:41:59 pekangas Exp $";) #define MIXRATE 4000 #define MIXMODE dsmMixMono #define OUTPUTMODE sd16bit | sdMono #define MAXTIME 500 #define MINTIME 10 /* A lot of functions do not use their arguments: */ //#ifdef __WATCOMC__ //#pragma off (unreferenced) //#endif /* Names and stuff: */ static char *nsndCard = "No Sound"; /* Variables: */ static DWORD prevPlayTime; static DWORD playElemsLeft; static unsigned nsndMasterVolume; static unsigned updateMix; /* number of elements to mix between two updates */ static unsigned mixLeft; /* number of elements to mix before next update */ /* Local prototypes: */ int CALLING nsndSetUpdRate(unsigned updRate); enum nsndFunctIDs { ID_nsndDetect = ID_nsnd, ID_nsndInit, ID_nsndClose, ID_nsndGetMixRate, ID_nsndGetMode, ID_nsndOpenChans, ID_nsndCloseChans, ID_nsndClearChans, ID_nsndMute, ID_nsndPause, ID_nsndSetMaster, ID_nsndPlaySound, ID_nsndStopSound, ID_nsndSetRate, ID_nsndGetRate, ID_nsndSetVol, ID_nsndSetInst, ID_nsndSetPos, ID_nsndGetPos, ID_nsndSetPanning, ID_nsndGetPanning, ID_nsndMuteChannel, ID_nsndAddInst, ID_nsndRemInst, ID_nsndSetUpdRate, ID_nsndPlay, ID_nsndGetMasterVolume, ID_nsndGetVolume, ID_nsndGetInstrument, ID_nsndStartPlay, ID_nsndSetAmplification, ID_nsndGetAmplification }; static int CALLING nsndDetect(int *result) { /* No Sound is always there */ *result = 1; return OK; } static int CALLING nsndInit(unsigned mixRate, unsigned mode) { int error; /* Initialize DSM - we'll be mixing the data: */ if ( (error = dsmInit(MIXRATE, MIXMODE, 16)) != OK ) PASSERROR(ID_nsndInit); /* Set update rate to 50Hz: */ if ( (error = nsndSetUpdRate(5000)) != OK ) PASSERROR(ID_nsndInit); /* Set real DSM master volume to 0 to speed up mixing: */ if ( (error = dsmSetMasterVolume(0)) != OK ) PASSERROR(ID_nsndInit); /* Initialize "previous" playing tick count: */ #ifdef __WIN32__ prevPlayTime = GetTickCount(); #endif return OK; } static int CALLING nsndClose(void) { int error; /* Just uninitialize DSM: */ if ( (error = dsmClose()) != OK ) PASSERROR(ID_nsndClose); return OK; } int CALLING nsndGetMode(unsigned *mode) { /* Return our default mode: */ *mode = OUTPUTMODE; return OK; } int CALLING nsndSetMasterVolume(unsigned masterVolume) { /* Just store the master volume, don't set it to DSM: */ nsndMasterVolume = masterVolume; return OK; } int CALLING nsndGetMasterVolume(unsigned *masterVolume) { /* Return our stored master vol: */ *masterVolume = nsndMasterVolume; return OK; } int CALLING nsndSetUpdRate(unsigned updRate) { /* Calculate number of elements to mix between two updates: (even) */ mixLeft = updateMix = ((unsigned) ((100L * (ulong) MIXRATE) / ((ulong) updRate)) + 1) & 0xFFFFFFFE; return OK; } int CALLING nsndStartPlay(void) { DWORD time, timeDiff;; /* Get the time in milliseconds since last nsndStartPlay(): */ #ifdef __WIN32__ time = GetTickCount(); #endif timeDiff = time - prevPlayTime; prevPlayTime = time; /* Restrict the time difference to reasonable values: */ if ( timeDiff > MAXTIME ) timeDiff = MAXTIME; if ( timeDiff < MINTIME ) timeDiff = 0; /* Calculate the number of elements that fits into this time - it is the amount we'll mix this polling time: */ playElemsLeft = (timeDiff * MIXRATE) / 1000; return OK; } int CALLING nsndPlay(int *callMP) { int error; unsigned dsmBufSize; unsigned numElems, doNow; if ( !playElemsLeft ) { *callMP = 0; return OK; } #ifdef __32__ dsmBufSize = dsmMixBufferSize >> 2; #else dsmBufSize = dsmMixBufferSize >> 1; #endif #if MIXMODE == dsmMixStereo dsmBufSize >>= 1; #endif if ( playElemsLeft > mixLeft ) numElems = mixLeft; else numElems = playElemsLeft; mixLeft -= numElems; playElemsLeft -= numElems; while ( numElems ) { if ( numElems > dsmBufSize ) doNow = dsmBufSize; else doNow = numElems; numElems -= doNow; if ( (error = dsmMixData(doNow)) != OK ) PASSERROR(ID_nsndPlay) } /* Check if the music player should be called: */ if ( mixLeft == 0 ) { mixLeft = updateMix; *callMP = 1; } else { *callMP = 0; } return OK; } /* And the struct: */ SoundDevice MixNoSound = { 0, /* Poll to tempo */ sdUseDSM, 0, 0, 0, 1, 1, sdMono | sd16bit, "Mixing No Sound Sound Device", &nsndCard, 0, NULL, &nsndDetect, &nsndInit, &nsndClose, &dsmGetMixRate, &nsndGetMode, &dsmOpenChannels, &dsmCloseChannels, &dsmClearChannels, &dsmMute, &dsmPause, &dsmSetMasterVolume, &dsmGetMasterVolume, &dsmSetAmplification, &dsmGetAmplification, &dsmPlaySound, &dsmReleaseSound, &dsmStopSound, &dsmSetRate, &dsmGetRate, &dsmSetVolume, &dsmGetVolume, &dsmSetSample, &dsmGetSample, &dsmSetPosition, &dsmGetPosition, &dsmGetDirection, &dsmSetPanning, &dsmGetPanning, &dsmMuteChannel, &dsmAddSample, &dsmRemoveSample, &nsndSetUpdRate, &nsndStartPlay, &nsndPlay #ifdef SUPPORTSTREAMS , &dsmStartStream, &dsmStopStream #endif }; /* * $Log: dsmnsnd.c,v $ * Revision 1.2 1997/01/16 18:41:59 pekangas * Changed copyright messages to Housemarque * * Revision 1.1 1996/07/29 19:35:39 pekangas * Initial revision * * Revision 1.1 1996/05/22 20:49:33 pekangas * Initial revision * */