home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------------------------------ */
- /* @@ Source Documentation *** TC Version *** */
- /* */
- /* Copyright (c) Creative Technology Pte Ltd, 1991. All rights reserved. */
- /* */
- /* TITLE : DEMOCMF.C */
- /* */
- /* DESCRIPTION : */
- /* This program demonstrates how to use the SBFM high level functions */
- /* to play back the music file FFARES.CMF. The user is allowed to */
- /* control the music output from the keyboard. */
- /* */
- /* Note that the BLASTER environment has to be set and SBFMDRV.COM */
- /* has to be installed before executing this program. */
- /* */
- /* ------------------------------------------------------------------------ */
-
- #include <io.h>
- #include <dos.h>
- #include <bios.h>
- #include <fcntl.h>
- #include <sbcmusic.h>
- #include <sbc.h>
-
- #define FPSEG(fp) (*((unsigned far *)&(fp)+1))
- #define FPOFF(fp) (*((unsigned far *)&(fp)))
-
-
- char far *lpMusicBuf = 0 ;
- char cTranspose = 0 ;
-
- main()
- {
- unsigned wVersion;
-
-
- if ( sbfm_init() )
- {
- wVersion = sbfm_version() ;
-
- printf("Driver version %d.%02d\n",wVersion >> 8,wVersion & 255) ;
-
- PlayCmfFile("FFARES.CMF") ;
-
- sbfm_terminate() ;
- }
- else
- printf("SBFMDRV not installed or FM Driver initialization error.\n") ;
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* @@ Usage */
- /* */
- /* PlayCmfFile (char *szFilename) */
- /* */
- /* DESCRIPTION: */
- /* Play a CMF file and wait for music to end. */
- /* */
- /* ENTRY: */
- /* szFileName :- Music file to be played. */
- /* */
- /* EXIT: */
- /* None. */
- /* */
- /* ------------------------------------------------------------------------ */
-
- PlayCmfFile (char *szFilename)
- {
- if ( LoadFile(szFilename) )
- {
- StartMusic() ;
- WaitMusicEnd() ;
- }
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* @@ Usage */
- /* */
- /* 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: */
- /* Non-Zero if successful, else returns 0. */
- /* */
- /* ------------------------------------------------------------------------ */
-
- LoadFile (char *szFilename)
- {
- char far *lpTmpPtr ;
- int Handle ;
- unsigned wByteRead, RetVal = 0 ;
- long lFileSize ;
-
-
- /* set the default file mode to binary mode */
- _fmode = O_BINARY;
-
- /* open file */
- if ( (Handle=_open(szFilename,O_RDONLY)) != -1 )
- {
- lFileSize = filelength(Handle) ;
-
- if ( allocmem((unsigned)((lFileSize+15) >> 4),&wByteRead) == -1 )
- {
- FPSEG(lpMusicBuf) = wByteRead ;
- FPOFF(lpMusicBuf) = 0 ;
-
- lpTmpPtr = lpMusicBuf ;
-
- RetVal = 1;
-
- do
- {
- if ( DosRead(Handle,lpTmpPtr,0x8000,&wByteRead))
- {
- if ( !(FPOFF(lpTmpPtr) += wByteRead) )
- FPSEG(lpTmpPtr) += 0x1000 ;
- }
- else
- {
- printf("Load file error.\n");
- wByteRead = 0 ;
- RetVal = 0 ;
- freemem(FPSEG(lpMusicBuf)) ;
- }
-
- } while (wByteRead == 0x8000) ;
- }
- else
- printf("Memory allocation error.\n");
-
- _close(Handle) ;
- }
- else
- printf("Open %s fails.\n",szFilename) ;
-
-
- return(RetVal) ;
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* @@ Usage */
- /* */
- /* StartMusic (void) */
- /* */
- /* DESCRIPTION: */
- /* Retrieves music information from the CMF music file header and */
- /* starts playing music. */
- /* */
- /* ENTRY: */
- /* None. */
- /* */
- /* EXIT: */
- /* None. */
- /* */
- /* ------------------------------------------------------------------------ */
-
- StartMusic (void)
- {
- char far *lpInstPtr ;
- char far *lpMusicPtr ;
- int Timer0Freq ;
-
-
- /* get instrument block and music block address */
- lpInstPtr = lpMusicBuf + *(int far*)(lpMusicBuf + 6) ;
- lpMusicPtr = lpMusicBuf + *(int far*)(lpMusicBuf + 8) ;
-
- sbfm_reset() ;
-
- /* set song speed */
- Timer0Freq = (int)(1193180L / (*(int far*)(lpMusicBuf + 12))) ;
- sbfm_song_speed(Timer0Freq) ;
-
- /* set instrument table */
- if (FPOFF(lpInstPtr))
- sbfm_instrument(lpInstPtr,*(lpMusicBuf+0x24)) ;
-
- sbfm_play_music(lpMusicPtr) ;
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* @@ Usage */
- /* */
- /* WaitMusicEnd (void) */
- /* */
- /* DESCRIPTION: */
- /* Control the music output from keyboard. */
- /* */
- /* ENTRY: */
- /* None. */
- /* */
- /* EXIT: */
- /* None. */
- /* */
- /* ------------------------------------------------------------------------ */
-
- #pragma loop_opt(off)
- WaitMusicEnd (void)
- {
- unsigned wKey, wStatus ;
-
-
- while( (wStatus = sbfm_read_status()) != 0 )
- {
- if (wStatus != 255)
- printf("Status: %c - %d\n",wStatus,wStatus) ;
-
- if (bioskey(1))
- {
- if ((wKey=bioskey(0)) & 0xff)
- wKey = toupper(wKey & 255) ;
-
- switch(wKey)
- {
- case 0x1b : sbfm_stop_music() ;
- break ;
- case 0x4b00 : sbfm_transpose(--cTranspose) ;
- printf("Transpose: %d\n",cTranspose) ;
- break ;
- case 0x4d00 : sbfm_transpose(++cTranspose) ;
- printf("Transpose: %d\n",cTranspose) ;
- break ;
- case 'P' : sbfm_pause_music() ;
- break ;
- case 'C' : sbfm_resume_music() ;
- break ;
- }
- }
- }
- }
- #pragma loop_opt()
-
-
- /* ------------------------------------------------------------------------ */
- /* @@ Usage */
- /* */
- /* DosRead (int Handle, char far *Buffer, */
- /* unsigned wLen, unsigned *lpByteRead) */
- /* */
- /* DESCRIPTION: */
- /* DOS read function using DOS interrupt 0x21 function 0x3F. */
- /* */
- /* ENTRY: */
- /* Handle :- File handle to read. */
- /* Buffer :- Buffer to write to. */
- /* wLen :- Number of byte to read. */
- /* lpByteRead :- pointer to number of byte actually read. */
- /* */
- /* EXIT: */
- /* Byte read if successful, else returns 0. */
- /* */
- /* ------------------------------------------------------------------------ */
-
- DosRead (int Handle, char far *Buffer, unsigned wLen, unsigned *wByteRead)
- {
- union REGS regs;
- struct SREGS segregs;
-
-
- regs.h.ah = 0x3f ;
- regs.x.bx = Handle;
- regs.x.dx = FPOFF(Buffer);
- regs.x.cx = wLen;
- segregs.ds = FPSEG(Buffer);
-
- intdosx(®s, ®s, &segregs);
-
- if(regs.x.cflag) /* error */
- *wByteRead = 0;
- else
- *wByteRead = regs.x.ax ;
-
-
- return(*wByteRead);
- }
-