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