示例#1
0
// Increase the number of key splits. This will not clean the entry's that are added.
// This will add from the end. This will freeup the passed InstrumentResource
InstrumentResource * XAddKeySplit(InstrumentResource *theX, short int howMany)
{
    long				size, moveSize, size2;
    short int			total;
    KeySplit 			*pSplits;
    char				*pSrc, *pDest;
    InstrumentResource	*theNewX;

    theNewX = NULL;
    if (theX)
	{
	    total = (short)XGetShort(&theX->keySplitCount);
	    size = XGetPtrSize(theX);
	    size2 =  (long)(sizeof(KeySplit) * howMany);
	    theNewX = (InstrumentResource *)XNewPtr(size2 + size);
	    if (theNewX)
		{
		    XBlockMove(theX, theNewX, size);	// make copy
		    XPutShort(&theNewX->keySplitCount, (unsigned short)(total + howMany));
		    // must move all zones down
		    pSplits = (KeySplit *) ( ((unsigned char *)&theX->keySplitCount) + sizeof(unsigned short int));
		    pSrc = (char *)&pSplits[total];

		    pSplits = (KeySplit *) ( ((unsigned char *)&theNewX->keySplitCount) + sizeof(unsigned short int));
		    pDest = (char *)&pSplits[total + howMany];
		    moveSize =  size - (pSrc - (char *)theX);
		    // this move must handle overlapping data
		    XBlockMove(pSrc, pDest, moveSize);
		}
	}
    return theNewX;
}
示例#2
0
void * mod_realloc(void* ptr, long size)
{
    XPTR	p;

    p = NULL;
    if (ptr)
    {
        p = XNewPtr(size);
        if (p)
        {
            size = XGetPtrSize((XPTR)ptr);	// get old size
            if (size)
            {
                XBlockMove(ptr, p, size);
            }
            else
            {
                XDisposePtr(p);
                p = NULL;	// can't get size, so fail
            }
            XDisposePtr(ptr);
        }
    }
    return p;
}
示例#3
0
void XTestCompression(XPTR compressedAndEncryptedData, long size, XPTR originalData, long originalSize)
{
    XPTR	pData, pData2;
    short int	safe;

    if (compressedAndEncryptedData && originalData && size && originalSize)
	{
	    // since this is encrypted, make a new copy and decrypt
	    pData = XNewPtr(size);
	    if (pData)
		{
		    XBlockMove(compressedAndEncryptedData, pData, size);
		    XDecryptData(pData, (unsigned long)size);				// decrypt first
		    pData2 = pData;
		    pData = XDecompressPtr(pData2, (unsigned long)size, TRUE);		// uncompress second
		    if (pData)
			{
			    size = XGetPtrSize(pData);	// get new size
			    if (size == originalSize)
				{
				    safe = XMemCmp(pData, originalData, size);
				    if (safe)
					{
					    DebugStr("\pmemcmp failed");
					}
				    else
					{
					    DebugStr("\pSAFE!");
					}
				}
			    else
				{
示例#4
0
static void PV_TrackNameCallback(void *threadContext, GM_Song *pSong, char markerType, void *pMetaText, INT32 metaTextLength, short currentTrack)
{
    XBYTE **tnArray,*str;

    threadContext;
    if (markerType == 0x03) 
	{	// track name
	    if (currentTrack != -1)
		{
		    str = (XBYTE *)XNewPtr(metaTextLength+1);
		    if (str)
			{
			    XBlockMove(pMetaText,str+1,metaTextLength);
			    str[0] = (XBYTE)metaTextLength;
			    tnArray = (XBYTE **)pSong->metaEventCallbackReference;
			    tnArray[currentTrack] = str;
			}
		}
	}
}
OPErr XProcessMPEGEncoder(XMPEGEncodeData *stream)
{
	OPErr				theErr;
	MPEGEncoderPrivate	*pPrivate;
	XPTR				encodedBuffer;
	unsigned long		encodedLength;
	int					result;
	char				*resultBuffer;
	XBOOL				lastFrame;

	theErr = NO_ERR;
	if (stream)
	{
		pPrivate = MPEG_ENCODE_PRIVATE(stream);
		if (pPrivate->pCompressedAudio && pPrivate->encoder)
		{
			result = MPG_EncodeProcess(pPrivate->encoder, &encodedBuffer, &encodedLength, &lastFrame);
			if (lastFrame)
			{
				theErr = STREAM_STOP_PLAY;	// we're done. compress this last buffer and stop
			}
			if (encodedLength)
			{
				resultBuffer = (char *)pPrivate->pCompressedAudio + pPrivate->compressedAudioPosition;
				XBlockMove(encodedBuffer, (XPTR)(resultBuffer), encodedLength);
				pPrivate->compressedAudioPosition += encodedLength;
				stream->currentFrameBuffer++;
			}
			stream->pFrameBuffer = resultBuffer;
			stream->frameBufferSize = encodedLength;
		}
		else
		{
			BAE_ASSERT(FALSE);
			theErr = PARAM_ERR;
		}
	}
	return theErr;
}
示例#6
0
OPErr GM_GetSongInstrumentChanges(void *theSongResource, GM_Song **outSong, XBYTE **outTrackNames)
{
    OPErr		err;
    ScanMode 	saveScan;
    XBOOL		saveLoop,saveAlive;
    GM_Song		*theSong;
    void		*newMidiData;
	
    err = NO_ERR;
    // don't need a thread context here because we don't callback
    theSong = GM_LoadSong(NULL, NULL, 0, theSongResource, NULL, 0L, NULL, FALSE, TRUE, &err);
    if (!theSong)
	{
	    return err;
	}	
    err = PV_ConfigureMusic(theSong);
    // first pass: count the program changes, so we know how big to make our
    if (err == NO_ERR)
	{
	    theSong->pPatchInfo = (PatchInfo *)XNewPtr((INT32)sizeof(PatchInfo));
	    if (theSong->pPatchInfo)
		{
		    saveScan = theSong->AnalyzeMode;
		    theSong->AnalyzeMode = SCAN_COUNT_PATCHES;
		    saveLoop = theSong->loopSong;
		    theSong->loopSong = FALSE;
		    saveAlive = theSong->SomeTrackIsAlive;
		    theSong->SomeTrackIsAlive = TRUE;
		    while (theSong->SomeTrackIsAlive)
			{
			    // don't need a thread context here because we don't callback
			    err = PV_ProcessMidiSequencerSlice(NULL, theSong);
			    if (err)
				{
				    break;
				}
			}
		}
	    else
		{
		    err = MEMORY_ERR;
		}
	}
    // now theSong->pPatchInfo->pgmCount points to the number of program
    // changes without immediately preceding bank changes, and rsCount
    // is the number of program changes that were discovered to have been
    // written into the file in running status mode (implement this later)
    // done in two passes because we can't keep changing the midi data
    // pointer, so we have figure out how big it needs to be first and
    // move it in place

    if (err == NO_ERR)
	{
	    // expand the ptr enough to accomodate bank messages (4 bytes each)
	    newMidiData = XNewPtr(XGetPtrSize(theSong->midiData) + theSong->pPatchInfo->instrCount * 4);
	    XBlockMove(theSong->midiData,newMidiData,XGetPtrSize(theSong->midiData));
	    XDisposePtr(theSong->midiData);
	    theSong->midiData = newMidiData;

	    // start over
	    err = PV_ConfigureMusic(theSong);

	    // second pass: get the program changes, add bank events before each one
	    if (err == NO_ERR)
		{
		    GM_SetSongMetaEventCallback(theSong, PV_TrackNameCallback, (INT32)outTrackNames);
		    saveScan = theSong->AnalyzeMode;
		    theSong->AnalyzeMode = SCAN_FIND_PATCHES;
		    saveLoop = theSong->loopSong;
		    theSong->loopSong = FALSE;
		    saveAlive = theSong->SomeTrackIsAlive;
		    theSong->SomeTrackIsAlive = TRUE;
		    while (theSong->SomeTrackIsAlive)
			{
				// don't need a thread context here because we don't callback
			    err = PV_ProcessMidiSequencerSlice(NULL, theSong);
			    if (err)
				{
				    break;
				}
			}
		}
	}
    // since there was an error, caller won't be using the song
    if (err)
	{
	    if (theSong->pPatchInfo)
		{
		    XDisposePtr(theSong->pPatchInfo);
		}
	    // don't need a thread context here because we don't callback
	    GM_FreeSong(NULL, theSong);	// we ignore the error codes, because it should be ok to dispose
	    // since this song was never engaged
	}
    else
	{
	    *outSong = theSong;
	}
    return err;
}
// given a MPEG stream and an offset, decode the mpeg stream into memory
OPErr XExpandMPEG(GM_Waveform const* src, UINT32 startFrame, GM_Waveform* dst)
{
OPErr				err;
XMPEGDecodedData*	stream;

	BAE_ASSERT(dst);
	BAE_ASSERT(src);
	*dst = *src;
	dst->theWaveform = NULL;
	dst->compressionType = C_NONE;
	
	stream = XOpenMPEGStreamFromMemory(src->theWaveform, src->waveSize, &err);
	if (stream)
	{
	UINT32		decodingBytes;
	XPTR		decodingData;

		decodingBytes = stream->maxFrameBuffers * stream->frameBufferSize;
		decodingData = XNewPtr(decodingBytes);
		if (decodingData)
		{
		UINT32			const bytesPerFrame = dst->channels * sizeof(short);
		XBYTE*			data;
		UINT32			startByte;
		UINT32			count;

			data = (XBYTE*)decodingData;
			startByte = startFrame * bytesPerFrame;
			count = 0;
			while (count < stream->maxFrameBuffers)
			{
			XBOOL		done;
				
				err = XFillMPEGStreamBuffer(stream, data, &done);

				if (startByte == 0)
				{
					data += stream->frameBufferSize;
				}
				else if (startByte < stream->frameBufferSize)
				{
					XBlockMove(data + startByte, data,
								stream->frameBufferSize - startByte);
					data += stream->frameBufferSize - startByte;
					startByte = 0;
				}
				else
				{
					// don't increment "data", skip the buffer
					startByte -= stream->frameBufferSize;
				}
				if ((err != NO_ERR) || done)
				{
					break;
				}
				count++;
			}
			
			if (err == NO_ERR)
			{
			UINT32			decodedBytes;
			UINT32			definedBytes;

				decodedBytes = data - (XBYTE*)decodingData;
				definedBytes = dst->waveFrames * bytesPerFrame;
				if (decodedBytes < definedBytes)
				{
					//MOE: This is a little weird that the number of frames decoded is less
					//     When ascertaining the true number of frames is better (with a
					//	   better MPEG decoder), we shouldn't see this happening.
					definedBytes = decodedBytes;
					dst->waveFrames = decodedBytes / bytesPerFrame;
				}
				
				if (definedBytes < decodingBytes)
				{
				XPTR			trimmedData;
				
					trimmedData = XResizePtr(decodingData, definedBytes);
					BAE_ASSERT(trimmedData);	// making memory block smaller shouldn't fail
					if (trimmedData)
					{
						decodingData = trimmedData;
					}
				}
				
				dst->theWaveform = (XSBYTE *)decodingData;
				dst->waveSize = definedBytes;
			}
			else
			{
				BAE_ASSERT(FALSE);	// check "err"
				XDisposePtr(decodingData);
				decodingData = NULL;
			}
		}
		else
		{
			err = MEMORY_ERR;
		}
		XCloseMPEGStream(stream);
	}
	return err;
}