// 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; }
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; }
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 {
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; }
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; }