this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

CoreAudio: Allow accessing Carbon components via new AudioToolbox APIs

+301 -30
+190 -24
src/CoreAudio/AudioToolbox/AudioComponent.mm
··· 18 18 */ 19 19 20 20 #include <AudioToolbox/AudioComponent.h> 21 + #include <CoreServices/Components.h> 22 + #include <CoreServices/Resources.h> 23 + #include <CoreServices/MacErrors.h> 24 + #include <CoreServices/MacMemory.h> 21 25 #include "AudioComponentManager.h" 22 26 #include <iostream> 23 27 ··· 34 38 AudioComponent AudioComponentFindNext(AudioComponent inComponent, const AudioComponentDescription* desc) 35 39 { 36 40 auto matching = AudioComponentManager::instance()->findMatching(desc); 37 - if (matching.empty()) 38 - return nullptr; 39 - 40 - if (!inComponent) 41 - return matching[0]; 42 - 43 - for (size_t i = 0; i < matching.size()-1; i++) 41 + if (!matching.empty()) 44 42 { 45 - if (matching[i] == inComponent) 43 + if (!inComponent) 44 + return matching[0]; 45 + 46 + for (size_t i = 0; i < matching.size()-1; i++) 46 47 { 47 - return matching[i+1]; 48 + if (matching[i] == inComponent) 49 + { 50 + return matching[i+1]; 51 + } 48 52 } 49 53 } 50 54 51 - return nullptr; 55 + return (AudioComponent) ::FindNextComponent(Component(inComponent), (ComponentDescription*) desc); 52 56 } 53 57 54 58 UInt32 AudioComponentCount(const AudioComponentDescription* desc) 55 59 { 56 - return AudioComponentManager::instance()->findMatching(desc).size(); 60 + const UInt32 carbonComponents = ::CountComponents((ComponentDescription*) desc); 61 + UInt32 numDuplicates = 0; 62 + Component carbonComponent = nullptr; 63 + 64 + while ((carbonComponent = ::FindNextComponent(carbonComponent, (ComponentDescription*) desc)) != nullptr) 65 + { 66 + ComponentDescription cd; 67 + 68 + ::GetComponentInfo(carbonComponent, &cd, nullptr, nullptr, nullptr); 69 + 70 + if (::AudioComponentFindNext(nullptr, (AudioComponentDescription*) &cd) != nullptr) 71 + numDuplicates++; 72 + } 73 + 74 + return AudioComponentManager::instance()->findMatching(desc).size() + carbonComponents - numDuplicates; 57 75 } 58 76 59 77 OSStatus AudioComponentCopyName(AudioComponent component, CFStringRef* outName) 60 78 { 61 - const char* name; 62 - OSStatus status = AudioComponentManager::instance()->getName(component, &name); 79 + if (AudioComponentManager::isOurInstance(component)) 80 + { 81 + const char* name; 82 + OSStatus status = AudioComponentManager::instance()->getName(component, &name); 83 + 84 + if (status == noErr) 85 + *outName = CFStringCreateWithCString(nullptr, name, kCFStringEncodingUTF8); 86 + else 87 + *outName = nullptr; 63 88 64 - if (status == noErr) 65 - *outName = CFStringCreateWithCString(nullptr, name, kCFStringEncodingUTF8); 89 + return status; 90 + } 66 91 else 67 - *outName = nullptr; 92 + { 93 + Handle handle = ::NewEmptyHandle(); 94 + OSStatus status = ::GetComponentInfo(Component(component), nullptr, handle, nullptr, nullptr); 68 95 69 - return status; 96 + if (status != noErr) 97 + { 98 + ::DisposeHandle(handle); 99 + *outName = nullptr; 100 + return status; 101 + } 102 + else 103 + { 104 + *outName = ::CFStringCreateWithPascalString(nullptr, ConstStr255Param(*handle), kCFStringEncodingMacRoman); 105 + ::DisposeHandle(handle); 106 + return noErr; 107 + } 108 + } 70 109 } 71 110 72 111 OSStatus AudioComponentGetDescription(AudioComponent component, AudioComponentDescription* outDesc) 73 112 { 74 - return AudioComponentManager::instance()->getDescription(component, outDesc); 113 + if (AudioComponentManager::isOurInstance(component)) 114 + { 115 + return AudioComponentManager::instance()->getDescription(component, outDesc); 116 + } 117 + else 118 + { 119 + return ::GetComponentInfo(Component(component), (ComponentDescription*) outDesc, nullptr, nullptr, nullptr); 120 + } 75 121 } 76 122 123 + #pragma pack(push, 1) 124 + struct PlatformInfo 125 + { 126 + uint32_t ComponentFlags; 127 + uint32_t CodeType; 128 + uint16_t CodeId; 129 + uint16_t PlatformType; 130 + }; 131 + 132 + struct CarbonThng 133 + { 134 + uint32_t Type; 135 + uint32_t Subtype; 136 + uint32_t Manufacturer; 137 + uint32_t ComponentFlags; 138 + uint32_t ComponentFlagsMask; 139 + uint32_t CodeType; 140 + uint16_t CodeId; 141 + uint32_t NameType; 142 + uint16_t NameId; 143 + uint32_t InfoType; 144 + uint16_t InfoId; 145 + uint32_t IconType; 146 + uint16_t IconId; 147 + uint32_t ComponentVersion; 148 + uint32_t RegistrationFlags; 149 + uint16_t IconFamilyId; 150 + 151 + uint32_t PlatformInfoCount; 152 + PlatformInfo PlatformInfos[]; 153 + }; 154 + #pragma pack(pop) 155 + #ifdef __LITTLE_ENDIAN__ 156 + # define SWAP(x) x = _bswap(x) 157 + 158 + static inline uint16_t _bswap(uint16_t v) { return __builtin_bswap16(v); } 159 + static inline int16_t _bswap(int16_t v) { return __builtin_bswap16(v); } 160 + static inline uint32_t _bswap(uint32_t v) { return __builtin_bswap32(v); } 161 + 162 + #else 163 + # define SWAP(x) 164 + #endif 165 + 77 166 OSStatus AudioComponentGetVersion(AudioComponent component, UInt32* outVersion) 78 167 { 79 - return AudioComponentManager::instance()->getVersion(component, (uint32_t*) outVersion); 168 + if (AudioComponentManager::isOurInstance(component)) 169 + { 170 + return AudioComponentManager::instance()->getVersion(component, (uint32_t*) outVersion); 171 + } 172 + else 173 + { 174 + ResFileRefNum resFile, oldFile; 175 + AudioComponentDescription desc; 176 + OSStatus status; 177 + 178 + status = ::AudioComponentGetDescription(component, &desc); 179 + if (status != noErr) 180 + return status; 181 + 182 + status = ::OpenAComponentResFile(Component(component), &resFile); 183 + if (status != noErr) 184 + return status; 185 + 186 + oldFile = ::CurResFile(); 187 + ::UseResFile(resFile); 188 + 189 + const ResourceCount count = ::Count1Resources('thng'); 190 + bool found = false; 191 + 192 + for (int i = 1; i <= count; i++) 193 + { 194 + Handle handle = ::Get1IndResource('thng', i); 195 + if (handle && ::GetHandleSize(handle) >= sizeof(CarbonThng)) 196 + { 197 + CarbonThng thng = *((CarbonThng*) *handle); 198 + 199 + SWAP(thng.Type); 200 + SWAP(thng.Subtype); 201 + SWAP(thng.Manufacturer); 202 + 203 + if (thng.Type == desc.componentType && thng.Subtype == desc.componentSubType && thng.Manufacturer == desc.componentManufacturer) 204 + { 205 + SWAP(thng.ComponentVersion); 206 + *outVersion = thng.ComponentVersion; 207 + found = true; 208 + break; 209 + } 210 + } 211 + } 212 + 213 + ::UseResFile(oldFile); 214 + ::CloseComponentResFile(resFile); 215 + 216 + return found ? noErr : invalidComponentID; 217 + } 80 218 } 81 219 82 220 #if !TARGET_OS_IPHONE ··· 97 235 98 236 OSStatus AudioComponentInstanceNew(AudioComponent component, AudioComponentInstance* outInstance) 99 237 { 100 - return AudioComponentManager::instance()->instantiate(component, outInstance); 238 + if (AudioComponentManager::isOurInstance(component)) 239 + { 240 + return AudioComponentManager::instance()->instantiate(component, outInstance); 241 + } 242 + else 243 + { 244 + return ::OpenAComponent(Component(component), (ComponentInstance*) outInstance); 245 + } 101 246 } 102 247 103 248 void AudioComponentInstantiate(AudioComponent component, AudioComponentInstantiationOptions opts, void(^handler)(AudioComponentInstance, OSStatus)) ··· 107 252 108 253 OSStatus AudioComponentInstanceDispose(AudioComponentInstance inst) 109 254 { 110 - return AudioComponentManager::instance()->dispose(inst); 255 + if (AudioComponentManager::isOurInstance(inst)) 256 + { 257 + return AudioComponentManager::instance()->dispose(inst); 258 + } 259 + else 260 + { 261 + return ::CloseComponent(inst); 262 + } 111 263 } 112 264 113 265 AudioComponent AudioComponentInstanceGetComponent(AudioComponentInstance inst) 114 266 { 115 - return AudioComponentManager::instance()->getComponent(inst); 267 + if (AudioComponentManager::isOurInstance(inst)) 268 + { 269 + return AudioComponentManager::instance()->getComponent(inst); 270 + } 271 + else 272 + { 273 + return (AudioComponent) ::GetComponentIDFromComponentInstance(inst); 274 + } 116 275 } 117 276 118 277 Boolean AudioComponentInstanceCanDo(AudioComponentInstance inst, SInt16 sel) 119 278 { 120 - AudioComponentPlugInInterface* iface = AudioComponentManager::instance()->instanceInterface(inst); 121 - return iface->Lookup(sel) != nullptr; 279 + if (AudioComponentManager::isOurInstance(inst)) 280 + { 281 + AudioComponentPlugInInterface* iface = AudioComponentManager::instance()->instanceInterface(inst); 282 + return iface->Lookup(sel) != nullptr; 283 + } 284 + else 285 + { 286 + return ::CallComponentCanDo(inst, sel); 287 + } 122 288 } 123 289 124 290 OSStatus AudioComponentCopyConfigurationInfo(AudioComponent component, CFDictionaryRef* outInfo)
+2 -1
src/CoreAudio/AudioToolbox/AudioComponentManager.h
··· 59 59 // Returns true if it looks like an instance managed by this class. 60 60 // False means it is probably managed by the Carbon Component Manager. 61 61 static bool isOurInstance(AudioComponentInstance instance); 62 + static bool isOurInstance(AudioComponent component); 62 63 63 64 AudioComponent registerComponent(const AudioComponentDescription* desc, const char* name, 64 65 uint32_t version, AudioComponentFactoryFunction factory); ··· 80 81 private: 81 82 82 83 std::unordered_map<AudioComponent, RegisteredComponent> m_components; 83 - uint32_t m_nextComponentId = 0x4000; 84 + uint32_t m_nextComponentId = 0x4000 | 0x80000000; 84 85 std::recursive_mutex m_componentsMutex; 85 86 86 87 struct ComponentInstanceData
+5
src/CoreAudio/AudioToolbox/AudioComponentManager.mm
··· 164 164 return v & 0x80000000; 165 165 } 166 166 167 + bool AudioComponentManager::isOurInstance(AudioComponent component) 168 + { 169 + return isOurInstance(AudioComponentInstance(component)); 170 + } 171 + 167 172 /* 168 173 AudioComponentInstance AudioComponentManager::audioUnitToInstance(AudioUnit unit) 169 174 {
+1 -1
src/CoreAudio/AudioToolbox/AudioConverterImpl.h
··· 10 10 #include <libavcodec/avcodec.h> 11 11 } 12 12 13 - class AudioConverter 13 + class __attribute__((visibility("hidden"))) AudioConverter 14 14 { 15 15 AudioConverter(const AudioStreamBasicDescription* inSourceFormat, const AudioStreamBasicDescription* inDestinationFormat); 16 16 public:
+22
src/frameworks/CoreServices/ComponentManager.cpp
··· 640 640 641 641 return noErr; 642 642 } 643 + 644 + uint32_t ComponentManager::componentInstances(Component c) 645 + { 646 + std::unique_lock<std::recursive_mutex> l(m_componentsMutex); 647 + 648 + auto itMap = m_componentsMap.find(c); 649 + if (itMap == m_componentsMap.end()) 650 + return 0; 651 + 652 + ComponentData* cd = itMap->second; 653 + return cd->instances; 654 + } 655 + 656 + Component ComponentManager::componentID(ComponentInstance ci) 657 + { 658 + std::unique_lock<std::recursive_mutex> l(m_componentInstancesMutex); 659 + 660 + auto it = m_componentInstances.find(ci); 661 + if (it == m_componentInstances.end()) 662 + return nullptr; 663 + return it->second.component; 664 + }
+3
src/frameworks/CoreServices/ComponentManager.h
··· 74 74 static CFBundleRef bundleFromPath(const char* path); 75 75 OSStatus resFileForComponent(Component c, ResFileRefNum* resFile); 76 76 77 + uint32_t componentInstances(Component c); 78 + Component componentID(ComponentInstance ci); 79 + 77 80 struct ComponentData 78 81 { 79 82 Component component;
+69 -4
src/frameworks/CoreServices/Components.cpp
··· 42 42 return nullptr; 43 43 } 44 44 45 + OSErr OpenADefaultComponent(OSType componentType, OSType componentSubType, ComponentInstance *ci) 46 + { 47 + ComponentDescription desc = { 48 + .componentFlags = 0, 49 + .componentFlagsMask = 0, 50 + .componentManufacturer = 0, 51 + .componentType = componentType, 52 + .componentSubType = componentSubType, 53 + }; 54 + Component c = FindNextComponent(nullptr, &desc); 55 + 56 + if (!c) 57 + { 58 + *ci = nullptr; 59 + return invalidComponentID; 60 + } 61 + 62 + return OpenAComponent(c, ci); 63 + } 64 + 65 + long CountComponentInstances(Component aComponent) 66 + { 67 + return ComponentManager::instance()->componentInstances(aComponent); 68 + } 69 + 45 70 long CountComponents(ComponentDescription* desc) 46 71 { 47 72 return ComponentManager::instance()->findMatching(desc).size(); ··· 117 142 if (status != noErr) 118 143 return status; 119 144 120 - *cd = cmd.cd; 121 - stringToHandle(cmd.name, componentName); 122 - stringToHandle(cmd.info, componentInfo); 123 - EmptyHandle(componentIcon); 145 + if (cd) 146 + *cd = cmd.cd; 147 + if (componentName) 148 + stringToHandle(cmd.name, componentName); 149 + if (componentInfo) 150 + stringToHandle(cmd.info, componentInfo); 151 + 152 + if (componentIcon) 153 + EmptyHandle(componentIcon); 124 154 125 155 return noErr; 126 156 } 157 + 158 + ComponentResult CallComponentCanDo(ComponentInstance ci, SInt16 ftnNumber) 159 + { 160 + ComponentParameters* params = (ComponentParameters*) alloca(sizeof(ComponentParameters) + sizeof(long)); 161 + 162 + params->flags = 0; 163 + params->what = kComponentCanDoSelect; 164 + params->paramSize = sizeof(long) * 2; 165 + 166 + #if __LP64__ 167 + params->params[0] = long(ci); 168 + params->params[1] = ftnNumber; 169 + #else 170 + 171 + params->params[1] = long(ci); 172 + #ifdef __ppc__ 173 + params->params[0] = long(ftnNumber) << 16; 174 + #else 175 + params->params[0] = ftnNumber; 176 + #endif 177 + 178 + #endif 179 + return ComponentManager::instance()->dispatch(params); 180 + } 181 + 182 + OSErr CloseComponentResFile(ResFileRefNum refnum) 183 + { 184 + CloseResFile(refnum); 185 + return ResError(); 186 + } 187 + 188 + Component GetComponentIDFromComponentInstance(ComponentInstance inst) 189 + { 190 + return ComponentManager::instance()->componentID(inst); 191 + }
+9
src/frameworks/CoreServices/include/CoreServices/Components.h
··· 153 153 OSErr OpenAComponentResFile(Component aComponent, ResFileRefNum* resRef); 154 154 OSErr GetComponentInfo(Component aComponent, ComponentDescription *cd, Handle componentName, Handle componentInfo, Handle componentIcon); 155 155 156 + ComponentResult CallComponentCanDo(ComponentInstance ci, SInt16 ftnNumber); 157 + OSErr OpenADefaultComponent(OSType componentType, OSType componentSubType, ComponentInstance *ci); 158 + 159 + long CountComponentInstances(Component aComponent); 160 + OSErr CloseComponentResFile(ResFileRefNum refnum); 161 + 162 + // Apple private API 163 + Component GetComponentIDFromComponentInstance(ComponentInstance inst); 164 + 156 165 #ifdef __cplusplus 157 166 } 158 167 #endif