Example #1
0
ComponentResult		AUInstrumentBase::Reset(			AudioUnitScope 					inScope,
														AudioUnitElement 				inElement)
{
#if DEBUG_PRINT
	printf("AUInstrumentBase::Reset\n");
#endif
	if (inScope == kAudioUnitScope_Global)
	{
		// kill all notes..
		mFreeNotes.Empty();
		for (UInt32 i=0; i<mNumNotes; ++i)
		{
			SynthNote *note = GetNote(i);
			if (note->IsSounding()) 
				note->Kill(0);
			note->ListRemove();
			mFreeNotes.AddNote(note);
		}
		mNumActiveNotes = 0;
		mAbsoluteSampleFrame = 0;

		// empty lists.
		UInt32 numGroups = Groups().GetNumberOfElements();
		for (UInt32 j = 0; j < numGroups; ++j)
		{
			SynthGroupElement *group = (SynthGroupElement*)Groups().GetElement(j);
			group->Reset();
		}
	}
	return noErr;
}
Example #2
0
void SynthGroupElement::NoteOff(NoteInstanceID inNoteID, UInt32 inFrame)
{	
#if DEBUG_PRINT_NOTE
	printf("SynthGroupElement::NoteOff %d\n", inNoteID);
#endif
	UInt32 noteState = kNoteState_Attacked;
	SynthNote *note = GetNote(inNoteID, true, &noteState);	// asking for unreleased only
	if (note)
	{
#if DEBUG_PRINT_NOTE
		printf("  old note state: %d\n", note->mState);
#endif
		if (noteState == kNoteState_Attacked)
		{
			mNoteList[noteState].RemoveNote(note);
			if (mSustainIsOn) {
				mNoteList[kNoteState_ReleasedButSustained].AddNote(note);
			} else {
				note->Release(inFrame);
				mNoteList[kNoteState_Released].AddNote(note);
			}
#if DEBUG_PRINT_NOTE
			printf("  new note state: %d\n", note->mState);
#endif
		}
		else /* if (noteState == kNoteState_Sostenutoed) */
		{
			mNoteList[kNoteState_Sostenutoed].RemoveNote(note);
			mNoteList[kNoteState_ReleasedButSostenutoed].AddNote(note);
		}
	}
}
Example #3
0
OSStatus SynthGroupElement::Render(SInt64 inAbsoluteSampleFrame, UInt32 inNumberFrames, AUScope &outputs)
{
	// Avoid duplicate calls at same sample offset
	if (inAbsoluteSampleFrame != mCurrentAbsoluteFrame)
	{
		mCurrentAbsoluteFrame = inAbsoluteSampleFrame;
		AudioBufferList* buffArray[16];
		UInt32 numOutputs = outputs.GetNumberOfElements();
		for (UInt32 outBus = 0; outBus < numOutputs && outBus < 16; ++outBus)
		{
			buffArray[outBus] = &GetAudioUnit()->GetOutput(outBus)->GetBufferList();
		}
		
		for (UInt32 i=0 ; i<kNumberOfSoundingNoteStates; ++i)
		{
			SynthNote *note = mNoteList[i].mHead;
			while (note)
			{
#if DEBUG_PRINT_RENDER
				printf("SynthGroupElement::Render: state %d, note %p\n", i, note);
#endif
				SynthNote *nextNote = note->mNext;
				
				OSStatus err = note->Render(inAbsoluteSampleFrame, inNumberFrames, buffArray, numOutputs);
				if (err) return err;
				
				note = nextNote;
			}
		}
	}
	return noErr;
}
Example #4
0
SynthNote*  AUInstrumentBase::VoiceStealing(UInt32 inFrame, bool inKillIt)
{

#if DEBUG_PRINT
	printf("enter voice stealing\n");
#endif
	// free list was empty so we need to kill a note.
	UInt32 startState = inKillIt ? kNoteState_FastReleased : kNoteState_Released;
	for (UInt32 i = startState; i <= startState; --i)
	{
#if DEBUG_PRINT
		printf(" steal state %d\n", i);
#endif
		UInt32 numGroups = Groups().GetNumberOfElements();
		for (UInt32 j = 0; j < numGroups; ++j)
		{
			SynthGroupElement *group = (SynthGroupElement*)Groups().GetElement(j);
#if DEBUG_PRINT
			printf(" steal group %d   size %d\n", j, group->mNoteList[i].Length());
#endif
			if (group->mNoteList[i].NotEmpty()) {
#if DEBUG_PRINT
				printf("not empty %d %d\n", i, j);
#endif
				SynthNote *note = group->mNoteList[i].FindMostQuietNote();
				if (inKillIt) {
#if DEBUG_PRINT
					printf("--=== KILL ===---\n");
#endif
					note->mRelativeKillFrame = inFrame;
					note->Kill(inFrame);
					group->mNoteList[i].RemoveNote(note);
					if (i != kNoteState_FastReleased)
						DecNumActiveNotes();
					return note;
				} else {
#if DEBUG_PRINT
					printf("--=== FAST RELEASE ===---\n");
#endif
					group->mNoteList[i].RemoveNote(note);
					note->FastRelease(inFrame);
					group->mNoteList[kNoteState_FastReleased].AddNote(note);
					DecNumActiveNotes(); // kNoteState_FastReleased counts as inactive for voice stealing purposes.
					return NULL;
				}
			}
		}
	}
#if DEBUG_PRINT
	printf("no notes to steal????\n");
#endif
	return NULL; // It should be impossible to get here. It means there were no notes to kill in any state. 
}
Example #5
0
UInt32		AUInstrumentBase::CountActiveNotes()
{
	// debugging tool.
	UInt32 sum = 0;
	for (UInt32 i=0; i<mNumNotes; ++i)
	{
		SynthNote *note = GetNote(i);
		if (note->GetState() <= kNoteState_Released) 
			sum++;
	}
	return sum;
}
Example #6
0
void		AUInstrumentBase::SetNotes(UInt32 inNumNotes, UInt32 inMaxActiveNotes, SynthNote* inNotes, UInt32 inNoteDataSize)
{
#if DEBUG_PRINT
	printf("AUInstrumentBase::SetNotes %d %d %08X %d\n", inNumNotes, inMaxActiveNotes, inNotes, inNoteDataSize);
#endif
	mNumNotes = inNumNotes;
	mMaxActiveNotes = inMaxActiveNotes;
	mNoteSize = inNoteDataSize;
	mNotes = inNotes;
	
	for (UInt32 i=0; i<mNumNotes; ++i)
	{
			SynthNote *note = GetNote(i);
			note->Reset();
			mFreeNotes.AddNote(note);
	}
}
Example #7
0
void SynthGroupElement::NoteOff(NoteInstanceID inNoteID, UInt32 inFrame)
{
#if DEBUG_PRINT
    printf("SynthGroupElement::NoteOff %d\n", inNoteID);
#endif
    SynthNote *note = mNoteList[kNoteState_Attacked].mHead;
    // see if this note is attacked.
    while (note && note->mNoteID != inNoteID)
    {
#if DEBUG_PRINT
        printf("   ? %08X %d\n", note, note->mNoteID);
#endif
        note = note->mNext;
    }

#if DEBUG_PRINT
    printf("  found %08X\n", note);
#endif
    if (note)
    {
#if DEBUG_PRINT
        printf("  old state %d\n", note->mState);
#endif
        mNoteList[kNoteState_Attacked].RemoveNote(note);
        note->Release(inFrame);
        mNoteList[kNoteState_Released].AddNote(note);
#if DEBUG_PRINT
        printf("  new state %d\n", note->mState);
#endif
    }
    else if (mSostenutoIsOn)
    {
        // see if this note is sostenutoed.
        note = mNoteList[kNoteState_Sostenutoed].mHead;
        while (note && note->mNoteID != inNoteID)
            note = note->mNext;
        if (note)
        {
            mNoteList[kNoteState_Sostenutoed].RemoveNote(note);
            mNoteList[kNoteState_ReleasedButSostenutoed].AddNote(note);
        }
    }
}
Example #8
0
void SynthGroupElement::AllSoundOff(UInt32 inFrame)
{
#if DEBUG_PRINT
	printf("SynthGroupElement::AllSoundOff\n");
#endif
	SynthNote *note;
	
	for (UInt32 i=0 ; i<kNumberOfActiveNoteStates; ++i)
	{
		note = mNoteList[i].mHead;
		while (note)
		{
			SynthNote *nextNote = note->mNext;
			
			mNoteList[i].RemoveNote(note);
			note->FastRelease(inFrame);
			mNoteList[kNoteState_FastReleased].AddNote(note);
			GetAUInstrument()->DecNumActiveNotes();
			note = nextNote;
		}
	}	
}
Example #9
0
void SynthGroupElement::AllNotesOff(UInt32 inFrame)
{
#if DEBUG_PRINT
	printf("SynthGroupElement::AllNotesOff\n");
#endif
	SynthNote *note;
	for (UInt32 i=0 ; i<=kNoteState_Sostenutoed; ++i)
	{
		UInt32 newState = (i == kNoteState_Attacked) ?
			kNoteState_Released : kNoteState_ReleasedButSostenutoed;
		note = mNoteList[i].mHead;
		while (note)
		{
			SynthNote *nextNote = note->mNext;
			
			mNoteList[i].RemoveNote(note);
			note->Release(inFrame);
			mNoteList[newState].AddNote(note);
			
			note = nextNote;
		}
	}	
}
Example #10
0
ComponentResult		AUMonotimbralInstrumentBase::RealTimeStartNote(	
															SynthGroupElement 			*inGroup, 
															NoteInstanceID 				inNoteInstanceID, 
															UInt32 						inOffsetSampleFrame, 
															const MusicDeviceNoteParams &inParams)
{
#if DEBUG_PRINT_RENDER
	printf("AUMonotimbralInstrumentBase::RealTimeStartNote %d\n", inNoteInstanceID);
#endif

	if (NumActiveNotes() + 1 > MaxActiveNotes()) 
	{
		VoiceStealing(inOffsetSampleFrame, false);
	}
	SynthNote *note = GetAFreeNote(inOffsetSampleFrame);
	if (!note) return -1;
	
	IncNumActiveNotes();
	note->AttackNote(NULL, inGroup, inNoteInstanceID, 
			mAbsoluteSampleFrame + inOffsetSampleFrame, inOffsetSampleFrame, inParams);
			
	inGroup->mNoteList[kNoteState_Attacked].AddNote(note);
	return noErr;
}
Example #11
0
OSStatus SynthGroupElement::Render(UInt32 inNumberFrames)
{
    SynthNote *note;
    AudioBufferList& bufferList = GetAudioUnit()->GetOutput(mOutputBus)->GetBufferList();

    for (UInt32 i=0 ; i<kNumberOfSoundingNoteStates; ++i)
    {
        note = mNoteList[i].mHead;
        while (note)
        {
#if DEBUG_PRINT
            printf("   note %d %08X   %d\n", i, note, inNumberFrames);
#endif
            SynthNote *nextNote = note->mNext;

            OSStatus err = note->Render(inNumberFrames, bufferList);
            if (err) return err;

            note = nextNote;
        }
    }

    return noErr;
}
Example #12
0
void SynthNote::Legato::apply(SynthNote &note, float *outl, float *outr)
{
    if(silent) // Silencer
        if(msg != LM_FadeIn) {
            memset(outl, 0, synth.bufferbytes);
            memset(outr, 0, synth.bufferbytes);
        }
    try {
        switch (msg) {
            case LM_CatchUp: // Continue the catch-up...
                if (decounter == -10)
                    decounter = fade.length;
                //Yea, could be done without the loop...
                for (int i = 0; i < synth.buffersize; ++i) {
                    decounter--;
                    if (decounter < 1) {
                        // Catching-up done, we can finally set
                        // the note to the actual parameters.
                        decounter = -10;
                        msg = LM_ToNorm;
                        LegatoParams pars{param.freq, param.vel, param.portamento,
                                          param.midinote, false};
                        note.legatonote(pars);
                        break;
                    }
                }
                break;
            case LM_FadeIn: // Fade-in
                if (decounter == -10)
                    decounter = fade.length;
                silent = false;
                for (int i = 0; i < synth.buffersize; ++i) {
                    decounter--;
                    if (decounter < 1) {
                        decounter = -10;
                        msg = LM_Norm;
                        break;
                    }
                    fade.m += fade.step;
                    outl[i] *= fade.m;
                    outr[i] *= fade.m;
                }
                break;
            case LM_FadeOut: // Fade-out, then set the catch-up
                if (decounter == -10)
                    decounter = fade.length;
                for (int i = 0; i < synth.buffersize; ++i) {
                    decounter--;
                    if (decounter < 1) {
                        for (int j = i; j < synth.buffersize; ++j) {
                            outl[j] = 0.0f;
                            outr[j] = 0.0f;
                        }
                        decounter = -10;
                        silent = true;
                        // Fading-out done, now set the catch-up :
                        decounter = fade.length;
                        msg = LM_CatchUp;
                        //This freq should make this now silent note to catch-up/resync
                        //with the heard note for the same length it stayed at the
                        //previous freq during the fadeout.
                        float catchupfreq = param.freq * (param.freq / lastfreq);
                        LegatoParams pars{catchupfreq, param.vel, param.portamento,
                                          param.midinote, false};
                        note.legatonote(pars);
                        break;
                    }
                    fade.m -= fade.step;
                    outl[i] *= fade.m;
                    outr[i] *= fade.m;
                }
                break;
            default:
                break;
        }
    } catch (std::bad_alloc &ba) {
        std::cerr << "failed to apply legato: " << ba.what() << std::endl;
    }
}