/[svn]/linuxsampler/trunk/src/hostplugins/au/PluginAU.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/hostplugins/au/PluginAU.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1845 - (show annotations) (download)
Tue Feb 24 17:41:02 2009 UTC (15 years, 2 months ago) by iliev
File size: 13627 byte(s)
* AU plugin, work in progress: added the source files

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2009 Grigor Iliev *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #include "PluginAU.h"
24
25 #include "../../drivers/audio/AudioChannel.h"
26
27 #if AU_DEBUG_DISPATCHER
28 #include <AUDebugDispatcher.h>
29 #endif
30
31 COMPONENT_ENTRY(PluginAU)
32
33 //namespace LinuxSampler {
34
35 const midi_chan_t PluginAU::midiChns[16] = {
36 midi_chan_1, midi_chan_2, midi_chan_3, midi_chan_4, midi_chan_5,
37 midi_chan_6, midi_chan_7, midi_chan_8, midi_chan_9, midi_chan_10,
38 midi_chan_11, midi_chan_12, midi_chan_13, midi_chan_14, midi_chan_15,
39 midi_chan_16
40 };
41
42 AUPreset PluginAU::factoryPresets[kFactoryPresetCount] = {
43 { kOneSamplerChannel, CFSTR("LS: 1 Channel") },
44 { k16SamplerChannels, CFSTR("LS: 16 Channels") }
45 };
46
47 PluginAU::PluginAU(ComponentInstance inComponentInstance)
48 : MusicDeviceBase(inComponentInstance, 0, 1), Plugin(false) {
49
50 #if AU_DEBUG_DISPATCHER
51 mDebugDispatcher = new AUDebugDispatcher(this);
52 #endif
53 charBufSize = 512;
54 charBuf = new char[charBufSize];
55 InstallListeners();
56
57 SetAFactoryPresetAsCurrent(factoryPresets[kDefaultPreset]);
58 }
59
60 PluginAU::~PluginAU() {
61 #if AU_DEBUG_DISPATCHER
62 delete mDebugDispatcher;
63 #endif
64 delete [] charBuf;
65 UninstallListeners();
66 }
67
68 void PluginAU::InstallListeners() {
69 AddPropertyListener(kAudioUnitProperty_ContextName, PropertyListenerCallback, this);
70
71 }
72
73 void PluginAU::UninstallListeners() {
74 RemovePropertyListener(kAudioUnitProperty_ContextName, PropertyListenerCallback, this, true);
75 }
76
77 void PluginAU::PropertyListenerCallback (
78 void* inRefCon,
79 AudioUnit ci,
80 AudioUnitPropertyID inID,
81 AudioUnitScope inScope,
82 AudioUnitElement inElement
83 ) {
84 ((PluginAU*)inRefCon)->PropertyChanged(inID, inScope, inElement);
85 }
86
87 void PluginAU::PropertyChanged (
88 AudioUnitPropertyID inID,
89 AudioUnitScope inScope,
90 AudioUnitElement inElement
91 ) {
92 switch (inID) {
93 case kAudioUnitProperty_ContextName:
94 // TODO:
95 //GetStr(mContextName);
96 break;
97 }
98 }
99
100 ComponentResult PluginAU::GetPropertyInfo (
101 AudioUnitPropertyID inID,
102 AudioUnitScope inScope,
103 AudioUnitElement inElement,
104 UInt32& outDataSize,
105 Boolean& outWritable
106 ) {
107 // TODO:
108 return MusicDeviceBase::GetPropertyInfo(inID, inScope, inElement, outDataSize, outWritable);
109 }
110
111 ComponentResult PluginAU::GetProperty (
112 AudioUnitPropertyID inID,
113 AudioUnitScope inScope,
114 AudioUnitElement inElement,
115 void* outData
116 ) {
117 // TODO:
118 return MusicDeviceBase::GetProperty(inID, inScope, inElement, outData);
119 }
120
121 ComponentResult PluginAU::SetProperty (
122 AudioUnitPropertyID inID,
123 AudioUnitScope inScope,
124 AudioUnitElement inElement,
125 const void* inData,
126 UInt32 inDataSize
127 ) {
128 switch (inID) {
129 case kAudioUnitProperty_AUHostIdentifier:
130 if(inData != NULL) {
131 AUHostIdentifier* host = (AUHostIdentifier*)inData;
132 hostName = GetHostNameByID(GetStr(host->hostName));
133 }
134 break;
135 }
136 return MusicDeviceBase::SetProperty(inID, inScope, inElement, inData, inDataSize);
137 }
138
139 ComponentResult PluginAU::GetPresets(CFArrayRef* outData) const {
140 if (outData == NULL) return noErr;
141
142 CFMutableArrayRef presetsArray = CFArrayCreateMutable (
143 NULL, kFactoryPresetCount, NULL
144 );
145
146 for (int i = 0; i < kFactoryPresetCount; i++) {
147 CFArrayAppendValue(presetsArray, &factoryPresets[i] );
148 }
149
150 *outData = (CFArrayRef)presetsArray;
151 return noErr;
152 }
153
154 OSStatus PluginAU::NewFactoryPresetSet(const AUPreset& inNewFactoryPreset) {
155 if(global == NULL) return noErr;
156
157 switch(inNewFactoryPreset.presetNumber) {
158 case kOneSamplerChannel:
159 AddSamplerChannel("GIG", midi_chan_1);
160 break;
161 case k16SamplerChannels:
162 Set16SamplerChannelsPreset();
163 break;
164 default:
165 return kAudioUnitErr_InvalidProperty;
166 }
167
168 SetAFactoryPresetAsCurrent(inNewFactoryPreset);
169 return noErr;
170 }
171
172 UInt32 PluginAU::SupportedNumChannels(const AUChannelInfo** outInfo) {
173 static AUChannelInfo plugChannelInfo = { 0, -1 };
174 if (outInfo != NULL) *outInfo = &plugChannelInfo;
175 return 1;
176 }
177
178 ComponentResult PluginAU::Initialize() {
179 MusicDeviceBase::Initialize();
180
181 // The timeconsuming tasks delayed until the pluging is to be used
182 PreInit();
183
184 if(pAudioDevice) {
185 RemoveChannels();
186 global->pSampler->DestroyAudioOutputDevice(pAudioDevice);
187 pAudioDevice = NULL;
188 }
189
190 if(pMidiDevice) {
191 global->pSampler->DestroyMidiInputDevice(pMidiDevice);
192 pMidiDevice = NULL;
193 }
194
195 int srate = (int)GetStreamFormat(kAudioUnitScope_Output, 0).mSampleRate;
196 int chnNum = GetStreamFormat(kAudioUnitScope_Output, 0).NumberChannels();
197
198 Init(srate, GetMaxFramesPerSlice(), chnNum);
199
200 if(hostName.empty()) {
201 hostName = GetHostNameByID(GetHostBundleID());
202 }
203
204 if(!hostName.empty()) {
205 for(int i = 0; i < pMidiDevice->PortCount(); i++) {
206 DeviceRuntimeParameter* param;
207 param = pMidiDevice->GetPort(i)->PortParameters()["NAME"];
208 if(param != NULL) param->SetValue(hostName + " " + ToString(i + 1));
209
210 }
211 }
212
213 if(!hostName.empty()) {
214 for(int i = 0; i < pAudioDevice->ChannelCount(); i++) {
215 DeviceRuntimeParameter* param;
216 param = pAudioDevice->Channel(i)->ChannelParameters()["NAME"];
217 if(param != NULL) param->SetValue(hostName + " " + ToString(i + 1));
218
219 }
220 }
221
222 NewFactoryPresetSet(factoryPresets[kDefaultPreset]);
223
224 /*AudioChannelLayout* pLayout = CAAudioChannelLayout::Create(chnNum);
225 if(pLayout != NULL) {
226 for(int i = 0; i < chnNum; i++) {
227 pLayout->mChannelDescriptions[i].mChannelLabel =
228 }
229 SetAudioChannelLayout(kAudioUnitScope_Output, 0, pLayout);
230 }*/
231
232 return noErr;
233 }
234
235 bool PluginAU::StreamFormatWritable(AudioUnitScope scope, AudioUnitElement element) {
236 return IsInitialized() ? false : true;
237 }
238
239 OSStatus PluginAU::HandleMidiEvent (
240 UInt8 inStatus, UInt8 inChannel,
241 UInt8 inData1, UInt8 inData2,
242 UInt32 inStartFrame
243 ) {
244 if(!IsInitialized()) return kAudioUnitErr_Uninitialized;
245 MidiInputPort* port = pMidiDevice->Port();
246
247 switch (inStatus) {
248 case 0x90:
249 if(inData2) {
250 port->DispatchNoteOn (
251 inData1, inData2, inChannel, inStartFrame
252 );
253 } else {
254 port->DispatchNoteOff (
255 inData1, inData2, inChannel, inStartFrame
256 );
257 }
258 break;
259 case 0x80:
260 port->DispatchNoteOff (
261 inData1, inData2, inChannel, inStartFrame
262 );
263 break;
264 case 0xB0:
265 port->DispatchControlChange (
266 inData1, inData2, inChannel, inStartFrame
267 );
268 break;
269 case 0xC0:
270 port->DispatchProgramChange(inData1, inChannel);
271 break;
272 case 0xE0:
273 port->DispatchPitchbend(inData2, inChannel, inStartFrame);
274 break;
275 case 0xD0:
276 port->DispatchControlChange (
277 inData1, inData2, inChannel, inStartFrame
278 );
279 break;
280 }
281
282 return noErr;
283 }
284
285 ComponentResult PluginAU::Render (
286 AudioUnitRenderActionFlags& ioActionFlags,
287 const AudioTimeStamp& inTimeStamp,
288 UInt32 inNumberFrames
289 ) {
290 float* buf;
291 int chnCount = GetOutput(0)->GetBufferList().mNumberBuffers;
292 for(int i = 0; i < chnCount; i++) {
293 buf = (float*)GetOutput(0)->GetBufferList().mBuffers[i].mData;
294 pAudioDevice->Channel(i)->SetBuffer(buf);
295 }
296
297 pAudioDevice->Render(inNumberFrames);
298 return noErr;
299 }
300
301 void PluginAU::Set16SamplerChannelsPreset() {
302 RemoveChannels();
303 for(int i = 0; i < 16; i++) {
304 AddSamplerChannel("GIG", midiChns[i]);
305 }
306 }
307
308 void PluginAU::AddSamplerChannel(const char* engine, midi_chan_t midiChn) {
309 SamplerChannel* channel = global->pSampler->AddSamplerChannel();
310 channel->SetEngineType(engine);
311 channel->SetAudioOutputDevice(pAudioDevice);
312 channel->SetMidiInputDevice(pMidiDevice);
313 channel->SetMidiInputChannel(midiChn);
314 }
315
316 OSStatus PluginAU::GetInstrumentCount(UInt32 &outInstCount) const {
317 // TODO:
318 return MusicDeviceBase::GetInstrumentCount(outInstCount);
319 }
320
321 std::string PluginAU::GetHostNameByID(std::string Identifier) {
322 std::string name;
323 if(Identifier == "com.apple.logic.pro") {
324 name = "Logic Pro";
325 } else if(Identifier == "com.apple.garageband") {
326 name = "GarageBand";
327 } else if(Identifier == "com.ableton.live") {
328 name = "Ableton Live";
329 } else if(Identifier == "com.apple.audio.aulab") {
330 name = "AULab";
331 }
332
333 return name;
334 }
335
336 std::string PluginAU::GetHostBundleID() {
337 std::string id;
338 CFStringRef identifier;
339 CFBundleRef mainBundle = CFBundleGetMainBundle();
340 if (mainBundle) {
341 identifier = CFBundleGetIdentifier(mainBundle);
342 id = GetStr(identifier);
343 }
344
345 return id;
346 }
347
348 std::string PluginAU::GetStr(CFStringRef s) {
349 if(s == NULL) return std::string("");
350
351 CFRetain(s);
352 CFIndex len = CFStringGetLength(s) + 1;
353 if(charBufSize < len) {
354 delete [] charBuf;
355 charBufSize *= 2;
356 if(charBufSize < len) charBufSize = len;
357 charBuf = new char[charBufSize];
358 }
359
360 std::string s2;
361 if(CFStringGetCString(s, charBuf, charBufSize, kCFStringEncodingASCII)) {
362 s2 = charBuf;
363 }
364 CFRelease(s);
365
366 return s2;
367 }
368
369 ComponentResult PluginAU::SaveState(CFPropertyListRef* outData) {
370 ComponentResult result = AUBase::SaveState(outData);
371 if(global == NULL || result != noErr) return result;
372
373 void** d = const_cast<void**> (outData);
374 CFMutableDictionaryRef dict = static_cast<CFMutableDictionaryRef> (*d);
375
376 std::string s = GetState();
377 CFStringRef cfsState = CFStringCreateWithCString(NULL, s.c_str(), kCFStringEncodingASCII);
378
379 CFDictionarySetValue(dict, CFSTR("org.linuxsampler.LinuxSamplerPluginAU"), cfsState);
380 CFRelease(cfsState);
381
382 return noErr;
383 }
384
385 ComponentResult PluginAU::RestoreState(CFPropertyListRef inData) {
386 ComponentResult result = AUBase::RestoreState(inData);
387 if(global == NULL || result != noErr) return result;
388
389 CFDictionaryRef dict = static_cast<CFDictionaryRef>(inData);
390
391 const void* d = CFDictionaryGetValue (
392 dict, CFSTR("org.linuxsampler.LinuxSamplerPluginAU")
393 );
394
395 CFStringRef str = static_cast<CFStringRef>(d);
396 if(str != NULL) SetState(GetStr(str));
397
398 return noErr;
399 }
400
401 //} // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC