Skip to content

Commit 1470b45

Browse files
committed
AudioToolbox: Some work around AudioFileComponents
1 parent de92485 commit 1470b45

File tree

3 files changed

+412
-10
lines changed

3 files changed

+412
-10
lines changed

src/CoreAudio/AudioToolbox/AudioFile.cpp

Lines changed: 165 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ along with Darling. If not, see <http://www.gnu.org/licenses/>.
1919

2020
#include <AudioToolbox/AudioFile.h>
2121
#include <CoreServices/MacErrors.h>
22+
#include "AudioFileFormatManager.h"
2223

2324
OSStatus AudioFileCreateWithURL (CFURLRef inFileRef,
2425
AudioFileTypeID inFileType,
@@ -193,7 +194,34 @@ OSStatus AudioFileGetGlobalInfoSize( AudioFilePropertyID inPropertyID,
193194
void * _Nullable inSpecifier,
194195
UInt32 *outDataSize)
195196
{
196-
return unimpErr;
197+
return AudioFileGetGlobalInfo(inPropertyID, inSpecifierSize, inSpecifier, outDataSize, nullptr);
198+
}
199+
200+
static void writeUInt32Set(const std::set<UInt32>& set, void *outPropertyData)
201+
{
202+
if (outPropertyData)
203+
{
204+
UInt32* out = static_cast<UInt32*>(outPropertyData);
205+
int i = 0;
206+
for (UInt32 v : set)
207+
out[i++] = v;
208+
}
209+
}
210+
211+
template <typename ContainerType>
212+
CFArrayRef stringContainerToArray(const ContainerType& t)
213+
{
214+
std::unique_ptr<CFStringRef[]> ptrs(new CFStringRef[t.size()]);
215+
int i = 0;
216+
217+
for (const std::string& str : t)
218+
ptrs[i++] = CFStringCreateWithCString(nullptr, str.c_str(), kCFStringEncodingUTF8);
219+
220+
CFArrayRef rv = CFArrayCreate(nullptr, (const void**) ptrs.get(), t.size(), &kCFTypeArrayCallBacks);
221+
222+
for (int i = 0; i < t.size(); i++)
223+
CFRelease(ptrs[i]);
224+
return rv;
197225
}
198226

199227
OSStatus AudioFileGetGlobalInfo( AudioFilePropertyID inPropertyID,
@@ -202,6 +230,142 @@ OSStatus AudioFileGetGlobalInfo( AudioFilePropertyID inPropertyID,
202230
UInt32 *ioDataSize,
203231
void *outPropertyData)
204232
{
233+
switch (inPropertyID)
234+
{
235+
case kAudioFileGlobalInfo_ReadableTypes:
236+
case kAudioFileGlobalInfo_WritableTypes:
237+
{
238+
std::set<UInt32> types = AudioFileFormatManager::instance()->types(inPropertyID == kAudioFileGlobalInfo_WritableTypes);
239+
240+
*ioDataSize = types.size() * sizeof(UInt32);
241+
writeUInt32Set(types, outPropertyData);
242+
243+
return noErr;
244+
}
245+
case kAudioFileGlobalInfo_FileTypeName:
246+
{
247+
const UInt32* fileType = static_cast<const UInt32*>(inSpecifier);
248+
if (inSpecifierSize != sizeof(*fileType))
249+
return kAudioFileBadPropertySizeError;
250+
251+
const AudioFileFormatManager::ComponentInfo* ci;
252+
253+
ci = AudioFileFormatManager::instance()->fileType(*fileType);
254+
if (!ci)
255+
return kAudioFileUnsupportedFileTypeError;
256+
257+
CFStringRef* out = static_cast<CFStringRef*>(outPropertyData);
258+
*ioDataSize = sizeof(*out);
259+
260+
if (out)
261+
*out = CFStringCreateWithCString(nullptr, ci->name.c_str(), kCFStringEncodingUTF8);
262+
263+
return noErr;
264+
}
265+
case kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat:
266+
{
267+
const AudioFileTypeAndFormatID* spec = static_cast<const AudioFileTypeAndFormatID*>(inSpecifier);
268+
if (inSpecifierSize != sizeof(*spec))
269+
return kAudioFileBadPropertySizeError;
270+
break;
271+
}
272+
case kAudioFileGlobalInfo_AvailableFormatIDs:
273+
{
274+
const UInt32* fileType = static_cast<const UInt32*>(inSpecifier);
275+
if (inSpecifierSize != sizeof(*fileType))
276+
return kAudioFileBadPropertySizeError;
277+
278+
auto set = AudioFileFormatManager::instance()->availableFormatIDs(*fileType);
279+
*ioDataSize = set.size() * sizeof(UInt32);
280+
281+
writeUInt32Set(set, outPropertyData);
282+
283+
return noErr;
284+
}
285+
case kAudioFileGlobalInfo_AllHFSTypeCodes:
286+
case kAudioFileGlobalInfo_HFSTypeCodesForType:
287+
case kAudioFileGlobalInfo_TypesForHFSTypeCode:
288+
*ioDataSize = 0;
289+
return noErr;
290+
case kAudioFileGlobalInfo_AllExtensions:
291+
case kAudioFileGlobalInfo_AllUTIs:
292+
case kAudioFileGlobalInfo_AllMIMETypes:
293+
{
294+
*ioDataSize = sizeof(CFArrayRef);
295+
296+
if (outPropertyData)
297+
{
298+
std::set<std::string> set;
299+
AudioFileFormatManager* mgr = AudioFileFormatManager::instance();
300+
301+
if (inPropertyID == kAudioFileGlobalInfo_AllExtensions)
302+
set = mgr->allExtensions();
303+
else if (inPropertyID == kAudioFileGlobalInfo_AllUTIs)
304+
set = mgr->allUTIs();
305+
else if (inPropertyID == kAudioFileGlobalInfo_AllMIMETypes)
306+
set = mgr->allMIMEs();
307+
308+
*((CFArrayRef*)outPropertyData) = stringContainerToArray(set);
309+
}
310+
311+
return noErr;
312+
}
313+
case kAudioFileGlobalInfo_ExtensionsForType:
314+
case kAudioFileGlobalInfo_UTIsForType:
315+
case kAudioFileGlobalInfo_MIMETypesForType:
316+
{
317+
const UInt32* fileType = static_cast<const UInt32*>(inSpecifier);
318+
if (inSpecifierSize != sizeof(*fileType))
319+
return kAudioFileBadPropertySizeError;
320+
321+
*ioDataSize = sizeof(CFArrayRef);
322+
323+
if (outPropertyData)
324+
{
325+
const std::vector<std::string>* vector;
326+
const AudioFileFormatManager::ComponentInfo* ci;
327+
328+
ci = AudioFileFormatManager::instance()->fileType(*fileType);
329+
if (!ci)
330+
return kAudioFileUnsupportedFileTypeError;
331+
332+
if (inPropertyID == kAudioFileGlobalInfo_ExtensionsForType)
333+
vector = &ci->extensions;
334+
else if (inPropertyID == kAudioFileGlobalInfo_UTIsForType)
335+
vector = &ci->utis;
336+
else if (inPropertyID == kAudioFileGlobalInfo_MIMETypesForType)
337+
vector = &ci->mimeTypes;
338+
339+
*((CFArrayRef*)outPropertyData) = stringContainerToArray(*vector);
340+
}
341+
342+
return noErr;
343+
}
344+
case kAudioFileGlobalInfo_TypesForMIMEType:
345+
case kAudioFileGlobalInfo_TypesForUTI:
346+
case kAudioFileGlobalInfo_TypesForExtension:
347+
{
348+
CFStringRef str = static_cast<CFStringRef>(inSpecifier);
349+
if (inSpecifierSize != sizeof(str))
350+
return kAudioFileBadPropertySizeError;
351+
352+
AudioFileFormatManager* mgr = AudioFileFormatManager::instance();
353+
const char* cstr = CFStringGetCStringPtr(str, kCFStringEncodingUTF8);
354+
std::set<UInt32> set;
355+
356+
if (inPropertyID == kAudioFileGlobalInfo_TypesForMIMEType)
357+
set = mgr->typesForMIME(cstr);
358+
else if (inPropertyID == kAudioFileGlobalInfo_TypesForUTI)
359+
set = mgr->typesForUTI(cstr);
360+
else if (inPropertyID == kAudioFileGlobalInfo_TypesForExtension)
361+
set = mgr->typesForExtension(cstr);
362+
363+
*ioDataSize = set.size() * sizeof(UInt32);
364+
writeUInt32Set(set, outPropertyData);
365+
366+
return noErr;
367+
}
368+
}
205369
return unimpErr;
206370
}
207371

0 commit comments

Comments
 (0)