Beispiel #1
0
ComponentResult		AUInstrumentBase::Render(   AudioUnitRenderActionFlags &	ioActionFlags,
												const AudioTimeStamp &			inTimeStamp,
												UInt32							inNumberFrames)
{
	PerformEvents(inTimeStamp);

	UInt32 numOutputs = Outputs().GetNumberOfElements();
	for (UInt32 j = 0; j < numOutputs; ++j)
	{
		AudioBufferList& bufferList = GetOutput(j)->GetBufferList();
		for (UInt32 k = 0; k < bufferList.mNumberBuffers; ++k)
		{
			memset(bufferList.mBuffers[k].mData, 0, bufferList.mBuffers[k].mDataByteSize);
		}
	}
	
	UInt32 numGroups = Groups().GetNumberOfElements();
	for (UInt32 j = 0; j < numGroups; ++j)
	{
		SynthGroupElement *group = (SynthGroupElement*)Groups().GetElement(j);
		OSStatus err = group->Render(inNumberFrames);
		if (err) return err;
	}
	mAbsoluteSampleFrame += inNumberFrames;
	return noErr;
}
Beispiel #2
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;
}
Beispiel #3
0
OSStatus	AUInstrumentBase::HandleControlChange(	UInt8 	inChannel,
													UInt8 	inController,
													UInt8 	inValue,
													UInt32	inStartFrame)
{
#if DEBUG_PRINT
	printf("AUInstrumentBase::HandleControlChange ch %u ctlr: %u val: %u frm: %u\n", inChannel, inController, inValue, inStartFrame);
#endif
	SynthGroupElement *gp = GetElForGroupID(inChannel);
	if (gp)
	{
		gp->ChannelMessage(inController, inValue);
	}
	else
		return kAudioUnitErr_InvalidElement;
	switch (inController)
	{
		case kMidiController_Sustain :
			if (inValue >= 64)
				SendPedalEvent(inChannel, SynthEvent::kEventType_SustainOn, inStartFrame);
			else
				SendPedalEvent(inChannel, SynthEvent::kEventType_SustainOff, inStartFrame);
			break;
		case kMidiController_Sostenuto :
			if (inValue >= 64)
				SendPedalEvent(inChannel, SynthEvent::kEventType_SostenutoOn, inStartFrame);
			else
				SendPedalEvent(inChannel, SynthEvent::kEventType_SostenutoOff, inStartFrame);
			break;
	}
	return noErr;
}
Beispiel #4
0
OSStatus			AUInstrumentBase::Render(   AudioUnitRenderActionFlags &	ioActionFlags,
												const AudioTimeStamp &			inTimeStamp,
												UInt32							inNumberFrames)
{
	PerformEvents(inTimeStamp);

	AUScope &outputs = Outputs();
	UInt32 numOutputs = outputs.GetNumberOfElements();
	for (UInt32 j = 0; j < numOutputs; ++j)
	{
		GetOutput(j)->PrepareBuffer(inNumberFrames);	// AUBase::DoRenderBus() only does this for the first output element
		AudioBufferList& bufferList = GetOutput(j)->GetBufferList();
		for (UInt32 k = 0; k < bufferList.mNumberBuffers; ++k)
		{
			memset(bufferList.mBuffers[k].mData, 0, bufferList.mBuffers[k].mDataByteSize);
		}
	}
	
	UInt32 numGroups = Groups().GetNumberOfElements();
	for (UInt32 j = 0; j < numGroups; ++j)
	{
		SynthGroupElement *group = (SynthGroupElement*)Groups().GetElement(j);
		OSStatus err = group->Render((SInt64)inTimeStamp.mSampleTime, inNumberFrames, outputs);
		if (err) return err;
	}
	mAbsoluteSampleFrame += inNumberFrames;
	return noErr;
}
Beispiel #5
0
OSStatus	AUInstrumentBase::HandleChannelPressure(UInt8 	inChannel,
													UInt8 	inValue,
													UInt32	inStartFrame)
{
	SynthGroupElement *gp = GetElForGroupID(inChannel);
	if (gp)
	{
		gp->ChannelMessage(kMidiMessage_ChannelPressure, inValue);
		return noErr;
	}
	else
		return kAudioUnitErr_InvalidElement;
}
Beispiel #6
0
OSStatus	AUInstrumentBase::HandlePitchWheel(		UInt8 	inChannel,
													UInt8 	inPitch1,	// LSB
													UInt8 	inPitch2,	// MSB
													UInt32	inStartFrame)
{
	SynthGroupElement *gp = GetElForGroupID(inChannel);
	if (gp)
	{
		gp->ChannelMessage(kMidiMessage_PitchWheel, (inPitch2 << 7) | inPitch1);
		return noErr;
	}
	else
		return kAudioUnitErr_InvalidElement;
}
Beispiel #7
0
OSStatus	AUInstrumentBase::HandlePolyPressure(	UInt8 	inChannel,
													UInt8 	inKey,
													UInt8	inValue,
													UInt32	inStartFrame)
{
	SynthGroupElement *gp = GetElForGroupID(inChannel);
	if (gp)
	{
		// Combine key and value into single argument.  UGLY!
		gp->ChannelMessage(kMidiMessage_PolyPressure, (inKey << 7) | inValue);
		return noErr;
	}
	else
		return kAudioUnitErr_InvalidElement;
}
Beispiel #8
0
OSStatus	AUInstrumentBase::HandleProgramChange(	UInt8 	inChannel,
													UInt8 	inValue)
{
#if DEBUG_PRINT
	printf("AUInstrumentBase::HandleProgramChange %u %u\n", inChannel, inValue);
#endif
	SynthGroupElement *gp = GetElForGroupID(inChannel);
	if (gp)
	{
		gp->ChannelMessage(kMidiMessage_ProgramChange, inValue);
		return noErr;
	}
	else
		return kAudioUnitErr_InvalidElement;
}
Beispiel #9
0
SynthGroupElement *	AUInstrumentBase::GetElForNoteID (NoteInstanceID inNoteID)
{
#if DEBUG_PRINT
	printf("GetElForNoteID id %u\n", inNoteID);
#endif
	AUScope & groups = Groups();
	unsigned int numEls = groups.GetNumberOfElements();
	
	for (unsigned int i = 0; i < numEls; ++i) {
		SynthGroupElement* el = reinterpret_cast<SynthGroupElement*>(groups.GetElement(i));
		if (el->GetNote(inNoteID) != NULL)	// searches for any note state
			return el;
	}
	throw static_cast<OSStatus>(kAudioUnitErr_InvalidElement);
}
Beispiel #10
0
void		AUInstrumentBase::PerformEvents(const AudioTimeStamp& inTimeStamp)
{
#if DEBUG_PRINT_RENDER
	printf("AUInstrumentBase::PerformEvents\n");
#endif
	SynthEvent *event;
	SynthGroupElement *group;
	
	while ((event = mEventQueue.ReadItem()) != NULL)
	{
#if DEBUG_PRINT_RENDER
		printf("event %08X %d\n", event, event->GetEventType());
#endif
		switch(event->GetEventType())
		{
			case SynthEvent::kEventType_NoteOn :
				RealTimeStartNote(GetElForGroupID (event->GetGroupID()), event->GetNoteID(),
									event->GetOffsetSampleFrame(), *event->GetParams());
				break;
			case SynthEvent::kEventType_NoteOff :
				RealTimeStopNote(GetElForGroupID (event->GetGroupID()), event->GetNoteID(),
					event->GetOffsetSampleFrame());
				break;
			case SynthEvent::kEventType_SustainOn :
				group = GetElForGroupID (event->GetGroupID());
				group->SustainOn(event->GetOffsetSampleFrame());
				break;
			case SynthEvent::kEventType_SustainOff :
				group = GetElForGroupID (event->GetGroupID());
				group->SustainOff(event->GetOffsetSampleFrame());
				break;
			case SynthEvent::kEventType_SostenutoOn :
				group = GetElForGroupID (event->GetGroupID());
				group->SostenutoOn(event->GetOffsetSampleFrame());
				break;
			case SynthEvent::kEventType_SostenutoOff :
				group = GetElForGroupID (event->GetGroupID());
				group->SostenutoOff(event->GetOffsetSampleFrame());
				break;
			case SynthEvent::kEventType_AllNotesOff :
				group = GetElForGroupID (event->GetGroupID());
				group->AllNotesOff(event->GetOffsetSampleFrame());
				break;
			case SynthEvent::kEventType_AllSoundOff :
				group = GetElForGroupID (event->GetGroupID());
				group->AllSoundOff(event->GetOffsetSampleFrame());
				break;
			case SynthEvent::kEventType_ResetAllControllers :
				group = GetElForGroupID (event->GetGroupID());
				group->ResetAllControllers(event->GetOffsetSampleFrame());
				break;
		}
		
		mEventQueue.AdvanceReadPtr();
	}
}
Beispiel #11
0
OSStatus			AUInstrumentBase::RealTimeStopNote(
												MusicDeviceGroupID 			inGroupID, 
												NoteInstanceID 				inNoteInstanceID, 
												UInt32 						inOffsetSampleFrame)
{
#if DEBUG_PRINT
	printf("AUInstrumentBase::RealTimeStopNote ch %d id %d\n", inGroupID, inNoteInstanceID);
#endif
	
	SynthGroupElement *gp = (inGroupID == kMusicNoteEvent_Unused
								? GetElForNoteID (inNoteInstanceID)
								: GetElForGroupID(inGroupID));
	if (gp)
	{
		gp->NoteOff (inNoteInstanceID, inOffsetSampleFrame);
	}
	
	return noErr;
}
Beispiel #12
0
SynthGroupElement *	AUInstrumentBase::GetElForGroupID (MusicDeviceGroupID	inGroupID)
{
	AUScope & groups = Groups();
	unsigned int numEls = groups.GetNumberOfElements();
	SynthGroupElement* unassignedEl = NULL;
	
	for (unsigned int i = 0; i < numEls; ++i) {
		SynthGroupElement* el = reinterpret_cast<SynthGroupElement*>(groups.GetElement(i));
		if (el->GroupID() == inGroupID) 
			return el;
		if (el->GroupID() == SynthGroupElement::kUnassignedGroup) {
			unassignedEl = el;
			break; // we fill this up from the start of the group scope vector
		}
	}
	if (unassignedEl) {
		unassignedEl->SetGroupID(inGroupID);
		return unassignedEl;
	}
	throw static_cast<OSStatus>(kAudioUnitErr_InvalidElement);
}
Beispiel #13
0
OSStatus	AUInstrumentBase::SendPedalEvent(MusicDeviceGroupID inGroupID, UInt32 inEventType, UInt32 inOffsetSampleFrame)
{
	
	if (InRenderThread ())
	{
		SynthGroupElement *group = GetElForGroupID(inGroupID);
		if (!group)
			return kAudioUnitErr_InvalidElement;
		
		switch (inEventType)
		{
			case SynthEvent::kEventType_SustainOn :
				group->SustainOn(inOffsetSampleFrame);
				break;
			case SynthEvent::kEventType_SustainOff :
				group->SustainOff(inOffsetSampleFrame);
				break;
			case SynthEvent::kEventType_SostenutoOn :
				group->SostenutoOn(inOffsetSampleFrame);
				break;
			case SynthEvent::kEventType_SostenutoOff :
				group->SostenutoOff(inOffsetSampleFrame);
				break;
			case SynthEvent::kEventType_AllNotesOff :
				group->AllNotesOff(inOffsetSampleFrame);
				mNumActiveNotes = CountActiveNotes();
				break;
			case SynthEvent::kEventType_AllSoundOff :
				group->AllSoundOff(inOffsetSampleFrame);
				mNumActiveNotes = CountActiveNotes();
				break;
			case SynthEvent::kEventType_ResetAllControllers :
				group->ResetAllControllers(inOffsetSampleFrame);
				break;
		}
	}
	else
	{
		SynthEvent *event = mEventQueue.WriteItem();
		if (!event) return -1; // queue full

		event->Set(inEventType, inGroupID, 0, 0, NULL);
		
		mEventQueue.AdvanceWritePtr();
	}
	return noErr;
}