コード例 #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
long XGetSongTempoFactor(SongResource *pSong)
{
    long			tempo;

    tempo = 16667;	// 1.0
    if (pSong)
	{
	    switch (((SongResource_SMS *)pSong)->songType)
		{
		case SONG_TYPE_SMS:
		    tempo = XGetShort(&((SongResource_SMS *)pSong)->songTempo);
		    break;
		case SONG_TYPE_RMF:
		    tempo = XGetShort(&((SongResource_RMF *)pSong)->songTempo);
		    break;
		}
	    if (tempo == 0)
		{
		    tempo = 16667;
		}
	}
    return tempo;
}
コード例 #3
0
// Set a keysplit entry. The result will be ordered for the 68k CPU
void XSetKeySplitFromPtr(InstrumentResource *theX, short int entry, KeySplit *keysplit)
{
    KeySplit	*pSplits;
    short int	count;

    count = (short)XGetShort(&theX->keySplitCount);
    if ( (count) && (entry < count) )
	{
	    pSplits = (KeySplit *) ( ((unsigned char *)&theX->keySplitCount) + sizeof(short int));
	    pSplits[entry] = *keysplit;

	    XPutShort(&pSplits[entry].sndResourceID, (unsigned short)keysplit->sndResourceID);
	    XPutShort(&pSplits[entry].miscParameter1, (unsigned short)keysplit->miscParameter1);
	    XPutShort(&pSplits[entry].miscParameter2, (unsigned short)keysplit->miscParameter2);
	}
    else
	{
	    XSetMemory(keysplit, (long)sizeof(KeySplit), 0);
	}
}
コード例 #4
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;
}
コード例 #5
0
ファイル: GenSong.c プロジェクト: fatman2021/myforthprocessor
void GM_MergeExternalSong(void *theExternalSong, XShortResourceID theSongID, GM_Song *theSong)
{
    short int			maps;
    short int			count;
    short int			number;
    SongResource_SMS	*songSMS;
    SongResource_RMF	*songRMF;
    Remap				*pMap;

    if (theExternalSong && theSong)
	{
	    switch (((SongResource_SMS *)theExternalSong)->songType)
		{
		case SONG_TYPE_SMS:
		    songSMS = (SongResource_SMS *)theExternalSong;
		    theSong->songID = theSongID;
		    theSong->songPitchShift = songSMS->songPitchShift;
		    theSong->allowProgramChanges = (songSMS->flags1 & XBF_enableMIDIProgram) ? TRUE : FALSE;
		    theSong->defaultPercusionProgram = songSMS->defaultPercusionProgram;
		    theSong->defaultReverbType = songSMS->reverbType;
		    theSong->maxSongVoices = songSMS->maxNotes;
		    theSong->mixLevel = XGetShort(&songSMS->mixLevel);
		    theSong->maxEffectVoices = songSMS->maxEffects;
		    theSong->ignoreBadInstruments = (songSMS->flags2 & XBF_ignoreBadPatches) ? TRUE : FALSE;
		    maps = XGetShort(&songSMS->remapCount);
		    PV_SetTempo(theSong, XGetShort(&songSMS->songTempo));
		    theSong->songVolume = XGetSongVolume((SongResource *)theExternalSong);

		    // Load instruments
		    if ((songSMS->flags1 & XBF_enableMIDIProgram) == FALSE)
			{
			    number = (songSMS->flags1 & XBF_fileTrackFlag) ? MAX_TRACKS : MAX_CHANNELS;
			    for (count = 0; count < number; count++)
				{
				    theSong->instrumentRemap[count] = count;
				}
			}

				// Fill in remap first
		    if (maps)
			{
			    pMap = (Remap *)&songSMS->remaps;
			    for (count = 0; count < maps; count++)
				{
				    number = XGetShort(&pMap[count].instrumentNumber) & ((MAX_INSTRUMENTS*MAX_BANKS)-1);
				    theSong->instrumentRemap[number] = XGetShort(&pMap[count].ResourceINSTID);
				}
			}
		    break;
		
		case SONG_TYPE_RMF:
		    songRMF = (SongResource_RMF *)theExternalSong;
		    theSong->songID = theSongID;
		    theSong->songPitchShift = songRMF->songPitchShift;
		    theSong->allowProgramChanges = TRUE;			// aloways allow program changes
		    theSong->defaultPercusionProgram = -1;			// GM percussion only
		    theSong->defaultReverbType = songRMF->reverbType;
		    theSong->maxSongVoices = XGetShort(&songRMF->maxNotes);
		    theSong->mixLevel = XGetShort(&songRMF->mixLevel);
		    theSong->maxEffectVoices = XGetShort(&songRMF->maxEffects);
		    theSong->ignoreBadInstruments = TRUE;
		    PV_SetTempo(theSong, XGetShort(&songRMF->songTempo));
		    theSong->songVolume = XGetSongVolume((SongResource *)theExternalSong);
		    break;
		}
	}
}
コード例 #6
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;
}
コード例 #7
0
// Given an external instrument resource and an internal resource type fill the envelope data
// and if not there, place a default envelope
static void PV_GetEnvelopeData(InstrumentResource	*theX, GM_Instrument *theI, INT32 theXSize)
{
    INT32					count, count2, lfoCount;
    INT32					size, unitCount, unitType, unitSubCount;
    unsigned short int		data;
    register char 			*pData, *pData2;
    register char 			*pUnit;
    register KeySplit 		*pSplits;
    register LFORecord		*pLFO;
    register ADSRRecord		*pADSR;
    register CurveRecord	*pCurve;
    XBOOL					disableModWheel;

    disableModWheel = FALSE;
    theI->volumeADSRRecord.currentTime = 0;
    theI->volumeADSRRecord.currentPosition = 0;
    theI->volumeADSRRecord.currentLevel = 0;
    theI->volumeADSRRecord.previousTarget = 0;
    theI->volumeADSRRecord.mode = 0;
    theI->volumeADSRRecord.sustainingDecayLevel = 65536;

    theI->LPF_frequency = 0;
    theI->LPF_resonance = 0;
    theI->LPF_lowpassAmount = 0;

    // fill default
    theI->volumeADSRRecord.ADSRLevel[0] = VOLUME_RANGE;
    theI->volumeADSRRecord.ADSRFlags[0] = ADSR_TERMINATE;
    theI->volumeADSRRecord.ADSRTime[0] = 0;
    theI->LFORecordCount = 0;
    theI->curveRecordCount = 0;
    theI->extendedFormat = FALSE;
    pUnit = NULL;
    size = theXSize;
    if (theX && size)
	{
	    if (theX->flags1 & ZBF_extendedFormat)
		{
		    // search for end of tremlo data $8000. If not there, don't walk past end of instrument
		    pSplits = (KeySplit *) ( ((char *)&theX->keySplitCount) + sizeof(short));
		    count = XGetShort(&theX->keySplitCount);
		    pData = (char *)&pSplits[count];
		    pData2 = (char *)theX;
		    size -= (INT32) (pData - pData2);
		    for (count = 0; count < size; count++)
			{
			    data = XGetShort(&pData[count]);
			    if (data == 0x8000)
				{
				    count += 4;								// skip past end token and extra word
				    data = (unsigned short)pData[count] + 1;			// get first string length;
				    count2 = (INT32)pData[count+data] + 1;			// get second string length
				    pUnit = (char *) (&pData[count + data + count2]);
				    // NOTE: src will be non aligned, possibly on a byte boundry.
				    break;
				}
			}
		    if (pUnit)
			{
			    theI->extendedFormat = TRUE;
			    pUnit += 12;		// reserved global space

			    unitCount = *pUnit;		// how many unit records?
			    pUnit++;					// byte
			    if (unitCount)
				{
				    lfoCount = 0;
				    for (count = 0; count < unitCount; count++)
					{
					    unitType = XGetLong(pUnit) & 0x5F5F5F5F;
					    pUnit += 4;	// long
					    switch (unitType)
						{
						case INST_EXPONENTIAL_CURVE:
						    if (theI->curveRecordCount >= MAX_CURVES)	// can only handle 4
							{
							    goto bailoninstrument;
							}
						    pCurve = &theI->curve[theI->curveRecordCount];
						    theI->curveRecordCount++;
						    pCurve->tieFrom = XGetLong(pUnit) & 0x5F5F5F5F; pUnit += 4;
						    pCurve->tieTo = XGetLong(pUnit) & 0x5F5F5F5F; pUnit += 4;
						    unitSubCount = *pUnit++;
						    if (unitSubCount > MAX_CURVES)
							{
							    goto bailoninstrument;
							}
						    pCurve->curveCount = (short int)unitSubCount;
						    for (count2 = 0; count2 < unitSubCount; count2++)
							{
							    pCurve->from_Value[count2] = *pUnit++;
							    pCurve->to_Scalar[count2] = XGetShort(pUnit);
							    pUnit += 2;
							}
						    // there's one extra slot in the definition to allow for this PAST the end of the 8 possible entries
						    pCurve->from_Value[count2] = 127;
						    pCurve->to_Scalar[count2] = pCurve->to_Scalar[count2];
						    break;
						case INST_ADSR_ENVELOPE:
						    unitSubCount = *pUnit;		// how many unit records?
						    pUnit++;					// byte
						    if (unitSubCount > ADSR_STAGES)
							{	// can't have more than ADSR_STAGES stages
							    goto bailoninstrument;
							}
						    pADSR = &theI->volumeADSRRecord;
						    for (count2 = 0; count2 < unitSubCount; count2++)
							{
							    pADSR->ADSRLevel[count2] = XGetLong(pUnit);
							    pUnit += 4;

							    pADSR->ADSRTime[count2] = XGetLong(pUnit);
							    pUnit += 4;

							    pADSR->ADSRFlags[count2] = XGetLong(pUnit) & 0x5F5F5F5F;
							    pUnit += 4;
							}
						    break;

						case INST_LOW_PASS_FILTER:		// low pass global filter parameters
						    theI->LPF_frequency = XGetLong(pUnit);
						    pUnit += 4;
						    theI->LPF_resonance = XGetLong(pUnit);
						    pUnit += 4;
						    theI->LPF_lowpassAmount = XGetLong(pUnit);
						    pUnit += 4;
						    break;

						case INST_DEFAULT_MOD:		// default mod wheel hookup
						    disableModWheel = TRUE;
						    break;

						    // LFO types
						case INST_PITCH_LFO:
						case INST_VOLUME_LFO:
						case INST_STEREO_PAN_LFO:
						case INST_STEREO_PAN_NAME2:
						case INST_LOW_PASS_AMOUNT:
						case INST_LPF_DEPTH:
						case INST_LPF_FREQUENCY:
						    if (lfoCount > MAX_LFOS)
							{
							    goto bailoninstrument;
							}
						    unitSubCount = *pUnit;		// how many unit records?
						    pUnit++;					// byte
						    if (unitSubCount > ADSR_STAGES)
							{	// can't have more than ADSR_STAGES stages
							    //DEBUG_STR("\p too many stages");
							    goto bailoninstrument;
							}
						    pLFO = &theI->LFORecords[lfoCount];
						    for (count2 = 0; count2 < unitSubCount; count2++)
							{
							    pLFO->a.ADSRLevel[count2] = XGetLong(pUnit);
							    pUnit += 4;
							    pLFO->a.ADSRTime[count2] = XGetLong(pUnit);
							    pUnit += 4;
							    pLFO->a.ADSRFlags[count2] = XGetLong(pUnit) & 0x5F5F5F5F;
							    pUnit += 4;
							}
						    pLFO->where_to_feed = unitType & 0x5F5F5F5F;

						    pLFO->period = XGetLong(pUnit);
						    pUnit += 4;
						    pLFO->waveShape = XGetLong(pUnit);
						    pUnit += 4;
						    pLFO->DC_feed = XGetLong(pUnit);
						    pUnit += 4;
						    pLFO->level = XGetLong(pUnit);
						    pUnit += 4;

						    pLFO->currentWaveValue = 0;
						    pLFO->currentTime = 0;
						    pLFO->LFOcurrentTime = 0;
						    pLFO->a.currentTime = 0;
						    pLFO->a.currentPosition = 0;
						    pLFO->a.currentLevel = 0;
						    pLFO->a.previousTarget = 0;
						    pLFO->a.mode = 0;
						    pLFO->a.sustainingDecayLevel = 65536;
						    lfoCount++;
						    break;
						}
					}

				    if ((lfoCount < (MAX_LFOS-1)) && (theI->curveRecordCount < MAX_CURVES) && (disableModWheel == FALSE))
					{
					    pCurve = &theI->curve[theI->curveRecordCount];
					    theI->curveRecordCount++;

					    // Create a straight-line curve function to tie mod wheel to pitch LFO
					    pCurve->tieFrom = MOD_WHEEL_CONTROL;
					    pCurve->tieTo = PITCH_LFO;
					    pCurve->curveCount = 2;
					    pCurve->from_Value[0] = 0;
					    pCurve->to_Scalar[0] = 0;
					    pCurve->from_Value[1] = 127;
					    pCurve->to_Scalar[1] = 256;
					    pCurve->from_Value[2] = 127;
					    pCurve->to_Scalar[2] = 256;

					    // Create a default pitch LFO unit to tie the MOD wheel to.
					    pLFO = &theI->LFORecords[lfoCount];
					    pLFO->where_to_feed = PITCH_LFO;
					    pLFO->period = 180000;
					    pLFO->waveShape = SINE_WAVE;
					    pLFO->DC_feed = 0;
					    pLFO->level = 64;
					    pLFO->currentWaveValue = 0;
					    pLFO->currentTime = 0;
					    pLFO->LFOcurrentTime = 0;
					    pLFO->a.ADSRLevel[0] = 65536;
					    pLFO->a.ADSRTime[0] = 0;
					    pLFO->a.ADSRFlags[0] = ADSR_TERMINATE;
					    pLFO->a.currentTime = 0;
					    pLFO->a.currentPosition = 0;
					    pLFO->a.currentLevel = 0;
					    pLFO->a.previousTarget = 0;
					    pLFO->a.mode = 0;
					    pLFO->a.sustainingDecayLevel = 65536;
					    lfoCount++;
					}

				    theI->LFORecordCount = (unsigned char)lfoCount;
				bailoninstrument:
				    ;
				}
			}
		}
	}
}
コード例 #8
0
/*
**	Given an INST resource, this will return an array of snd resources
**	that are used for this instrument
*/
short int XCollectSoundsFromInstrument(InstrumentResource *theX, XShortResourceID *sndArray, short maxArraySize)
{
    short int			sndOutCount, sndCount, splitCount, count, count2;
    KeySplit			theSplit;
    XShortResourceID	countSndArray[MAX_SAMPLES];		/* Max samples per instrument */
    XBOOL				goodSound;
    XShortResourceID	soundID;

    sndCount = 0;
    sndOutCount = 0;
    if (theX)
	{
	    splitCount = (short)XGetShort(&theX->keySplitCount);
	    if ( splitCount == 0)
		{
		    if (maxArraySize > 1)
			{
			    sndCount = 1;
			    countSndArray[0] = (XShortResourceID)XGetShort(&theX->sndResourceID);
			    if (countSndArray[0] == (XShortResourceID)-1)
				{
				    sndCount = 0;
				}
			}
		}
	    else
		{
		    if (maxArraySize > splitCount)
			{
			    sndCount = 1;
			    countSndArray[0] = (XShortResourceID)XGetShort(&theX->sndResourceID);
			    if (countSndArray[0] == (XShortResourceID)-1)
				{
				    sndCount = 0;
				}
			    for (count = 0; count < splitCount; count++)
				{
				    XGetKeySplitFromPtr(theX, count, &theSplit);
				    countSndArray[sndCount] = theSplit.sndResourceID;
				    if (countSndArray[sndCount] != (XShortResourceID)-1)
					{
					    sndCount++;
					}
				}
			}
		}
	    XBubbleSortArray((short *)countSndArray, (short)sndCount);

	    // Remove duplicates
	    sndOutCount = 0;
	    for (count = 0; count < sndCount; count++)
		{
		    goodSound = TRUE;
		    soundID = countSndArray[count];
		    for (count2 = 0; count2 < sndOutCount; count2++)
			{
			    if (soundID == sndArray[count2])
				{
				    goodSound = FALSE;
				    break;
				}
			}
		    if (goodSound)
			{
			    sndArray[sndOutCount++] = soundID;
			}
		}
	}
    return sndOutCount;
}