1 /*
2 Copyright (C) 2016 Apple Inc. All Rights Reserved.
3 See LICENSE.txt for this sample’s licensing information
4 
5 Abstract:
6 Part of Core Audio AUInstrument Base Classes
7 */
8 
9 #ifndef __SynthNote__
10 #define __SynthNote__
11 
12 #include <AudioUnit/AudioUnit.h>
13 #include <CoreAudio/CoreAudio.h>
14 #include "MusicDeviceBase.h"
15 
16 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17 
18 enum SynthNoteState {
19 	kNoteState_Attacked = 0,
20 	kNoteState_Sostenutoed = 1,
21 	kNoteState_ReleasedButSostenutoed = 2,
22 	kNoteState_ReleasedButSustained = 3,
23 	kNoteState_Released = 4,
24 	kNoteState_FastReleased = 5,
25 	kNoteState_Free = 6,
26 	kNumberOfActiveNoteStates = 5,
27 	kNumberOfSoundingNoteStates = 6,
28 	kNumberOfNoteStates = 7,
29 	kNoteState_Unset = kNumberOfNoteStates
30 };
31 
32 /*
33 		This table describes the state transitions for SynthNotes
34 
35         EVENT                   CURRENT STATE                                   NEW STATE
36         note on                 free                                            attacked
37         note off                attacked (and sustain on)                       released but sustained
38         note off                attacked                                        released
39         note off                sostenutoed                                     released but sostenutoed
40         sustain on              -- no changes --
41         sustain off             released but sustained                          released
42         sostenuto on            attacked                                        sostenutoed
43         sostenuto off           sostenutoed                                     attacked
44         sostenuto off           released but sostenutoed (and sustain on)       released but sustained
45         sostenuto off           released but sostenutoed                        released
46         end of note             any state                                       free
47 		soft voice stealing     any state                                       fast released
48 		hard voice stealing     any state                                       free
49 
50 		soft voice stealing happens when there is a note on event and NumActiveNotes > MaxActiveNotes
51 		hard voice stealing happens when there is a note on event and NumActiveNotes == NumNotes (no free notes)
52 		voice stealing removes the quietest note in the highest numbered state that has sounding notes.
53 */
54 
55 class SynthGroupElement;
56 class SynthPartElement;
57 class AUInstrumentBase;
58 
59 struct SynthNote
60 {
SynthNoteSynthNote61 	SynthNote() :
62 		mPrev(0), mNext(0), mPart(0), mGroup(0),
63 		mNoteID(0xffffffff),
64 		mState(kNoteState_Unset),
65 		mAbsoluteStartFrame(0),
66 		mRelativeStartFrame(0),
67 		mRelativeReleaseFrame(-1),
68 		mRelativeKillFrame(-1),
69 		mPitch(0.0f),
70 		mVelocity(0.0f)
71 	{
72 	}
73 
~SynthNoteSynthNote74 	virtual					~SynthNote() {}
75 
76 	virtual void			Reset();
77 	//! Returns true if active note resulted from this call, otherwise false
78 	virtual bool			AttackNote(
79 									SynthPartElement *				inPart,
80 									SynthGroupElement *				inGroup,
81 									NoteInstanceID					inNoteID,
82 									UInt64							inAbsoluteSampleFrame,
83 									UInt32							inOffsetSampleFrame,
84 									const MusicDeviceNoteParams		&inParams
85 							);
86 
87 	virtual OSStatus		Render(UInt64 inAbsoluteSampleFrame, UInt32 inNumFrames, AudioBufferList** inBufferList, UInt32 inOutBusCount) = 0;
88 	//! Returns true if active note resulted from this call, otherwise false
89 	virtual bool			Attack(const MusicDeviceNoteParams &inParams) = 0;
90 	virtual void			Kill(UInt32 inFrame); // voice is being stolen.
91 	virtual void			Release(UInt32 inFrame);
92 	virtual void			FastRelease(UInt32 inFrame);
93 	virtual Float32			Amplitude() = 0; // used for finding quietest note for voice stealing.
94 
95 	virtual void			NoteEnded(UInt32 inFrame);
96 
GetGroupSynthNote97 	SynthGroupElement*		GetGroup() const { return mGroup; }
GetPartSynthNote98 	SynthPartElement*		GetPart() const { return mPart; }
99 
100 	AUInstrumentBase*		GetAudioUnit() const;
101 
102 	Float32					GetGlobalParameter(AudioUnitParameterID inParamID) const;
103 
GetNoteIDSynthNote104 	NoteInstanceID			GetNoteID() const { return mNoteID; }
GetStateSynthNote105 	SynthNoteState			GetState() const { return mState; }
GetMidiKeySynthNote106 	UInt8					GetMidiKey() const { return (UInt8) mPitch; }
GetMidiVelocitySynthNote107 	UInt8					GetMidiVelocity() const { return (UInt8) mVelocity; }
108 
IsSoundingSynthNote109 	Boolean					IsSounding() const { return mState < kNumberOfSoundingNoteStates; }
IsActiveSynthNote110 	Boolean					IsActive() const { return mState < kNumberOfActiveNoteStates; }
GetAbsoluteStartFrameSynthNote111 	UInt64					GetAbsoluteStartFrame() const { return mAbsoluteStartFrame; }
GetRelativeStartFrameSynthNote112 	SInt32					GetRelativeStartFrame() const { return mRelativeStartFrame; }
GetRelativeReleaseFrameSynthNote113 	SInt32					GetRelativeReleaseFrame() const { return mRelativeReleaseFrame; }
GetRelativeKillFrameSynthNote114 	SInt32					GetRelativeKillFrame() const { return mRelativeKillFrame; }
115 
ListRemoveSynthNote116 	void					ListRemove() { mPrev = mNext = 0; } // only use when lists will be reset.
117 
118 	float					GetPitchBend() const;
119 	double					TuningA() const;
120 
GetPitchSynthNote121 	Float32					GetPitch() const { return mPitch; }	// returns raw pitch from MusicDeviceNoteParams
122 	virtual double			Frequency(); // returns the frequency of note + pitch bend.
123 	virtual double			SampleRate();
124 
125 	// linked list pointers
126 	SynthNote				*mPrev;
127 	SynthNote				*mNext;
128 
129 	friend class			SynthGroupElement;
130 	friend struct			SynthNoteList;
131 protected:
SetStateSynthNote132 	void					SetState(SynthNoteState inState) { mState = inState; }
133 private:
134 	SynthPartElement*		mPart;
135 	SynthGroupElement*	mGroup;
136 
137 	NoteInstanceID			mNoteID;
138 	SynthNoteState			mState;
139 	UInt64					mAbsoluteStartFrame;
140 	SInt32					mRelativeStartFrame;
141 	SInt32					mRelativeReleaseFrame;
142 	SInt32					mRelativeKillFrame;
143 
144 	Float32					mPitch;
145 	Float32					mVelocity;
146 };
147 
148 #endif
149 
150