Jamoma API  0.6.0.a19
SynthElement.h
1 /* Copyright 2007 Apple Inc. All Rights Reserved.
2 
3  Disclaimer: IMPORTANT: This Apple software is supplied to you by
4  Apple Inc. ("Apple") in consideration of your agreement to the
5  following terms, and your use, installation, modification or
6  redistribution of this Apple software constitutes acceptance of these
7  terms. If you do not agree with these terms, please do not use,
8  install, modify or redistribute this Apple software.
9 
10  In consideration of your agreement to abide by the following terms, and
11  subject to these terms, Apple grants you a personal, non-exclusive
12  license, under Apple's copyrights in this original Apple software (the
13  "Apple Software"), to use, reproduce, modify and redistribute the Apple
14  Software, with or without modifications, in source and/or binary forms;
15  provided that if you redistribute the Apple Software in its entirety and
16  without modifications, you must retain this notice and the following
17  text and disclaimers in all such redistributions of the Apple Software.
18  Neither the name, trademarks, service marks or logos of Apple Inc.
19  may be used to endorse or promote products derived from the Apple
20  Software without specific prior written permission from Apple. Except
21  as expressly stated in this notice, no other rights or licenses, express
22  or implied, are granted by Apple herein, including but not limited to
23  any patent rights that may be infringed by your derivative works or by
24  other works in which the Apple Software may be incorporated.
25 
26  The Apple Software is provided by Apple on an "AS IS" basis. APPLE
27  MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
28  THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
29  FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
30  OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
31 
32  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
33  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
36  MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
37  AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
38  STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
39  POSSIBILITY OF SUCH DAMAGE.
40 */
41 #ifndef __SynthElement__
42 #define __SynthElement__
43 
44 #include <Carbon/Carbon.h>
45 #include <AudioUnit/AudioUnit.h>
46 #include "MusicDeviceBase.h"
47 #include "SynthNoteList.h"
48 
49 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
50 class AUInstrumentBase;
51 
52 class SynthElement : public AUElement
53 {
54 public:
55  SynthElement(AUInstrumentBase *audioUnit, UInt32 inElement);
56  virtual ~SynthElement();
57 
58  UInt32 GetIndex() const { return mIndex; }
59 
60  AUInstrumentBase* GetAUInstrument() { return (AUInstrumentBase*)GetAudioUnit(); }
61 
62  CFStringRef GetName() const { return mName; }
63  void SetName(CFStringRef inName)
64  {
65  CFStringRef oldName = mName;
66  mName = inName;
67  CFRetain(mName);
68  if (oldName) CFRelease(oldName);
69  }
70 private:
71  CFStringRef mName;
72  UInt32 mIndex;
73 };
74 
75 
76 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
77 enum {
78  kMidiController_BankSelect = 0,
79  kMidiController_ModWheel = 1,
80  kMidiController_Breath = 2,
81  kMidiController_Foot = 4,
82  kMidiController_PortamentoTime = 5,
83  kMidiController_DataEntry = 6,
84  kMidiController_Volume = 7,
85  kMidiController_Balance = 8,
86  kMidiController_Pan = 10,
87  kMidiController_Expression = 11,
88 
89  // these controls have a (0-63) == off, (64-127) == on
90  kMidiController_Sustain = 64, //hold1
91  kMidiController_Portamento = 65,
92  kMidiController_Sostenuto = 66,
93  kMidiController_Soft = 67,
94  kMidiController_LegatoPedal = 68,
95  kMidiController_Hold2Pedal = 69,
96  kMidiController_FilterResonance = 71,
97  kMidiController_ReleaseTime = 72,
98  kMidiController_AttackTime = 73,
99  kMidiController_Brightness = 74,
100  kMidiController_DecayTime = 75,
101  kMidiController_VibratoRate = 76,
102  kMidiController_VibratoDepth = 77,
103  kMidiController_VibratoDelay = 78,
104 
105  // these controls have a 0-127 range and in MIDI they have no LSB (so fractional values are lost in MIDI)
106  kMidiController_ReverbLevel = 91,
107  kMidiController_ChorusLevel = 93,
108 
109  kMidiController_AllSoundOff = 120,
110  kMidiController_ResetAllControllers = 121,
111  kMidiController_AllNotesOff = 123
112 };
113 
114 struct MidiControls
115 {
116  MidiControls();
117  void Reset();
118 
119  UInt8 mControls[128];
120  UInt8 mPolyPressure[128];
121  UInt8 mMonoPressure;
122  UInt8 mProgramChange;
123  UInt16 mPitchBend;
124  UInt16 mActiveRPN;
125  UInt16 mActiveNRPN;
126  UInt16 mActiveRPValue;
127  UInt16 mActiveNRPValue;
128 
129  UInt16 mPitchBendDepth;
130  float mFPitchBendDepth;
131  float mFPitchBend;
132 
133  SInt16 GetHiResControl(UInt32 inIndex) const
134  {
135  return ((mControls[inIndex] & 127) << 7) | (mControls[inIndex + 32] & 127);
136  }
137 
138  void SetHiResControl(UInt32 inIndex, UInt8 inMSB, UInt8 inLSB)
139  {
140  mControls[inIndex] = inMSB;
141  mControls[inIndex + 32] = inLSB;
142  }
143 
144  float GetControl(UInt32 inIndex) const
145  {
146  if (inIndex < 32) {
147  return (float)mControls[inIndex] + (float)mControls[inIndex + 32] / 127.;
148  } else {
149  return (float)mControls[inIndex];
150  }
151  }
152 
153  float PitchBend() const { return mFPitchBend * mFPitchBendDepth; }
154 
155 };
156 
157 
158 class SynthGroupElement : public SynthElement
159 {
160 public:
161  enum {
162  kUnassignedGroup = 0xFFFFFFFF
163  };
164 
165  SynthGroupElement(AUInstrumentBase *audioUnit, UInt32 inElement);
166 
167  void NoteOff(NoteInstanceID inNoteID, UInt32 inFrame);
168  void SustainOn(UInt32 inFrame);
169  void SustainOff(UInt32 inFrame);
170  void SostenutoOn(UInt32 inFrame);
171  void SostenutoOff(UInt32 inFrame);
172 
173  void NoteEnded(SynthNote *inNote, UInt32 inFrame);
174 
175  void AllNotesOff(UInt32 inFrame);
176  void AllSoundOff(UInt32 inFrame);
177  void ResetAllControllers(UInt32 inFrame);
178 
179  UInt32 GetOutputBus() const { return mOutputBus; }
180  void SetOutputBus(UInt32 inBus) { mOutputBus = inBus; }
181 
182  void Reset();
183 
184  virtual OSStatus Render(UInt32 inNumberFrames);
185 
186  float GetControl(UInt32 inIndex) const { return mMidiControls.GetControl(inIndex); }
187  float PitchBend() const { return mMidiControls.PitchBend(); }
188 
189  MusicDeviceGroupID GroupID () const { return mGroupID; }
190  void SetGroupID (MusicDeviceGroupID inGroup);
191 
192 private:
193  friend class AUInstrumentBase;
194  friend class AUMonotimbralInstrumentBase;
195  friend class AUMultitimbralInstrumentBase;
196 
197  MidiControls mMidiControls;
198 
199  bool mSustainIsOn;
200  bool mSostenutoIsOn;
201  UInt32 mOutputBus;
202  MusicDeviceGroupID mGroupID;
203 
204 
205  SynthNoteList mNoteList[kNumberOfSoundingNoteStates];
206 };
207 
208 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
209 struct SynthKeyZone
210 {
211  UInt8 mLoNote;
212  UInt8 mHiNote;
213  UInt8 mLoVelocity;
214  UInt8 mHiVelocity;
215 };
216 
217 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
218 
219 const UInt32 kUnlimitedPolyphony = 0xFFFFFFFF;
220 
221 class SynthPartElement : public SynthElement
222 {
223 public:
224  SynthPartElement(AUInstrumentBase *audioUnit, UInt32 inElement);
225 
226  UInt32 GetGroupIndex() const { return mGroupIndex; }
227  bool InRange(Float32 inNote, Float32 inVelocity);
228 
229  UInt32 GetMaxPolyphony() const { return mMaxPolyphony; }
230  void SetMaxPolyphony(UInt32 inMaxPolyphony) { mMaxPolyphony = inMaxPolyphony; }
231 
232 private:
233  UInt32 mGroupIndex;
234  UInt32 mPatchIndex;
235  UInt32 mMaxPolyphony;
236  SynthKeyZone mKeyZone;
237 };
238 
239 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
240 inline AUInstrumentBase* SynthNote::GetAudioUnit() const
241  {
242  return (AUInstrumentBase*)mGroup->GetAudioUnit();
243  }
244 
245 inline Float32 SynthNote::GetGlobalParameter(AudioUnitParameterID inParamID) const
246  {
247  return mGroup->GetAudioUnit()->Globals()->GetParameter(inParamID);
248  }
249 
250 inline void SynthNote::NoteEnded(UInt32 inFrame)
251  {
252  mGroup->NoteEnded(this, inFrame);
253  mNoteID = 0xFFFFFFFF;
254  }
255 
256 inline float SynthNote::PitchBend() const
257  {
258  return mGroup->PitchBend();
259  }
260 
261 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
262 #endif