/* ------------------------------------------------------------------------ */
/*  @@ Source Documentation                         *** C Version ***       */
/*                                                                          */
/*  TITLE : DEMOFADE.C                                                      */
/*                                                                          */
/*  DESCRIPTION :                                                           */
/*      This program demostrates how to use the AUXDRV.DRV and              */
/*      CTMIDI.DRV drivers to perform fading effect and volume              */
/*      control on the playing midi file.                                   */
/*                                                                          */
/*      Note that the BLASTER environment has to be set before executing    */
/*      this program.                                                       */
/*                                                                          */
/*  Copyright (c) Creative Technology Ltd, 1993. All rights reserved.       */
/*                                                                          */
/* ------------------------------------------------------------------------ */

#include  <io.h>
#include  <dos.h>
#include  <bios.h>
#include  <fcntl.h>
#include  <stdlib.h>
#include  <io.h>
#include  <conio.h>
#include  <dos.h>

#include  "sbkaux.h"
#include  "sbkmidi.h"
#include  "sbkmacro.h"
#include  "sbkx.h"
#include  "Loaddrv.c"


/* Local functions */
int PrepareCTMIDIDrv(char * BlasterEnv) ;
int PrepareCTAUXDrv(char * BlasterEnv) ;
int PlayMidi (char far * lpMusicBuf) ;
char far * LoadFile (char * szFilename) ;
void SoundEffect (void) ;
void WaitEffectEnd (void) ;

/* Global variable */
volatile WORD wMidiStatus ;         /* Midi music output status */
volatile WORD wFadeStatus ;         /* Fading effect output status */
char far * lpAuxOrigin ;            /* AUX original driver buffer */
char far * lpMidiOrigin;            /* MIDI original driver buffer */


main (int argc, char *argv[])
{
    char * BlasterEnv ;
    char far * lpMidiBuffer ;


    if (argc < 2)
    {
        printf("Usage : DEMOFADE midi_filename\n") ;
        exit(0);
    }

    printf("\nOutput MIDI music with fading effect.") ;


    if ((BlasterEnv = getenv("BLASTER")) == NULL)
    {
        printf("\nBLASTER environment not set.");
        exit(1);
    }

    /* Load CTMIDI.DRV into memory */
    if (!PrepareCTMIDIDrv(BlasterEnv))
    {
        /* Load the AUXDRV.DRV into memory */
        if (!PrepareCTAUXDrv(BlasterEnv))
        {
            /* Initialize CTMIDI.DRV driver */
            if (!ctmdInit())
            {
                /* Load midi file into buffer */
                if ((lpMidiBuffer = LoadFile(argv[1])) != NULL)
                {
                    /* Output MIDI music */
                    if (!PlayMidi(lpMidiBuffer))
                        /* Adds on fading effect */
                        SoundEffect();

                    /* free music buffer */
                    sbkFreeMem(lpMidiBuffer) ;
                }
                /* Terminate CTMIDI.DRV driver */
                ctmdTerminate() ;
            }
        }
    }
    return 0 ;
}


/* ------------------------------------------------------------------------ */
/*  @@ Usage                                                                */
/*                                                                          */
/*  PrepareCTMIDIDrv(char * BlasterEnv)                                     */
/*                                                                          */
/*  Description :                                                           */
/*      Load and endorses CTMIDI.DRV.                                       */
/*                                                                          */
/*  Entry :                                                                 */
/*      BlasterEnv - pointer to the BLASTER enviroment setting.             */
/*                                                                          */
/*  Exit :                                                                  */
/*      zero if sucessful, non-zero otherwise.                              */
/*                                                                          */
/* ------------------------------------------------------------------------ */

int PrepareCTMIDIDrv(char * BlasterEnv)
{
    /* load CTMIDI.DRV driver into memory. */
    if ((CTmidiDrv = (char far *)sbkLoadDriver("CTMIDI.DRV",UNUSED,
                            (char far **)&lpMidiOrigin)) != NULL)
    {
        if (ctmdGetDrvVer() >= 0x0100)
        {
            if (!ctmdGetEnvSettings((char far *)BlasterEnv))
                return(0) ;
            else
                printf("\nBLASTER environment is not valid") ;
        }
        else
        {
            printf("\nInvalid CTMIDI.DRV - ") ;
            printf("I need CTMIDI.DRV version 1.00 or higher.\n") ;
        }
    }
    return(1) ;
}

/* ------------------------------------------------------------------------ */
/*  @@ Usage                                                                */
/*                                                                          */
/*  PrepareCTAUXDrv(char * BlasterEnv)                                      */
/*                                                                          */
/*  Description :                                                           */
/*      Load and endorse AUXDRV.DRV.                                        */
/*                                                                          */
/*  Entry :                                                                 */
/*      BlasterEnv - pointer of the BLASTER environment string.             */
/*                                                                          */
/*  Exit :                                                                  */
/*      zero if sucessful, non-zero otherwise.                              */
/*                                                                          */
/* ------------------------------------------------------------------------ */

int PrepareCTAUXDrv(char * BlasterEnv)
{
    if ((CTAuxDrv = sbkLoadDriver("AUXDRV.DRV",UNUSED,
                        (char far **)&lpAuxOrigin)) != NULL)
    {
        if (ctadGetDrvVer() >= 0x0303)
        {
            if (!ctadGetEnvSettings((char far *)BlasterEnv))
                return(0) ;
            else
                printf("\nBLASTER environment is not valid");
        }
        else
        {
            printf("\nInvalid AUXDRV.DRV - ") ;
            printf("I need AUXDRV.DRV version 3.03 or higher.\n") ;
        }
    }
    return(1) ;
}


/* ------------------------------------------------------------------------ */
/*  @@ Usage                                                                */
/*                                                                          */
/*   int PlayMidi (char far * lpMidiBuffer)                                 */
/*                                                                          */
/*   DESCRIPTION:                                                           */
/*       Play a Midi file in the background and return.                     */
/*                                                                          */
/*   ENTRY:                                                                 */
/*       lpMidiBuffer - pointer to the loaded music buffer.                 */
/*                                                                          */
/*   EXIT:                                                                  */
/*       zero if successful else return 1.                                  */
/*                                                                          */
/* ------------------------------------------------------------------------ */

int PlayMidi (char far * lpMidiBuffer)
{
    int retVal = 1 ;


    /* Reset MIDI device parameter */
    if (!ctmdResetMidiDriver())
    {
        /* Set MIDI output status address */
        if (!ctmdSetOutputStatusAddx((const WORD far *)&wMidiStatus))
        {
            if(!ctmdPrepareMidiStart((const BYTE far *)lpMidiBuffer))
            {
                if(!ctmdPlayMidiMusic())
                    retVal = 0;
            }
        }
        else
            printf("\nError setting MIDI status address.") ;
    }
    else
        printf("\nError resetting MIDI device.") ;

    return (retVal) ;
}


/* ------------------------------------------------------------------------ */
/*  @@ Usage                                                                */
/*                                                                          */
/*   char far * LoadFile (char *szFilename)                                 */
/*                                                                          */
/*   DESCRIPTION:                                                           */
/*       Load file into memory. The Global variable lpMusicBuf is used to   */
/*       point to the loaded buffer.                                        */
/*                                                                          */
/*   ENTRY:                                                                 */
/*       szFileName :- File to be loaded.                                   */
/*                                                                          */
/*   EXIT:                                                                  */
/*       far pointer of the loader music buffer else return 0.              */
/*                                                                          */
/* ------------------------------------------------------------------------ */

char far * LoadFile (char *szFilename)
{
    char    far *lpTmpPtr = 0 ;
    char    far *lpMusicBuf = 0 ;
    int     Handle ;
    WORD    wByteRead ;
    long    lFileSize ;


    /* open file */
    if ((Handle = sbkDosOpen(szFilename)) != -1)
    {
        /* file size */
        lFileSize = filelength(Handle) ;

        /* allocate music buffer */
        if ((lpMusicBuf = sbkAllocMem(lFileSize + 15l)) != NULL)
        {
            lpTmpPtr = lpMusicBuf ;

            do
            {
                FPSEG(lpTmpPtr) += (FPOFF(lpTmpPtr) >> 4) ;
                FPOFF(lpTmpPtr) &= 0x000f ;

                if (sbkDosRead(Handle,(char far *)lpTmpPtr,0x8000,
                                (WORD far *)&wByteRead))
                {
                    printf("\nDOS : Read file error.");
                    wByteRead = 0 ;
                    sbkFreeMem(lpMusicBuf) ;
                    lpMusicBuf = 0 ;
                }
                else
                    FPOFF(lpTmpPtr) += wByteRead ;

            } while (wByteRead == 0x8000);
        }
        else
            printf("\nMemory allocation error.");

        sbkDosClose(Handle) ;
    }
    else
        printf("\nOpen %s failed.",szFilename) ;

    return(lpMusicBuf) ;
}


/* ------------------------------------------------------------------------ */
/*  @@ Usage                                                                */
/*                                                                          */
/*   SoundEffect (void)                                                     */
/*                                                                          */
/*   DESCRIPTION:                                                           */
/*       Adds fading effect on the playback midi.                           */
/*                                                                          */
/*   ENTRY:                                                                 */
/*       None.                                                              */
/*                                                                          */
/*   EXIT:                                                                  */
/*       None.                                                              */
/*                                                                          */
/* ------------------------------------------------------------------------ */

void SoundEffect (void)
{
    WORD  wPrevVol ;


    printf("\nFading effect....\n\n");
    printf("\t[Esc] - to stop\n");
    printf("\t[P  ] - to pause\n");
    printf("\t[C  ] - to continue\n");

    /* initialise AUXDRV.DRV driver */
    ctadInit() ;

    /* preserve the previous MIDI volume settings */
    wPrevVol = ctadGetVolume(MIXERVOL_MIDI) ;

    /* set address of the pan status */
    ctadSetFadeStAddx((WORD far *)&wFadeStatus) ;

    printf("\n");

    while (wMidiStatus)
    {
        /* set MIDI left/right volume to 0x8080 */
        ctadSetVolume(MIXERVOL_MIDI, 0x8080) ;

        /* Setup MIDI volume fading in mode 0 */
        printf("Fading effect...zoommmmm....in... \r");
        ctadFade(MIXERVOL_MIDI, 0xf0f0, 8000, 0, 0 ) ;
        ctadStartCtrl() ;
        WaitEffectEnd() ;

        /* set MIDIleft/right volume to 0xf0f0 */
        ctadSetVolume(MIXERVOL_MIDI,0xf0f0) ;

        /* Setup MIDI volume fading in mode 0 */
        printf("Fading effect...zoommmmm....out...  \r");
        ctadFade(MIXERVOL_MIDI, 0x8080, 8000, 0, 0 ) ;
        ctadStartCtrl() ;
        WaitEffectEnd() ;
    }
    ctmdStopMidiMusic() ;

    printf("\nEnd of fading effect...\n");

    /* set MIDI left/right volume back to previous status */
    ctadSetVolume(MIXERVOL_MIDI, wPrevVol) ;

    /* Terminate AUXDRV.DRV driver */
    ctadTerminate() ;

}


/* ------------------------------------------------------------------------ */
/*  @@ Usage                                                                */
/*                                                                          */
/*   WaitEffectEnd (void)                                                   */
/*                                                                          */
/*   DESCRIPTION:                                                           */
/*       Control fading effect of the digitized sound.                      */
/*                                                                          */
/*   ENTRY:                                                                 */
/*       None                                                               */
/*                                                                          */
/*   EXIT:                                                                  */
/*       None                                                               */
/*                                                                          */
/* ------------------------------------------------------------------------ */

void WaitEffectEnd (void)
{
    int pause = 0 ;


    /* End of sound effect process ? */
    while(wFadeStatus)
    {
        /* Stop effect if no MIDI process */
        if ( !wMidiStatus )
            ctadStopCtrl();

        if (sbkBiosKeybrd(KEYBRD_READY))
        {
            switch (sbkBiosKeybrd(KEYBRD_READ) & 0xff)
            {
                case 0x1b :
                    ctadStopCtrl() ;
                    ctmdStopMidiMusic() ;
                    break ;

                case 'P' :
                case 'p' :
                    if (pause == 0)
                    {
                        printf("Effect pause...                    \r") ;
                        ctadPauseCtrl() ;
                        ctmdPauseMidiMusic() ;
                        pause = 1 ;
                    }
                    break ;

                case 'C' :
                case 'c' :
                    if (pause != 0)
                    {
                        printf("Effect continue...                 \r") ;
                        ctadStartCtrl() ;
                        ctmdResumeMidiMusic() ;
                        pause = 0 ;
                    }
                    break ;
            }
        }
    }
}
/* End of file */
