Beispiel #1
0
/*
** Return the number of INST's and an array of resource IDs
*/
short int XGetInstrumentArray(XShortResourceID *instArray, short maxArraySize)
{
    short int	icount, totalCount;
    long		size;
    XPTR		theRes;

    /* Collect INST resources
     */
    totalCount = 0;
    if (instArray)
	{
	    for (icount = 0; icount < maxArraySize; icount++)
		{
		    theRes = XGetAndDetachResource(ID_INST, icount, &size);
		    if (theRes)
			{
			    XDisposePtr(theRes);
			    instArray[totalCount++] = (XShortResourceID)icount;
			    if (totalCount > maxArraySize)
				{
				    totalCount = maxArraySize;
				    break;
				}
			}
		}
	    XBubbleSortArray((short *)instArray, (short)totalCount);
	}
    return totalCount;
}
Beispiel #2
0
XBOOL XIsSampleUsedInAllInstruments(XShortResourceID soundSampleID, XShortResourceID *pWhichInstrument)
{
    InstrumentResource	*theX;
    short int			count, totalInstruments;
    XBOOL				used;
    long				size;
    XShortResourceID	instArray[MAX_INSTRUMENTS * MAX_BANKS];

    used = FALSE;
    totalInstruments = XGetInstrumentArray(instArray, MAX_INSTRUMENTS * MAX_BANKS);
    if (totalInstruments && pWhichInstrument)
	{
	    for (count = 0; count < totalInstruments; count++)
		{
		    theX = (InstrumentResource *)XGetAndDetachResource(ID_INST, instArray[count], &size);
		    if (theX)
			{
			    used = XIsSoundUsedInInstrument(theX, soundSampleID);
			    XDisposePtr((XPTR)theX);
			    if (used)
				{
				    *pWhichInstrument = instArray[count];
				    break;
				}
			}
		}
	}
    return used;
}
Beispiel #3
0
XShortResourceID XCheckValidInstrument(XShortResourceID theID)
{
    InstrumentResource	*theX;
    short int			totalSnds;
    XShortResourceID	sndArray[MAX_SAMPLES];
    short int			count;
    XShortResourceID	badLoad;
    XPTR				theSnd;
    long				size;

    badLoad = 0;
    theX = (InstrumentResource *)XGetAndDetachResource(ID_INST, theID, &size);
    if (theX)
	{
	    totalSnds = XCollectSoundsFromInstrument(theX, sndArray, MAX_SAMPLES);
	    XDisposePtr((XPTR)theX);
	    for (count = 0; count < totalSnds; count++)
		{
		    theSnd = XGetAndDetachResource(ID_CSND, sndArray[count], &size);		// look for compressed version first
		    if (theSnd == NULL)
			{
			    theSnd = XGetAndDetachResource(ID_SND, sndArray[count], &size);
			}
		    if (theSnd == NULL)
			{
			    theSnd = XGetAndDetachResource(ID_ESND, sndArray[count], &size);
			}
		    if (theSnd == NULL)
			{
			    badLoad = sndArray[count];
			}
		    XDisposePtr(theSnd);
		    if (badLoad)
			{
			    break;
			}
		}
	}
    return badLoad;
}
Beispiel #4
0
short int XCollectSoundsFromInstrumentID(XShortResourceID theID, XShortResourceID *sndArray, short maxArraySize)
{
    InstrumentResource	*theX;
    short int			totalSnds;
    long				size;

    totalSnds = 0;
    theX = (InstrumentResource *)XGetAndDetachResource(ID_INST, theID, &size);
    if (theX)
	{
	    totalSnds = XCollectSoundsFromInstrument(theX, sndArray, maxArraySize);
	    XDisposePtr((XPTR)theX);
	}
    return totalSnds;
}
Beispiel #5
0
// This will return a MIDI/CMID/EMID/ECMI object from an open resource file
//
// INPUT:
//	theXSong		is the SongResource structure
//
// OUTPUT:
//	pMusicName		is a pascal string
//	pMusicType		is the resource type
//	pMusicID		is the resource ID
//	pReturnedSize			is the resource size
XPTR XGetMusicObjectFromSong(SongResource *theXSong, char *pMusicName, 
			     XResourceType *pMusicType, XLongResourceID *pMusicID, long *pReturnedSize)
{
    long			musicID;
    SongType		songType;
    XPTR			data;
    XResourceType	midiTypes[] = {ID_MIDI, ID_MIDI_OLD, ID_CMID, ID_EMID, ID_ECMI};
    short int		count;

    data = NULL;
    if (pReturnedSize)
	{
	    *pReturnedSize = 0;
	}
    if (pMusicName)
	{
	    pMusicName[0] = 0;
	}
    if (theXSong)
	{
	    *pMusicType = 0;
	    *pMusicID = 0;
	    musicID = XGetSongResourceObjectID(theXSong);
	    songType = XGetSongResourceObjectType(theXSong);
		
	    for (count = 0; count < (sizeof(midiTypes) / sizeof(long)); count++)
		{
		    data = XGetAndDetachResource(midiTypes[count], musicID, pReturnedSize);
		    if (data)
			{
			    if (pMusicName)
				{
				    XGetResourceName(midiTypes[count], musicID, pMusicName);
				    XCtoPstr(pMusicName);
				}
			    *pMusicType = midiTypes[count];
			    *pMusicID = musicID;
			    break;
			}
		}
	}
    return data;
}
Beispiel #6
0
// Given an array of instruments, this will return an array of SND resources that are required to load
// these instruments
short int XGetTotalKeysplits(XShortResourceID *instArray, short int totalInstruments, 
			     XShortResourceID *sndArray, short int totalSnds)
{
    register short int	count, count2, count3, count4, keyCount;
    KeySplit			theSplit;
    InstrumentResource	*theInstrument;
    char				*pLoaded;
    long				size;

    keyCount = 0;
    if (instArray && totalInstruments && sndArray && totalSnds)
	{
	    pLoaded = (char *)XNewPtr((long)sizeof(char) * totalSnds);
	    if (pLoaded)
		{
		    for (count = 0; count < totalInstruments; count++)
			{
			    theInstrument = (InstrumentResource *)XGetAndDetachResource(ID_INST, instArray[count], &size);
			    if (theInstrument)
				{
				    count3 = (short)XGetShort(&theInstrument->keySplitCount);
				    for (count2 = 0; count2 < count3; count2++)
					{
					    XGetKeySplitFromPtr(theInstrument, count2, &theSplit);
					    count4 = PV_ConvertResourceID2Index(sndArray, totalSnds, theSplit.sndResourceID);
					    if (count4)
						{
						    if (pLoaded[count4] == 0)
							{
							    pLoaded[count4] = 1;
							    keyCount++;
							}
						}
					}
				}
			}
		    XDisposePtr((XPTR)pLoaded);
		}
	}
    return keyCount;
}
Beispiel #7
0
// Instruments 0 to MAX_INSTRUMENTS*MAX_BANKS are the standard MIDI instrument placements.
// This will create an internal instrument from and external instrument. If theX is non-null then it
// will use that data to create the GM_Instrument
GM_Instrument * PV_GetInstrument(XLongResourceID theID, void *theExternalX, INT32 patchSize)
{
    GM_Instrument		*theI, *theS;
    InstrumentResource	*theX;
    INT32				size;
    short int 			count;
    UBYTE				*theSound;
    KeySplit			theXSplit;
    CacheSampleInfo		sndInfo;
    LOOPCOUNT			i;
    INT32				theSampleID;

    theI = NULL;
    theX = (InstrumentResource *)theExternalX;
    if (theExternalX == NULL)
	{
	    theX = (InstrumentResource *)XGetAndDetachResource(ID_INST, theID, &patchSize);
	}
    if (theX)
	{
	    if (XGetShort(&theX->keySplitCount) < 2)	// if its 1, then it has no splits
		{
		    // get the sample ID from a short, values can be negative
		    // then allow conversion to take place.

		    // NOTE:	I know this is awfull, but if you change it things will break. The
		    //			internal ID values are all 32 bit signed, and some of the external
		    //			file structures are 16 bit signed.
		    theSampleID = (INT32)((short)XGetShort(&theX->sndResourceID));

		    theSound = (UBYTE *)PV_GetSampleFromID((INT32)theSampleID, &sndInfo);
		    if (theSound)
			{
			    theI = (GM_Instrument *)XNewPtr((INT32)sizeof(GM_Instrument));
			    if (theI)
				{
				    theI->u.w.theWaveform = (SBYTE *)theSound;

				    theI->disableSndLooping = TEST_FLAG_VALUE(theX->flags1, ZBF_disableSndLooping);
				    theI->playAtSampledFreq = TEST_FLAG_VALUE(theX->flags2, ZBF_playAtSampledFreq);
				    theI->doKeymapSplit = FALSE;
				    theI->notPolyphonic = TEST_FLAG_VALUE(theX->flags2, ZBF_notPolyphonic);
				    theI->avoidReverb = TEST_FLAG_VALUE(theX->flags1, ZBF_avoidReverb);
				    theI->useSampleRate = TEST_FLAG_VALUE(theX->flags1, ZBF_useSampleRate);
				    theI->sampleAndHold = TEST_FLAG_VALUE(theX->flags1, ZBF_sampleAndHold);
				    theI->useSoundModifierAsRootKey = TEST_FLAG_VALUE(theX->flags2, ZBF_useSoundModifierAsRootKey);
				    PV_GetEnvelopeData(theX, theI, patchSize);		// get envelope

				    theI->u.w.bitSize = sndInfo.bitSize;
				    theI->u.w.channels = sndInfo.channels;
				    theI->u.w.waveformID = XGetShort(&theX->sndResourceID);
				    theI->u.w.waveSize = sndInfo.waveSize;
				    theI->u.w.waveFrames = sndInfo.waveFrames;
				    theI->u.w.startLoop = sndInfo.loopStart;
				    theI->u.w.endLoop = sndInfo.loopEnd;

				    theI->masterRootKey = XGetShort(&theX->midiRootKey);
				    theI->panPlacement = theX->panPlacement;
				    theI->u.w.baseMidiPitch = (unsigned char)sndInfo.baseKey;
				    theI->u.w.sampledRate = sndInfo.rate;

				    // NOTE!! If ZBF_useSoundModifierAsRootKey is TRUE, then we are using
				    // the Sound Modifier data blocks as a root key replacement for samples in
				    // the particular split
				    theI->miscParameter1 = XGetShort(&theX->miscParameter1);
				    theI->miscParameter2 = XGetShort(&theX->miscParameter2);
				    if (theI->useSoundModifierAsRootKey)
					{
					    theI->enableSoundModifier = FALSE;
					    if (theI->miscParameter2 == 0)		// Forces a default value of 0 to 100
						{
						    theI->miscParameter2 = 100;
						}
					}
				    else
					{
					    theI->enableSoundModifier = TEST_FLAG_VALUE(theX->flags2, ZBF_enableSoundModifier);
					    theI->smodResourceID = theX->smodResourceID;

					    // Process sample in place
					    if ( (theI->enableSoundModifier) && (theI->u.w.bitSize == 8) && (theI->u.w.channels == 1) )
						{
#if DISPLAY_INSTRUMENTS
						    DPrint(drawDebug, "---->Processing instrument %ld with SMOD %ld\r", (INT32)theID, (INT32)theI->smodResourceID);
#endif
						    PV_ProcessSampleWithSMOD(theI->u.w.theWaveform,
									     theI->u.w.waveSize,
									     theI->u.w.waveformID,
									     theI->smodResourceID,
									     theI->miscParameter1,
									     theI->miscParameter2);
						}
					}
				}
			}
		}
	    else
		{	// Keysplits
#if DISPLAY_INSTRUMENTS
		    DPrint(drawDebug, "----->Processing %ld keysplits\r", (INT32)XGetShort(&theX->keySplitCount));
#endif
		    size = XGetShort(&theX->keySplitCount) * (INT32)sizeof(GM_KeymapSplit);
		    size += (INT32)sizeof(GM_KeymapSplitInfo);

		    theI = (GM_Instrument *)XNewPtr(size + (INT32)sizeof(GM_Instrument));
		    if (theI)
			{
			    theI->disableSndLooping = TEST_FLAG_VALUE(theX->flags1, ZBF_disableSndLooping);
			    theI->doKeymapSplit = TRUE;
			    theI->notPolyphonic = TEST_FLAG_VALUE(theX->flags2, ZBF_notPolyphonic);
			    theI->avoidReverb = TEST_FLAG_VALUE(theX->flags1, ZBF_avoidReverb);
			    theI->useSampleRate = TEST_FLAG_VALUE(theX->flags1, ZBF_useSampleRate);
			    theI->sampleAndHold = TEST_FLAG_VALUE(theX->flags1, ZBF_sampleAndHold);
			    theI->playAtSampledFreq = TEST_FLAG_VALUE(theX->flags2, ZBF_playAtSampledFreq);
			    theI->useSoundModifierAsRootKey = TEST_FLAG_VALUE(theX->flags2, ZBF_useSoundModifierAsRootKey);
			    PV_GetEnvelopeData(theX, theI, patchSize);		// get envelope

			    theI->u.k.KeymapSplitCount = XGetShort(&theX->keySplitCount);
			    theI->u.k.defaultInstrumentID = (XShortResourceID)XGetShort(&theX->sndResourceID);

			    theI->masterRootKey = XGetShort(&theX->midiRootKey);
			    theI->panPlacement = theX->panPlacement;

				// NOTE!! If ZBF_useSoundModifierAsRootKey is TRUE, then we are using
				// the Sound Modifier data blocks as a root key replacement for samples in
				// the particular split
			    theI->miscParameter1 = XGetShort(&theX->miscParameter1);
			    theI->miscParameter2 = XGetShort(&theX->miscParameter2);
			    if (theI->useSoundModifierAsRootKey)
				{
				    theI->enableSoundModifier = FALSE;
				    if (theI->miscParameter2 == 0)		// Forces a default value of 0 to 100
					{
					    theI->miscParameter2 = 100;
					}
				}
			    else
				{
				    theI->enableSoundModifier = TEST_FLAG_VALUE(theX->flags2, ZBF_enableSoundModifier);
				    theI->smodResourceID = theX->smodResourceID;
				}

			    for (count = 0; count < theI->u.k.KeymapSplitCount; count++)
				{
				    XGetKeySplitFromPtr(theX, count, &theXSplit);
				    theI->u.k.keySplits[count].lowMidi = theXSplit.lowMidi;
				    theI->u.k.keySplits[count].highMidi = theXSplit.highMidi;
				    theI->u.k.keySplits[count].miscParameter1 = theXSplit.miscParameter1;
				    if (theI->useSoundModifierAsRootKey && (theXSplit.miscParameter2 == 0))		// Forces a default value of 0 to 100
					{
					    theXSplit.miscParameter2 = 100;
					}
				    theI->u.k.keySplits[count].miscParameter2 = theXSplit.miscParameter2;

				    //					if (GM_IsInstrumentRangeUsed(theID, (INT16)theXSplit.lowMidi, (INT16)theXSplit.highMidi))
				    {
#if DISPLAY_INSTRUMENTS
					DPrint(drawDebug, "------->Keysplit %ld low %ld high %ld\r", (INT32)count,
					       (INT32)theXSplit.lowMidi,
					       (INT32)theXSplit.highMidi);
#endif
					theS =  PV_CreateInstrumentFromResource(theI, (XLongResourceID)theXSplit.sndResourceID);
					theI->u.k.keySplits[count].pSplitInstrument = theS;
					if (theS)
					    {
						theS->useSoundModifierAsRootKey = theI->useSoundModifierAsRootKey;
						theS->miscParameter1 = theXSplit.miscParameter1;
						if (theS->useSoundModifierAsRootKey && (theXSplit.miscParameter2 == 0))		// Forces a default value of 0 to 100
						    {
							theXSplit.miscParameter2 = 100;
						    }
						theS->miscParameter2 = theXSplit.miscParameter2;

						theS->masterRootKey = theI->masterRootKey;
						theS->avoidReverb = theI->avoidReverb;
						theS->volumeADSRRecord = theI->volumeADSRRecord;
						for (i = 0; i < theI->LFORecordCount; i++)
						    {
							theS->LFORecords[i] = theI->LFORecords[i];
						    }
						theS->LFORecordCount = theI->LFORecordCount;
						for (i = 0; i < theI->curveRecordCount; i++)
						    {
							theS->curve[i] = theI->curve[i];
						    }
						theS->curveRecordCount = theI->curveRecordCount;
						theS->LPF_frequency = theI->LPF_frequency;
						theS->LPF_resonance = theI->LPF_resonance;
						theS->LPF_lowpassAmount = theI->LPF_lowpassAmount;

						if (theS->useSoundModifierAsRootKey == FALSE)
						    {
							// Process sample in place
							if ( (theS->enableSoundModifier) && (theS->u.w.bitSize == 8) && (theS->u.w.channels == 1) )
							    {
#if DISPLAY_INSTRUMENTS
								DPrint(drawDebug, "----->Processing instrument %ld with SMOD %ld\r", (INT32)theID, (INT32)theI->smodResourceID);
#endif
								PV_ProcessSampleWithSMOD(	theS->u.w.theWaveform,
												theS->u.w.waveSize,
												theXSplit.sndResourceID,
												theS->smodResourceID,
												theS->miscParameter1,
												theS->miscParameter2);
							    }
						    }
					    }
				    }
				}
			}
		}
	    if (theExternalX == NULL)
		{
		    XDisposePtr((XPTR)theX);
		}
	}
#if DISPLAY_INSTRUMENTS
    if (theI)
	{
	    DPrint(drawDebug, "-------->INST info: masterRootKey %ld\r", (INT32)theI->masterRootKey);
	}
#endif
    return theI;
}
Beispiel #8
0
XERR XCopySndResources(XShortResourceID *pSndCopy, short int sndCount, XFILE readFileRef, 
		       XFILE writeFileRef, XBOOL protect, XBOOL copyNames)
{
    short int		count, resCount;
    XPTR			pData;
    short int		theID;
    char			theName[256];
    long			size;
    long			soundTypes[] = {ID_SND, ID_ESND, ID_CSND};

    if (sndCount && pSndCopy)
	{
	    XFileUseThisResourceFile(readFileRef);		/* from resource file */
	    for (count = 0; count < sndCount; count++)
		{
		    theID = pSndCopy[count];
			
		    // determine if the resource is already in the written file
		    XFileUseThisResourceFile(writeFileRef);
		    pData = XGetAndDetachResource(ID_SND, theID, &size);
		    if (pData == NULL)
			{
			    pData = XGetAndDetachResource(ID_ESND, theID, &size);
			}
		    if (pData == NULL)
			{
			    pData = XGetAndDetachResource(ID_CSND, theID, &size);
			}
		    XDisposePtr(pData);
		    if (pData == NULL)			// check to see that its not there already!!
			{
			    for (resCount = 0; resCount < 3; resCount++)
				{
				    XFileUseThisResourceFile(readFileRef);		/* from resource file */
				    pData = XGetFileResource(readFileRef, soundTypes[resCount], theID, theName, &size);
				    if (pData)
					{
					    if (copyNames == FALSE)
						{
						    theName[0] = 0;
						}

					    XFileUseThisResourceFile(writeFileRef);
					    if (protect && (soundTypes[resCount] == ID_SND))
						{
						    XEncryptData(pData, size);
						    XAddResource(ID_ESND, theID, theName, pData, size);
						}
					    else
						{
						    XAddResource(soundTypes[resCount], theID, theName, pData, size);
						}
					    XDisposePtr(pData);
					}
				}
			}
		    else
			{
			    XDisposePtr(pData);
			}
		}
	}
    return 0;
}
Beispiel #9
0
// Given a song ID and two arrays, this will return the INST resources ID and the 'snd ' resource ID
// that are needed to load the song terminated with a -1.
// Will return 0 for success or 1 for failure
OPErr XGetSongInstrumentList(XShortResourceID theSongID, XShortResourceID *pInstArray, short int maxInstArraySize, 
			     XShortResourceID *pSndArray, short int maxSndArraySize)
{
    long				count, instCount, sndCount, newCount, completeSndCount;
    XShortResourceID	soundID;
    SongResource		*theSong;
    XShortResourceID	completeSndArray[MAX_SAMPLES];
    XShortResourceID	completeInstArray[MAX_INSTRUMENTS * MAX_BANKS];
    XBOOL				goodSound;
    OPErr				theErr;
    long				size;

    theErr = NO_ERR;
    if ( (pInstArray) && (pSndArray) )
	{
	    for (count = 0; count < maxInstArraySize; count++)
		{
		    pInstArray[count] = (XShortResourceID)-1;
		    completeInstArray[count] = (XShortResourceID)-1;
		}
	    for (count = 0; count < maxSndArraySize; count++)
		{
		    pSndArray[count] = (XShortResourceID)-1;
		    completeSndArray[count] = (XShortResourceID)-1;
		}
	    theSong = (SongResource *)XGetAndDetachResource(ID_SONG, theSongID, &size);
	    if (theSong)
		{
		    instCount = GM_GetUsedPatchlist(theSong, NULL, 0L, completeInstArray, &theErr);
		    if (instCount && (theErr == 0) )
			{
				// remove duplicates in inst
			    sndCount = 0;
			    for (newCount = 0; newCount < instCount; newCount++)
				{
				    goodSound = TRUE;
				    soundID = completeInstArray[newCount];
				    for (count = 0; count < sndCount; count++)
					{
					    if (soundID == pInstArray[count])
						{
						    goodSound = FALSE;
						    break;
						}
					}
				    if (goodSound)
					{
					    pInstArray[sndCount++] = (XShortResourceID)soundID;
					}
				}
			    instCount = sndCount;
			    XBubbleSortArray((short *)pInstArray, (short)instCount);

			    completeSndCount = 0;
			    for (count = 0; count < instCount; count++)
				{
				    newCount = XCollectSoundsFromInstrumentID(pInstArray[count], 
									      &completeSndArray[completeSndCount], 128);
				    completeSndCount += newCount;
				}
				
				// remove duplicates in snds
			    sndCount = 0;
			    for (newCount = 0; newCount < completeSndCount; newCount++)
				{
				    goodSound = TRUE;
				    soundID = completeSndArray[newCount];
				    for (count = 0; count < sndCount; count++)
					{
					    if (soundID == pSndArray[count])
						{
						    goodSound = FALSE;
						    break;
						}
					}
				    if (goodSound)
					{
					    pSndArray[sndCount++] = (XShortResourceID)soundID;
					}
				}
			    XBubbleSortArray((short *)pSndArray, (short)sndCount);
			}
		    else
			{
			    theErr = BAD_MIDI_DATA;
			}
		}
	    XDisposePtr((XPTR)theSong);
	}
    return theErr;
}
Beispiel #10
0
// Given a list of instruments, this will return the sample ID's that are required to load
// all of these instruments
short int XGetSamplesFromInstruments(XShortResourceID *pInstArray, short int maxInstArraySize, 
				     XShortResourceID *pSndArray, short int maxSndArraySize)
{
    register long		count, instCount, sndCount, newCount, completeSndCount;
    XShortResourceID	soundID;
    XShortResourceID	*completeSndArray;
    XBOOL				goodSound;
    InstrumentResource	*theX;
    long				size;

    sndCount = 0;
    completeSndArray = (XShortResourceID *)XNewPtr(sizeof(XShortResourceID) * MAX_INSTRUMENTS * 128L);
    if (completeSndArray)
	{
	    if ( (pInstArray) && (pSndArray) )
		{
		    instCount = 0;
		    for (count = 0; count < maxInstArraySize; count++)
			{
			    if (pInstArray[count] != (XShortResourceID)-1)
				{
				    instCount++;
				}
			    else
				{
				    break;
				}
			}
		    for (count = 0; count < maxSndArraySize; count++)
			{
			    pSndArray[count] = (XShortResourceID)-1;
			    completeSndArray[count] = (XShortResourceID)-1;
			}


		    completeSndCount = 0;
		    for (count = 0; count < instCount; count++)
			{
			    theX = (InstrumentResource *)XGetAndDetachResource(ID_INST, pInstArray[count], &size);
			    if (theX)
				{
				    newCount = XCollectSoundsFromInstrument(theX, &completeSndArray[completeSndCount], 128);
				    XDisposePtr((XPTR)theX);
				    completeSndCount += newCount;
				}
			}
			
		    // remove duplicates in snds
		    for (newCount = 0; newCount < completeSndCount; newCount++)
			{
			    goodSound = TRUE;
			    soundID = completeSndArray[newCount];
			    for (count = 0; count < sndCount; count++)
				{
				    if (soundID == pSndArray[count])
					{
					    goodSound = FALSE;
					    break;
					}
				}
			    if (goodSound)
				{
				    pSndArray[sndCount++] = (XShortResourceID)soundID;
				}
			}
		    XBubbleSortArray((short *)pSndArray, (short)sndCount);
		}
	    XDisposePtr(completeSndArray);
	}
    return (short)sndCount;
}
Beispiel #11
0
/*
**	This will walk through all Instrument resources and collect all snd resources
**	that are used.
*/
short int XGatherAllSoundsFromAllInstruments(XShortResourceID *pSndArray, short int maxArraySize)
{
    short int			count, icount, sndCount, jcount;
    XShortResourceID	soundID;
    XBOOL				goodSound;
    XShortResourceID	instArray[MAX_INSTRUMENTS * MAX_BANKS];
    short int			totalInstruments;
    XShortResourceID	sndArray[MAX_SAMPLES];
    short int			totalSnds;
    XShortResourceID	*completeSndArray;
    short int			completeSndCount;
    InstrumentResource	*theX;
    long				size;

    completeSndCount = 0;
    sndCount = 0;
    completeSndArray = (XShortResourceID *)XNewPtr(MAX_INSTRUMENTS * MAX_BANKS * 128L * sizeof(XShortResourceID));
    if (completeSndArray)
	{
	    sndCount = 0;
	    totalInstruments = XGetInstrumentArray(instArray, MAX_INSTRUMENTS * MAX_BANKS);
	    if (totalInstruments)
		{
		    for (count = 0; count < totalInstruments; count++)
			{
			    theX = (InstrumentResource *)XGetAndDetachResource(ID_INST, instArray[count], &size);
			    if (theX)
				{
				    totalSnds = XCollectSoundsFromInstrument(theX, sndArray, MAX_SAMPLES);
				    XDisposePtr((XPTR)theX);

				    for (icount = 0; icount < totalSnds; icount++)
					{
					    completeSndArray[completeSndCount++] = sndArray[icount];
					}
				}
			}
		    XBubbleSortArray((short *)completeSndArray, (short)completeSndCount);

		    // Remove duplicates
		    for (jcount = 0; jcount < completeSndCount; jcount++)
			{
			    goodSound = TRUE;
			    soundID = completeSndArray[jcount];
			    for (count = 0; count < sndCount; count++)
				{
				    if (soundID == pSndArray[count])
					{
					    goodSound = FALSE;
					    break;
					}
				}
			    if (goodSound)
				{
				    if (sndCount < maxArraySize)
					{
					    pSndArray[sndCount++] = soundID;
					}
				}
			}
		}
	    XDisposePtr((XPTR)completeSndArray);
	}
    return sndCount;
}