52cfc187afe20d7bfe941ef0bffa1587419e7e30
[ardour.git] / libs / ardour / audio_unit.cc
1 /*
2     Copyright (C) 2006 Paul Davis 
3         Written by Taybin Rutkin
4         
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #include <ardour/audio_unit.h>
22 #include <ardour/utils.h>
23
24 #include <CoreServices/CoreServices.h>
25 #include <AudioUnit/AudioUnit.h>
26
27 using namespace ARDOUR;
28
29 PluginInfoList
30 AUPluginInfo::discover ()
31 {
32         PluginInfoList plugs;
33
34         int numTypes = 2;    // this magic number was retrieved from the apple AUHost example.
35
36         ComponentDescription desc;
37         desc.componentFlags = 0;
38         desc.componentFlagsMask = 0;
39         desc.componentSubType = 0;
40         desc.componentManufacturer = 0;
41
42         vector<ComponentDescription> vCompDescs;
43
44         for (int i = 0; i < numTypes; ++i) {
45                 if (i == 1) {
46                         desc.componentType = kAudioUnitType_MusicEffect;
47                 } else {
48                         desc.componentType = kAudioUnitType_Effect;
49                 }
50
51                 Component comp = 0;
52
53                 comp = FindNextComponent (NULL, &desc);
54                 while (comp != NULL) {
55                         ComponentDescription temp;
56                         GetComponentInfo (comp, &temp, NULL, NULL, NULL);
57                         vCompDescs.push_back(temp);
58                         comp = FindNextComponent (comp, &desc);
59                 }
60         }
61
62         for (unsigned int i = 0; i < vCompDescs.size(); ++i) {
63
64                 // the following large block is just for determining the name of the plugin.
65                 CFStringRef itemName = NULL;
66                 // Marc Poirier -style item name
67                 Component auComponent = FindNextComponent (0, &(vCompDescs[i]));
68                 if (auComponent != NULL) {
69                         ComponentDescription dummydesc;
70                         Handle nameHandle = NewHandle(sizeof(void*));
71                         if (nameHandle != NULL) {
72                                 OSErr err = GetComponentInfo(auComponent, &dummydesc, nameHandle, NULL, NULL);
73                                 if (err == noErr) {
74                                         ConstStr255Param nameString = (ConstStr255Param) (*nameHandle);
75                                         if (nameString != NULL) {
76                                                 itemName = CFStringCreateWithPascalString(kCFAllocatorDefault, nameString, CFStringGetSystemEncoding());
77                                         }
78                                 }
79                                 DisposeHandle(nameHandle);
80                         }
81                 }
82
83                 // if Marc-style fails, do the original way
84                 if (itemName == NULL) {
85                         CFStringRef compTypeString = UTCreateStringForOSType(vCompDescs[i].componentType);
86                         CFStringRef compSubTypeString = UTCreateStringForOSType(vCompDescs[i].componentSubType);
87                         CFStringRef compManufacturerString = UTCreateStringForOSType(vCompDescs[i].componentManufacturer);
88
89                         itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"), 
90                                 compTypeString, compManufacturerString, compSubTypeString);
91
92                         if (compTypeString != NULL)
93                                 CFRelease(compTypeString);
94                         if (compSubTypeString != NULL)
95                                 CFRelease(compSubTypeString);
96                         if (compManufacturerString != NULL)
97                                 CFRelease(compManufacturerString);
98                 }
99                 string realname = CFStringRefToStdString(itemName);
100
101                 AUPluginInfoPtr plug(new AUPluginInfo);
102                 plug->name = realname;
103                 plug->type = PluginInfo::AudioUnit;
104                 plug->n_inputs = 0;
105                 plug->n_outputs = 0;
106                 plug->category = "AudioUnit";
107
108                 plugs.push_back(plug);
109         }
110
111         return plugs;
112 }