/**************************************************************************** File : sosmawe.c Purpose : Module to handle AWE32 .SBK file uploads Date : 1-20-95 Programmer(s) : Don Fowler Last Updated : 1-29-95 **************************************************************************** Copyright(c) 1992,1995 Human Machine Interfaces All Rights Reserved ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "sosm.h" WORD sosMIDIAWE32SetSBKFile( WORD, PSTR ); WORD sosMIDIAWE32ReleaseSBKFiles( WORD ); WORD sosMIDIAWE32NoteOn( WORD, WORD, WORD, WORD, WORD, WORD ); WORD sosMIDIAWE32NoteOff( WORD, WORD, WORD ); // maximum number of .SBK files that can be set on the chip #define _MAX_SBKS 0x10 // offset into slot list for .SBK files to start #define _SBK_SLOT_OFFSET 0x01 // size of buffer needed to read in a chunk of .SBK file #define _READ_BUFFER_SIZE 0x2000 // pointer to preset data for awe32 #ifdef BORLAND PSTR _lpSOSMIDIAwe32PresetBuffer[ _SOS_MIDI_MAX_DRIVERS ][ _MAX_SBKS ] = { #else LPSTR _lpSOSMIDIAwe32PresetBuffer[ _SOS_MIDI_MAX_DRIVERS ][ _MAX_SBKS ] = { #endif { _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL }, { _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL }, { _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL }, { _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL }, { _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL } }; // index into list of presets to the currently available slot, // start the index at 0 to leave slot 0 open for general midi // rom on the AWE32 WORD _wSOSMIDIAwe32PresetIndex[ _SOS_MIDI_MAX_DRIVERS ] = { _SBK_SLOT_OFFSET, _SBK_SLOT_OFFSET, _SBK_SLOT_OFFSET, _SBK_SLOT_OFFSET, _SBK_SLOT_OFFSET }; /*************************************************************************** Function : WORD sosMIDIAWE32SetSBKFile Parameters : WORD hDriver Handle of SOS driver to set SBK file on. PSTR szFileName Name of .SBK file to set. Returns : -1 if error; otherwise, slot that the .SBK file was assigned to on the AWE32. Description : Stream a .SBK file onto the awe32 and return the slot streamed to. ****************************************************************************/ WORD sosMIDIAWE32SetSBKFile( WORD hDriver, PSTR szFileName ) { WORD wIndex; WORD hFile; WORD wReadSize; PSTR pDataPtr; #ifdef BORLAND SFAR lpTemp; #endif // attempt to find a slot to use for the .SBK file if( _wSOSMIDIAwe32PresetIndex[ hDriver ] == ( _MAX_SBKS - 1 ) ) return( -1 ); // attempt to open the sbk file if( ( hFile = open( ( const char * )szFileName, O_RDONLY | O_BINARY ) ) == -1 ) return( -1 ); // attempt to allocate a buffer to use for transfer if( !( pDataPtr = ( PSTR )malloc( _READ_BUFFER_SIZE ) ) ) { // close the file close( hFile ); // return an error return( -1 ); } // open the awe32 stream #ifdef BORLAND if( ( wReadSize = sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 5 ], lpTemp, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 ) #else if( ( wReadSize = _lpSOSMIDIDrvFunction[ hDriver ][ 5 ]( _NULL, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 ) #endif { // free the previously allocated memory free( pDataPtr ); // close the file close( hFile ); // return error return( -1 ); } // read in a chunk of data from the file if( read( hFile, pDataPtr, wReadSize ) == -1 ) return( -1 ); // get the sample data seek location #ifdef BORLAND lpTemp.sel = getDS(); lpTemp.off = pDataPtr; if( ( wIndex = sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 8 ], lpTemp, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 ) #else if( ( wIndex = _lpSOSMIDIDrvFunction[ hDriver ][ 8 ]( ( LPSTR )pDataPtr, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 ) #endif { // free the previously allocated memory free( pDataPtr ); // close the file close( hFile ); // return error return( -1 ); } // seek the file to the sample location if( lseek( hFile, wIndex, SEEK_SET ) == -1 ) { // close the file close( hFile ); // free the preset memory free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] ); // return an error return( -1 ); } // send chunks of data to the driver do { // read in a chunk of data from the file if( read( hFile, pDataPtr, wReadSize ) == -1 ) return( -1 ); // send the data to the driver #ifdef BORLAND lpTemp.sel = getDS(); lpTemp.off = pDataPtr; if( ( wReadSize = sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ] [ 6 ], lpTemp, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 ) #else if( ( wReadSize = _lpSOSMIDIDrvFunction[ hDriver ][ 6 ]( ( LPSTR )pDataPtr, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 ) #endif { // close the file close( hFile ); // free the memory free( pDataPtr ); // return an error return( -1 ); } } while( wReadSize ); // free the temporary memory buffer free( pDataPtr ); // get the preset data size #ifdef BORLAND wReadSize = sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 7 ], lpTemp, 0x00, 0x00 ); #else wReadSize = _lpSOSMIDIDrvFunction[ hDriver ][ 7 ]( _NULL, 0x00, 0x00 ); #endif // get the preset location in the file #ifdef BORLAND lpTemp.sel = getDS(); lpTemp.off = &wIndex; sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 9 ], lpTemp, 0x00, 0x00 ); #else _lpSOSMIDIDrvFunction[ hDriver ][ 9 ]( ( LPSTR )&wIndex, 0x00, 0x00 ); #endif // allocate the memory for the preset information #ifdef BORLAND if( !( _lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] = ( PSTR )malloc( wReadSize ) ) ) #else if( !( _lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] = ( LPSTR )malloc( wReadSize ) ) ) #endif { // close the file close( hFile ); // return an error return( -1 ); } // seek the file to the preset location if( lseek( hFile, wIndex, SEEK_SET ) == -1 ) { // close the file close( hFile ); // free the preset memory free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] ); // return an error return( -1 ); } // read in the preset information if( read( hFile, ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ], wReadSize ) == -1 ) { // close the file close( hFile ); // free the preset memory free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] ); // return an error return( -1 ); } // send the preset information to the driver #ifdef BORLAND lpTemp.sel = getDS(); lpTemp.off = _lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ]; if( ( sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 10 ], lpTemp, 0x00, 0x00 ) ) == -1 ) #else if( ( _lpSOSMIDIDrvFunction[ hDriver ][ 10 ]( ( LPSTR ) _lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ], 0x00, 0x00 ) ) == -1 ) #endif { // free the preset memory free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] ); // close the file close( hFile ); // return an error return( -1 ); } // close the SBK file close( hFile ); // increment the preset buffer index to the next available slot _wSOSMIDIAwe32PresetIndex[ hDriver ]++; // return no error return( _wSOSMIDIAwe32PresetIndex[ hDriver ] ); } /*************************************************************************** Function : WORD sosMIDIAWE32ReleaseAllSBKFiles Parameters : WORD hDriver Handle of SOS driver to release .SBK files from Returns : -1 if error; otherwise, _ERR_NO_ERROR Description : Release all of the memory associated to the .SBK files uploaded to the awe32. ****************************************************************************/ WORD sosMIDIAWE32ReleaseSBKFiles( WORD hDriver ) { WORD wIndex; #ifdef BORLAND SFAR lpTemp; #endif // call the driver to release all of the .SBK files #ifdef BORLAND if( sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 9 ], lpTemp, 0x01, 0x00 ) == -1 ) #else if( _lpSOSMIDIDrvFunction[ hDriver ][ 9 ]( ( LPSTR )_NULL, 0x01, 0x00 ) == -1 ) #endif return( -1 ); // free the memory allocated for the awe32 preset information for( wIndex = _SBK_SLOT_OFFSET; wIndex < _wSOSMIDIAwe32PresetIndex[ hDriver ]; wIndex++ ) free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ wIndex ] ); // reset the available slot index _wSOSMIDIAwe32PresetIndex[ hDriver ] = _SBK_SLOT_OFFSET; // return no error return( _ERR_NO_ERROR ); } /*************************************************************************** Function : WORD sosMIDIAWE32NoteOn Parameters : WORD hDriver Handle of SOS driver WORD wSlot .SBK file slot to associate patch to WORD wChannel Channel to use WORD wPatch Patch to use WORD wNote MIDI relative pitch to use WORD wVelocity Velocity to use Returns : -1 if error; otherwise, _ERR_NO_ERROR Description : Turn a note on ****************************************************************************/ WORD sosMIDIAWE32NoteOn( WORD hDriver, WORD wSlot, WORD wChannel, WORD wPatch, WORD wNote, WORD wVelocity ) { BYTE szMIDIData[ 0x10 ]; // setup the midi data structure to associate a slot to a channel szMIDIData[ 0 ] = 0xb0 | wChannel; szMIDIData[ 1 ] = 0x00; szMIDIData[ 2 ] = wSlot; #ifdef BORLAND sosMIDISendMIDIData( hDriver, ( PSTR )szMIDIData, 0x03 ); #else sosMIDISendMIDIData( hDriver, ( LPSTR )szMIDIData, 0x03 ); #endif // select the patch for the channel szMIDIData[ 0 ] = 0xc0 | wChannel; szMIDIData[ 1 ] = wPatch; #ifdef BORLAND sosMIDISendMIDIData( hDriver, ( PSTR )szMIDIData, 0x02 ); #else sosMIDISendMIDIData( hDriver, ( LPSTR )szMIDIData, 0x02 ); #endif // turn the note on with the correct pitch and attack szMIDIData[ 0 ] = 0x90 | wChannel; szMIDIData[ 1 ] = wNote; szMIDIData[ 2 ] = wVelocity; #ifdef BORLAND sosMIDISendMIDIData( hDriver, ( PSTR )szMIDIData, 0x02 ); #else sosMIDISendMIDIData( hDriver, ( LPSTR )szMIDIData, 0x02 ); #endif // return no error return( _ERR_NO_ERROR ); } /*************************************************************************** Function : WORD sosMIDIAWE32NoteOff Parameters : WORD hDriver Handle of SOS driver WORD wChannel Channel to use WORD wNote MIDI relative pitch to use Returns : -1 if error; otherwise, _ERR_NO_ERROR Description : Turn a note on ****************************************************************************/ WORD sosMIDIAWE32NoteOff( WORD hDriver, WORD wChannel, WORD wNote ) { BYTE szMIDIData[ 0x10 ]; // turn the note off szMIDIData[ 0 ] = 0x90 | wChannel; szMIDIData[ 1 ] = wNote; szMIDIData[ 2 ] = 0x00; #ifdef BORLAND sosMIDISendMIDIData( hDriver, ( PSTR )szMIDIData, 0x03 ); #else sosMIDISendMIDIData( hDriver, ( LPSTR )szMIDIData, 0x03 ); #endif // return no error return( _ERR_NO_ERROR ); }