home *** CD-ROM | disk | FTP | other *** search
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: ADMCEDIT.C
- *
- *
- * Copyright (c) IBM Corporation 1991, 1993
- * All Rights Reserved
- *
- * DESCRIPTIVE: Digital Audio clipboard manipulation and error
- * detection source file
- *
- * FUNCTION: Holds subroutines and flag checking routines for the
- * mci editing operations (e.g. cut/copy/paste/delete).
- *
- *
- * NOTES: Concepts illustrated in this source file:
- * A. How to process MCI_FROM / MCI_TO for edit operations
- * ( CheckEditFlags).
- * B. Determine default from/to positions.
- * C. Generic stream abort routine
- * D. Retrieving information from the clipboard.
- * E. Placing information into the clipboard.
- * F. Using mmio memory files to manipulate clipboard data.
- *
- * ENTRY POINTS:
- * LINKAGE: CALL FAR
- *
- *
- * EXIT-NORMAL: MCIERR_SUCCESS
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES:
- *
- ********************** END OF SPECIFICATIONS **********************/
-
- #define INCL_WINCLIPBOARD
- #define INCL_WINWINDOWMGR
- #define INCL_DOSSEMAPHORES
- #define INCL_DOSPROCESS
- #define INCL_ERRORS
- #define INCL_WINATOM
- #define INCL_HEAP
- #define INCL_DOSMEMMGR
-
- #include <os2.h> // OS2 defines.
- #include <string.h> // String functions.
- #include <stdio.h>
- #include <bsememf.h>
- #include <os2medef.h> // MME includes files.
- #include <mmioos2.h> // MMIO Include.
- #include <mcios2.h>
- #include <audio.h> // Audio Device Defines.
- #include <ssm.h> // SSM spi includes.
- #include <meerror.h> // MM Error Messages.
- #include <mmdrvos2.h> // MCI Driver Include.
- #include <mmio.h> // MMIO Include.
- #include <mcd.h> // AudioIFDriverInterface.
- #include <hhpheap.h> // Heap Manager Definitions
- #include <qos.h>
- #include <audiomcd.h> // Component Definitions
- #include "admcfunc.h" // Function Prototypes
- #include "admcres.h" // Definition for bitmap resource
- #ifndef TOOLKIT
- #include <convert.h> // Data conversion routines
- #endif
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: CheckEditFlags
- *
- * DESCRIPTIVE Ensures that editing functions have valid flags.
- *
- * FUNCTION: Checks to see if memory is correctly allocated, from/to
- * flags if the exist are valid, ensures that a file element
- * is loaded (if no buffer is passed) and aborts any in
- * progress commands.
- *
- * NOTES:
- *
- * ENTRY POINTS:
- * LINKAGE: CALL FAR
- *
- * INPUT: MCI_STOP message.
- *
- * EXIT-NORMAL: MCIERR_SUCCESS
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES:
- *
- *********************** END OF SPECIFICATIONS **********************/
-
-
-
- RC CheckEditFlags( FUNCTION_PARM_BLOCK *pFuncBlock,
- ULONG ulMCIMajic )
-
- {
-
- ULONG ulParam1; // Flags for this Msg
- ULONG ulParam2; // Data for this Msg
- ULONG ulrc; // Error Code Propogated
- ULONG ulFromRequest; // Position to operate from
- ULONG ulToRequest = 0; // Position to operate to
- ULONG ulFileLength; // File length--used in range checking
-
- ULONG ulEditFlags;
- ULONG ulAbortNotify=FALSE;// Flag to abort preceding commands
- ULONG ulOldTimeFormat; // Old Time Format
-
- LONG lTempVal;
- LONG lFromPosition;
-
- MCI_EDIT_PARMS *pEditParms;
-
- INSTANCE *ulpInstance; // Local Instance
-
- /********************************************
- * Dereference Pointers From Thread Block
- ********************************************/
-
- ulParam1 = pFuncBlock->ulParam1;
- ulParam2 = pFuncBlock->ulParam2;
- ulrc = MCIERR_SUCCESS;
- ulpInstance = (INSTANCE *) pFuncBlock->ulpInstance;
-
-
- /*******************************************
- * Ensure that the caller passed valid
- * edit parms to us.
- ********************************************/
-
- ulrc = CheckMem ( (PVOID) ulParam2,
- sizeof (MCI_EDIT_PARMS),
- PAG_READ | PAG_WRITE );
-
- if (ulrc != MCIERR_SUCCESS)
- {
- return (MCIERR_MISSING_PARAMETER);
- }
-
- pEditParms = (MCI_EDIT_PARMS *) ulParam2;
-
- /*********************************
- * Mask the flags the we support
- **********************************/
-
- ulEditFlags = pFuncBlock->ulParam1;
-
- if ( !ulMCIMajic )
- {
- ulEditFlags &= ~( MCI_FROM + MCI_TO + MCI_NOTIFY + MCI_WAIT +
- MCI_CONVERT_FORMAT + MCI_FROM_BUFFER + MCI_TO_BUFFER );
- }
- else
- {
- ulEditFlags &= ~( MCI_WAIT + MCI_NOTIFY );
- }
-
- /* If the caller passed in an unsupported flag--return an error */
-
- if ( ulEditFlags )
- return ( MCIERR_INVALID_FLAG );
-
-
- if ( ( ulParam1 & MCI_FROM_BUFFER ) && ( ulParam1 & MCI_TO_BUFFER ) )
- return ( MCIERR_INVALID_FLAG );
-
-
-
- /*********************************************
- * If the user passed in a buffer, ensure that
- * that it contains a valid pointer.
- *******************************************/
-
-
-
- if ( ( ulParam1 & MCI_FROM_BUFFER ) || ( ulParam1 & MCI_TO_BUFFER ) )
- {
-
-
- /********************************************************
- * When the buffer flags are passed in the caller is also
- * responsible for passing in a valid mmaudioheader in
- * the case of waveaudio.
- *********************************************************/
-
- ulrc = CheckMem ( (PVOID) pEditParms->pHeader,
- sizeof ( MMAUDIOHEADER ),
- PAG_READ | PAG_WRITE );
-
- if (ulrc != MCIERR_SUCCESS)
- {
- return ( MCIERR_INVALID_BUFFER );
- }
-
-
- ulrc = CheckMem ( (PVOID) pEditParms->pBuff,
- sizeof ( pEditParms->ulBufLen ),
- PAG_READ | PAG_WRITE );
-
- if (ulrc != MCIERR_SUCCESS)
- {
- return ( MCIERR_INVALID_BUFFER );
- }
-
-
-
-
- }
-
- /*******************************************
- * If a playlist is active, the only way to
- * use the MCI_EDITING functions is to
- * use a buffer since mmio commands do not
- * work on playlists.
- *******************************************/
-
- if ( ulpInstance->usPlayLstStrm &&
- ( !(ulParam1 & MCI_FROM_BUFFER ) || !(ulParam1 & MCI_TO_BUFFER ) ) )
- {
- return ( MCIERR_UNSUPPORTED_FUNCTION );
- }
-
- /*******************************************
- * Ensure that there is a file to operate on
- * if this is not a playlist and the buffer
- * flag has not been sent.
- *******************************************/
-
- if ( ulpInstance->usPlayLstStrm == FALSE &&
- ulpInstance->fFileExists != TRUE)
- {
- return ( MCIERR_FILE_NOT_FOUND );
- }
-
- /*******************************************
- * Ensure that there is a file to operate on
- * if this is not a playlist and the buffer
- * flag has not been sent.
- *******************************************/
-
- if ( AMPMIX.ulDataType != DATATYPE_WAVEFORM )
- {
- return ( MCIERR_UNSUPPORTED_FUNCTION );
- }
-
- /*****************************************
- * To ensure proper syncronization, acquire
- * the semaphore which is used to control
- * who can check to see which processes are
- * active. This function will also tell us
- * if there is an operation to abort or
- * supercede.
- ******************************************/
-
- GetNotifyAbortAccess ( ulpInstance, &ulAbortNotify );
-
- /*******************************************
- * If there is an operation active (i.e. a
- * play, record or save) then post a message
- * stating that the command has been
- * aborted (record or play) or
- * wait for completion (save).
- ********************************************/
-
- if ( ulAbortNotify )
- {
- /* Stop the command on another thread */
-
- GenericThreadAbort( ulpInstance, pFuncBlock, 0 );
-
- } /* There was a pending Notify */
-
-
-
- if ( STRMSTATE != MCI_STOP &&
- ulpInstance->ulCreateFlag == PREROLL_STATE )
- {
- ulrc = StopStream( ulpInstance, OPERATION_PLAY );
-
- if ( ulrc )
- {
- return( ulrc );
- }
- } /* If the stream is not in a stopped state */
-
-
-
- /*********************************************
- * In order to determine if the edit request
- * is valid, we must retrieve the length of
- * the file.
- *
- * Note: the length of the file is returned in
- * the time units we are using currently.
- *********************************************/
-
- ConvertTimeUnits ( ulpInstance,
- &ulFileLength,
- FILE_LENGTH);
-
- if ( ulParam1 & MCI_FROM )
- {
- /* The from request MUST be within the limits of the current file */
-
- if ( pEditParms->ulFrom > ulFileLength )
- {
- return ( MCIERR_OUTOFRANGE );
- } /* request greater than file length */
-
- /* Convert the MCI_FROM position to bytes. */
-
- if ( ulpInstance->ulTimeUnits != lBYTES )
- {
- // investigate combining this into one routine
-
- ulOldTimeFormat = ulpInstance->ulTimeUnits;
-
- ulrc = ConvertToMM ( ulpInstance,
- &ulFromRequest,
- pEditParms->ulFrom );
-
- ulpInstance->ulTimeUnits = lBYTES;
-
- /* Convert number to bytes */
- ConvertTimeUnits ( ulpInstance,
- &ulFromRequest,
- ulFromRequest );
-
- ulpInstance->ulTimeUnits = ulOldTimeFormat;
- }
- else
- {
- ulFromRequest = pEditParms->ulFrom;
- }
-
- lFromPosition = ulFromRequest;
-
- } /* MCI_FROM flag passed */
-
-
- /*******************************************************
- * In order to be valid, an MCI_TO request must
- * A. Be less than the file length.
- * B. Be less than the MCI_FROM position if specified.
- * C. If no from flag is specified, be less than the
- * current file position.
- ********************************************************/
-
- if ( ulParam1 & MCI_TO )
- {
- /* The TO request MUST be within the limits of the current file */
-
-
- if ( ulParam1 & MCI_FROM )
- {
- if ( pEditParms->ulTo <= pEditParms->ulFrom )
- {
- return ( MCIERR_OUTOFRANGE );
- }
- } /* MCI_FROM flag passed */
-
- // /********************************************
- // * If no from flag was passed, edit operations
- // * assume the current file position as the
- // * start--if so, then ensure that the to point
- // * is not behind our current position.
- // *********************************************/
- //
- // if ( ulpInstance->ulCreateFlag == PREROLL_STATE )
- // {
- // /**********************************************
- // * Get the current stream time, it will be used
- // * for range checking below.
- // ***********************************************/
- //
- // ulrc = SpiGetTime( STREAM.hStream,
- // ( PMMTIME ) &( STREAM.mmStreamTime ) );
- //
- // if ( ulrc )
- // {
- // return ( ulrc );
- // }
- //
- // // investigate --combine into function.
- //
- // ulOldTimeFormat = ulpInstance->ulTimeUnits;
- //
- // ulpInstance->ulTimeUnits = lBYTES;
- //
- // ConvertTimeUnits ( ulpInstance,
- // &ulToPosition,
- // STREAM.mmStreamTime );
- //
- // ulpInstance->ulTimeUnits = ulOldTimeFormat;
- //
- // } /* if a stream has been created */
- // else
- // {
- // lTempVal = mmioSeek( ulpInstance->hmmio,
- // 0,
- // SEEK_CUR );
- //
- // if ( lTempVal == MMIO_ERROR )
- // {
- // return ( MMIOERR_SEEK_FAILED );
- // }
- //
- // ulToPosition = ( ULONG ) lTempVal;
- // } /* else there is no stream active */
-
- /************************************************
- * Convert the MCI_TO request to mmtime,
- * then to bytes so we can compare it with
- * the current file position (which is in bytes).
- ************************************************/
-
- if ( ulpInstance->ulTimeUnits != lBYTES )
- {
- // investigate --combine into function.
- ulOldTimeFormat = ulpInstance->ulTimeUnits;
-
- ulrc = ConvertToMM ( ulpInstance,
- &ulToRequest,
- pEditParms->ulTo );
-
- ulpInstance->ulTimeUnits = lBYTES;
-
- ConvertTimeUnits ( ulpInstance,
- &ulToRequest,
- ulToRequest );
-
- ulpInstance->ulTimeUnits = ulOldTimeFormat;
- }
- else
- {
- ulToRequest = pEditParms->ulTo;
- }
-
- // what does this do?
-
- // if ( ulToPosition < ulToRequest )
- // {
- // return ( MCIERR_OUTOFRANGE );
- // }
-
-
- if ( pEditParms->ulTo > ulFileLength )
- // pEditParms->ulTo > ulToRequest )
- {
- return ( MCIERR_OUTOFRANGE );
- } /* request greater than file length or current position */
-
-
- } /* The MCI_TO flag was passed in */
-
-
-
- /* If undo or redo call, we are done */
-
- if ( ulMCIMajic )
- {
- return ( MCIERR_SUCCESS );
- }
-
- /*********************************************
- * All of the edit routines operate on a byte
- * wise basis, therefore, convert the from/to
- * numbers to bytes here so that code will not
- * be replicated.
- **********************************************/
-
- if ( ulParam1 & MCI_FROM )
- {
-
- /*********************************************
- * If we have a 16 bit file and the request
- * starts in the midst of a sample, move to
- * the beginning of the sample.
- **********************************************/
-
- if ( WAVEHDR.usBitsPerSample == 16 &&
- ulFromRequest % 2 )
- {
- ulFromRequest--;
- }
-
- pEditParms->ulFrom = ulFromRequest;
-
- }
-
- if ( ulParam1 & MCI_TO )
- {
-
- /*********************************************
- * If we have a 16 bit file and the to request
- * ends in the midst of a sample, move to
- * the beginning of the sample.
- **********************************************/
-
- if ( WAVEHDR.usBitsPerSample == 16 &&
- ulToRequest % 2 )
- {
- ulToRequest--;
- }
-
- /* We had previously converted this number to bytes */
-
- pEditParms->ulTo = ulToRequest;
- }
-
-
- return ( MCIERR_SUCCESS );
-
- } /* CheckEditFlags */
-
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: GetFromToPosition
- *
- * DESCRIPTIVE Returns the actual from/to position for edit operations.
- *
- * FUNCTION: Will place the file the correct spot for from/to edit
- * operations. If either of the flags is not set, then it
- * retrieves the defaults (current position for MCI_FROM, and
- * end of file for MCI_TO ).
- *
- * NOTES:
- *
- * ENTRY POINTS:
- * LINKAGE: CALL FAR
- *
- * INPUT: MCI_STOP message.
- *
- * EXIT-NORMAL: MCIERR_SUCCESS
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES:
- *
- *********************** END OF SPECIFICATIONS **********************/
-
- RC GetFromToPosition( LONG lCurrFilePos,
- ULONG ulParam1,
- MCI_EDIT_PARMS *pEditParms,
- INSTANCE *ulpInstance,
- PULONG pulFromPosition,
- PULONG pulToPosition )
-
-
- {
- LONG lTempPosition; // temporary file position used by seek
-
-
- if ( ulParam1 & MCI_FROM )
- {
- /********************************************************
- * If we are not currently at the place the caller wants
- * to copy from, seek there
- ********************************************************/
-
- if ( pEditParms->ulFrom != ( ULONG ) lCurrFilePos )
- {
- lTempPosition = mmioSeek( ulpInstance->hmmio,
- pEditParms->ulFrom,
- SEEK_SET );
-
- if ( lTempPosition == MMIO_ERROR )
- {
- return ( MMIOERR_SEEK_FAILED );
- }
-
- } /* if we are not at the from position */
-
- *pulFromPosition = pEditParms->ulFrom;
-
- } /* if the from flag was specified */
- else
- {
- *pulFromPosition = lCurrFilePos;
-
- } /* else the from flag was not specified */
-
- if ( ulParam1 & MCI_TO )
- {
- *pulToPosition = pEditParms->ulTo;
-
- } /* MCI_TO flag specified */
-
- else
- {
- /* if no MCI_TO, we will operate to the end of file */
-
- *pulToPosition = XWAVHDR.ulAudioLengthInBytes;
- } /* no MCI_TO flag */
-
- return ( MCIERR_SUCCESS );
-
- } /* GetFromToPosition */
-
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: GetClipboardData
- *
- * DESCRIPTIVE Gets digital audio information from the clipboard.
- *
- * FUNCTION: Checks to see if the correct audio format is in the
- * clipboard, if it is, a buffer is allocated and filled
- * with wave information.
- *
- * NOTES:
- *
- * ENTRY POINTS:
- * LINKAGE: CALL FAR
- *
- * INPUT: MCI_STOP message.
- *
- * EXIT-NORMAL: Return Code 0.
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES: spiStopStream () - SSM Spi
- *
- *********************** END OF SPECIFICATIONS **********************/
-
- RC GetClipboardData( PVOID *pBuffer,
- INSTANCE *pInstance,
- ULONG ulOperation,
- PULONG pulBuffLen,
- ULONG ulParam1,
- PMMAUDIOHEADER pmmaudioheader )
-
- {
- HAB habClipboard;
- HMQ hmq;
-
- BOOL fCreatedMQ = TRUE; /* message queue creation? */
-
- HMMIO hmmioMem; /* handle to memory file */
-
- MMIOINFO mmioinfo; /* info struct for memory file */
-
- ULONG ulFormatInfo = 0;
- ULONG rc;
- PULONG pulDataSize;
-
- LONG lBytesRead;
- LONG lReturnCode;
-
- MMAUDIOHEADER mmaudioheader;
- MMAUDIOHEADER mmaudioheaderTemp;
-
-
- PSZ pTempBuffer;
- PVOID pNewBuffer;
-
-
- habClipboard = WinInitialize( 0 );
- if ( !habClipboard )
- {
- return ( MCIERR_CLIPBOARD_ERROR );
- }
-
- hmq = WinCreateMsgQueue( habClipboard, 0 );
-
- if ( !hmq )
- {
- fCreatedMQ = FALSE;
- }
-
- // habClipboard = WinQueryAnchorBlock( HWND_DESKTOP );
-
- /*********************************************************************
- * Check to see if there is a wave ( CF_WAVE is the defined type) in
- * the clipboard.
- *********************************************************************/
-
-
- rc = WinQueryClipbrdFmtInfo( habClipboard,
- CF_WAVE,
- &ulFormatInfo );
-
- // if ( !rc )
- // {
- //
- // /*********************************************************************
- // * If CF_WAVE is not in the clipboard, then it is possible that a
- // * Win/OS2 OLE link is in the clipboard. Check and see.
- // *********************************************************************/
- //
- // = WinFindAtom( WinQuerySystemAtomTable(),
- // "OwnerLink" );
- // if ( !atomWave )
- // {
- // WinCloseClipbrd( habClipboard );
- // return ( MCIERR_CLIPBOARD_EMPTY );
- // }
- // else
- // {
- // ulOleLink = TRUE;
- // }
- //
- // }
-
- if ( !WinOpenClipbrd( habClipboard ) )
- {
- WinCloseClipbrd( habClipboard );
- return ( MCIERR_CLIPBOARD_ERROR );
- }
-
- pTempBuffer = ( PSZ ) WinQueryClipbrdData( habClipboard, CF_WAVE );
-
- if ( !pTempBuffer )
- {
- WinCloseClipbrd( habClipboard );
- return ( MCIERR_CLIPBOARD_ERROR );
- }
-
-
- /*********************************************************************
- * We need to find out how much data is in the file, so retrieve
- * the length of the riff chunk
- *********************************************************************/
- pulDataSize = ( PULONG ) pTempBuffer + 1;
-
-
- memset( &mmioinfo, '\0', sizeof( MMIOINFO ) );
-
- /*********************************************************************
- * Prepare to open a memory file--the buffer * in the clipboard contains
- * actual Riff-file which the wave io proc already knows how
- * to parse--use it to retrieve the information and keep the MCD from
- * file format dependence.
- *********************************************************************/
-
-
- mmioinfo.fccIOProc = mmioFOURCC( 'W', 'A', 'V', 'E' ) ;
- mmioinfo.fccChildIOProc = FOURCC_MEM;
-
- rc = CheckMem ( (PVOID) pulDataSize,
- sizeof ( ULONG ),
- PAG_READ | PAG_WRITE );
-
- if (rc != MCIERR_SUCCESS)
- {
- WinCloseClipbrd( habClipboard );
- return (MCIERR_OUT_OF_MEMORY );
- }
-
-
- mmioinfo.cchBuffer = ( *pulDataSize) + 8;
- mmioinfo.pchBuffer = pTempBuffer;
-
-
- hmmioMem = mmioOpen( NULL,
- &mmioinfo,
- MMIO_READ );
-
-
- if ( !hmmioMem )
- {
- WinCloseClipbrd( habClipboard );
- return ( mmioinfo.ulErrorRet );
- }
-
- /******************************************
- * Figure out how big the file is by
- * retrieving the audio header--remember that
- * although this is physical memory, it is
- * treated as a file by mmio.
- ******************************************/
-
- lReturnCode = mmioGetHeader ( hmmioMem,
- (PVOID) &mmaudioheader,
- sizeof( mmaudioheader ),
- &lBytesRead,
- (ULONG) NULL,
- (ULONG) NULL);
-
- if ( lReturnCode == MMIO_SUCCESS )
- {
- /***********************************************
- * The current routines can only process PCM.
- * Sometime in the future, we will handle other
- * formats like ADPCM. Note: what about alaw + mulaw?????????
- * should be easy to convert.
- **********************************************/
-
- if ( mmaudioheader.mmXWAVHeader.WAVEHeader.usFormatTag !=
- DATATYPE_WAVEFORM )
- {
- WinCloseClipbrd( habClipboard );
- return ( MCIERR_CANNOT_CONVERT ); // is there invalid format ?
- }
- /***********************************************
- * Have the io proc parse file format and bring in
- * the entire amount in the clipboard.
- **********************************************/
-
- *pulBuffLen = mmaudioheader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes;
-
- *pBuffer = HhpAllocBuffer( mmaudioheader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes + 500,
- 0 );
-
- lReturnCode = mmioRead( hmmioMem,
- ( PSZ ) *pBuffer,
- mmaudioheader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes );
-
- if ( lReturnCode != mmaudioheader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes )
- {
- // return better error
- WinCloseClipbrd( habClipboard );
- lReturnCode = mmioGetLastError( hmmioMem );
- mmioClose( hmmioMem, ( WORD ) NULL );
-
- return( lReturnCode );
- }
-
- } /* if we successfully retrieved the header */
- else
- {
- // return better error
- WinCloseClipbrd( habClipboard );
- lReturnCode = mmioGetLastError( hmmioMem );
-
- mmioClose( hmmioMem, ( WORD ) NULL );
- return ( lReturnCode ) ;
-
- } /* else we cannot retrieve the header */
-
-
- WinCloseClipbrd( habClipboard );
-
- if ( ulParam1 & MCI_CONVERT_FORMAT )
- {
- memmove( &mmaudioheaderTemp, &pInstance->mmAudioHeader, sizeof( MMAUDIOHEADER ) );
-
- #ifndef TOOLKIT
- rc = ConvertAudio( &mmaudioheader,
- *pBuffer,
- &mmaudioheaderTemp,
- &pNewBuffer);
-
- if ( !rc )
- {
-
- return ( MCIERR_CANNOT_CONVERT );
- }
- #endif
-
- rc = MCIERR_SUCCESS;
-
- if ( pNewBuffer )
- {
- HhpFreeBuffer( *pBuffer );
- *pBuffer = pNewBuffer;
-
- memmove( &mmaudioheader, &mmaudioheaderTemp, sizeof( MMAUDIOHEADER ) );
- *pulBuffLen = mmaudioheader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes;
- if ( pInstance->AmpInstance.lBitsPerSRate == 16 &&
- *pulBuffLen % 2 )
- *pulBuffLen = *pulBuffLen - 1;
- }
-
- }
- else
- {
- /*----------------------------------------------------------------------
- * If the to buffer flag is passed, the caller "should" be intelligent
- * enough to handle conversions.
- *---------------------------------------------------------------------*/
-
- if ( !(ulParam1 & MCI_TO_BUFFER ) )
- {
- /*----------------------------------------------------
- * If the clipboard contains a different format than
- * what is in the current file, return an error.
- *--------------------------------------------------*/
-
- if ( ( pInstance->AmpInstance.sChannels != (SHORT )
- mmaudioheader.mmXWAVHeader.WAVEHeader.usChannels ) ||
- ( pInstance->AmpInstance.lSRate != ( LONG )
- mmaudioheader.mmXWAVHeader.WAVEHeader.ulSamplesPerSec ) ||
- ( pInstance->AmpInstance.lBitsPerSRate != ( LONG )
- mmaudioheader.mmXWAVHeader.WAVEHeader.usBitsPerSample ) )
-
- {
- HhpFreeBuffer( *pBuffer );
- return (MCIERR_CANNOT_CONVERT );
- } /* if the clipboard + file contain different formats */
-
- } /* if the user did not request pasting to the buffer */
-
- } /* else the user does not want a conversion from the clipboard done */
- // is this needed?
-
- if ( ulParam1 & MCI_TO_BUFFER )
- {
- memmove( pmmaudioheader, &mmaudioheader, sizeof( MMAUDIOHEADER ) );
- }
-
- mmioClose( hmmioMem, ( WORD ) NULL );
-
-
- /*-----------------------------------------------------------
- * Message queue creation could have failed if the process has
- * already done it.
- *------------------------------------------------------------*/
-
- if ( fCreatedMQ )
- {
- WinDestroyMsgQueue( hmq );
- }
-
- WinTerminate( habClipboard );
-
-
-
- return ( rc );
- } /* GetClipboardData */
-
-
-
-
-
-
- /********************* START OF SPECIFICATIONS *********************
- *
- * SUBROUTINE NAME: PutClipboardData
- *
- * DESCRIPTIVE Puts digital audio information into the clipboard.
- *
- * FUNCTION: Allocates memory for digital audio information, opens
- * a memory file with correct header then places a
- * bitmap and wave information into the clipboard, then
- * closes the clipboard.
- *
- * NOTES:
- *
- * ENTRY POINTS:
- * LINKAGE: CALL FAR
- *
- * INPUT: MCI_STOP message.
- *
- * EXIT-NORMAL: Return Code 0.
- *
- * EXIT_ERROR: Error Code.
- *
- * EFFECTS:
- *
- * INTERNAL REFERENCES: MCIERR ().
- *
- * EXTERNAL REFERENCES: spiStopStream () - SSM Spi
- *
- *********************** END OF SPECIFICATIONS **********************/
-
- RC PutClipboardData( PVOID *pBuffer,
- INSTANCE *pInstance,
- ULONG ulOperation,
- ULONG ulBuffLength )
-
- {
- HAB habClipboard;
- HMQ hmq;
-
- BOOL fCreatedMQ = TRUE; /* message queue creation? */
-
- HBITMAP hbmWave;
- HPS hps;
-
- HMMIO hmmioMem; // handle to memory file
-
- MMIOINFO mmioinfo; // info struct for memory file
-
- ULONG rc;
- extern ULONG hModuleHandle; // module handle for dll
- extern HWND hwndClipWin; /* Clipboard win handle */
-
-
- LONG lBytesRead;
- LONG lReturnCode;
-
- MMAUDIOHEADER mmaudioheader;
-
- PCHAR pWave;
-
-
- memset( &mmioinfo, '\0', sizeof( MMIOINFO ) );
-
- /*********************************************************************
- * Prepare to open a memory file--the buffer * in the clipboard contains
- * actual Riff-file which the wave io proc already knows how
- * to parse--use it to retrieve the information and keep the MCD from
- * file format dependence.
- *********************************************************************/
-
-
- mmioinfo.fccIOProc = mmioFOURCC( 'W', 'A', 'V', 'E' ) ;
- mmioinfo.fccChildIOProc = FOURCC_MEM;
- mmioinfo.cchBuffer = ( ulBuffLength) + 200;
-
-
- pWave = ( PCHAR ) HhpAllocBuffer( ( ( ulBuffLength ) + 200 ), HH_SHARED );
-
- mmioinfo.pchBuffer = pWave;
-
- hmmioMem = mmioOpen( NULL,
- &mmioinfo,
- MMIO_READWRITE | MMIO_CREATE );
-
- if ( !hmmioMem )
- {
- return ( mmioinfo.ulErrorRet );
- }
-
- /***********************************************
- * Copy the instance header into a structure we
- * can safely modify for this particular buffer
- **********************************************/
-
-
- memmove( &mmaudioheader, &pInstance->mmAudioHeader, sizeof ( MMAUDIOHEADER ));
- mmaudioheader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes = ulBuffLength;
-
-
- lReturnCode = mmioWrite( hmmioMem,
- *pBuffer,
- ulBuffLength );
-
- if ( lReturnCode != ulBuffLength )
- {
- lReturnCode = mmioGetLastError ( hmmioMem );
- mmioClose( hmmioMem, ( WORD ) NULL );
- return( lReturnCode );
- }
-
- lReturnCode = mmioSetHeader ( hmmioMem,
- (PVOID) &mmaudioheader,
- sizeof( mmaudioheader ),
- &lBytesRead,
- (ULONG) NULL,
- (ULONG) NULL);
-
-
- if ( lReturnCode != MMIO_SUCCESS )
- {
- lReturnCode = mmioGetLastError ( hmmioMem );
- mmioClose( hmmioMem, ( WORD ) NULL );
- return( lReturnCode );
- }
-
-
- /********************************************************
- * The resource that is associated with this dll contains
- * a wave bitmap that we will place into the clipboard
- * along with the actual audio information, so obtain
- * a handle to the bitmap from PM.
- ********************************************************/
-
- // hps = WinGetPS( hwndClipWin );
- hps = WinGetPS( HWND_DESKTOP ) ;
-
-
- hbmWave = GpiLoadBitmap( hps, hModuleHandle, WAVE_BMP, 0, 0 );
-
- if ( !hbmWave )
- {
- WinReleasePS( hps );
- mmioClose( hmmioMem, ( WORD ) NULL );
- return ( MCIERR_CLIPBOARD_ERROR );
- }
-
- habClipboard = WinInitialize( 0 );
- if ( !habClipboard )
- {
- WinReleasePS( hps );
- return ( MCIERR_CLIPBOARD_ERROR );
- }
-
- hmq = WinCreateMsgQueue( habClipboard, 0 );
-
- if ( !hmq )
- {
- fCreatedMQ = FALSE;
- }
-
-
- // habClipboard = WinQueryAnchorBlock( HWND_DESKTOP );
-
- /***********************************************
- * Open the clipboard and prepare to copy the
- * information into it.
- **********************************************/
-
-
- if ( !WinOpenClipbrd( habClipboard ) )
- {
- WinReleasePS( hps );
- mmioClose( hmmioMem, ( WORD ) NULL );
- return ( MCIERR_CLIPBOARD_ERROR ); // cant open clipboard
- }
-
- /***********************************************
- * Clear what was previously in the clipboard--
- * standard PM protocol.
- **********************************************/
-
-
-
- if ( !WinEmptyClipbrd( habClipboard ) )
- {
- WinCloseClipbrd( habClipboard );
- mmioClose( hmmioMem, ( WORD ) NULL );
- WinReleasePS( hps );
- return ( MCIERR_CLIPBOARD_ERROR );
- }
-
- /**************************************************
- * Place the wave and the bitmap in the clipboard
- * if possible.
- **************************************************/
-
- if ( !WinSetClipbrdData( habClipboard,
- ( ULONG ) hbmWave,
- CF_BITMAP,
- CFI_HANDLE ) )
- {
- WinCloseClipbrd( habClipboard );
- mmioClose( hmmioMem, ( WORD ) NULL );
- WinReleasePS( hps );
- return ( MCIERR_CLIPBOARD_ERROR ); // cant open clipboard
-
- }
-
- if ( !WinSetClipbrdData( habClipboard,
- ( ULONG ) pWave,
- CF_WAVE,
- CFI_POINTER ) )
- {
- WinCloseClipbrd( habClipboard );
- WinReleasePS( hps );
- mmioClose( hmmioMem, ( WORD ) NULL );
- return ( MCIERR_CLIPBOARD_ERROR );
- }
-
- /***************************
- * Perform cleanup if any.
- ***************************/
-
- mmioClose( hmmioMem, ( WORD ) NULL );
-
- /**************************************************
- * Close the clipboard as quickly as possible since
- * only one process at a time can be in it.
- **************************************************/
-
- if ( !WinCloseClipbrd( habClipboard ) )
- {
- WinReleasePS( hps );
- return ( MCIERR_CLIPBOARD_ERROR );
- }
-
- /*-----------------------------------------------------------
- * Message queue creation could have failed if the process has
- * already done it.
- *------------------------------------------------------------*/
-
- if ( fCreatedMQ )
- {
- WinDestroyMsgQueue( hmq );
- }
-
- WinTerminate( habClipboard );
- WinReleasePS( hps );
-
- return ( MCIERR_SUCCESS );
- } /* PutClipboardData */
-
-
-