/*
This file is part of Darling.
Copyright (C) 2020 Lubos Dolezel
Darling is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Darling is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Darling. If not, see .
*/
#include
#include
#include "AudioFileFormatManager.h"
OSStatus AudioFileCreateWithURL (CFURLRef inFileRef,
AudioFileTypeID inFileType,
const AudioStreamBasicDescription *inFormat,
AudioFileFlags inFlags,
AudioFileID _Nullable * _Nonnull outAudioFile)
{
return unimpErr;
}
OSStatus AudioFileOpenURL ( CFURLRef inFileRef,
AudioFilePermissions inPermissions,
AudioFileTypeID inFileTypeHint,
AudioFileID _Nullable * _Nonnull outAudioFile)
{
return unimpErr;
}
OSStatus AudioFileInitializeWithCallbacks (
void * inClientData,
AudioFile_ReadProc inReadFunc,
AudioFile_WriteProc inWriteFunc,
AudioFile_GetSizeProc inGetSizeFunc,
AudioFile_SetSizeProc inSetSizeFunc,
AudioFileTypeID inFileType,
const AudioStreamBasicDescription *inFormat,
AudioFileFlags inFlags,
AudioFileID _Nullable * _Nonnull outAudioFile)
{
return unimpErr;
}
OSStatus AudioFileOpenWithCallbacks (
void * inClientData,
AudioFile_ReadProc inReadFunc,
AudioFile_WriteProc _Nullable inWriteFunc,
AudioFile_GetSizeProc inGetSizeFunc,
AudioFile_SetSizeProc _Nullable inSetSizeFunc,
AudioFileTypeID inFileTypeHint,
AudioFileID _Nullable * _Nonnull outAudioFile)
{
return unimpErr;
}
OSStatus AudioFileClose (AudioFileID inAudioFile)
{
return unimpErr;
}
OSStatus AudioFileOptimize (AudioFileID inAudioFile)
{
return unimpErr;
}
OSStatus AudioFileReadBytes ( AudioFileID inAudioFile,
Boolean inUseCache,
SInt64 inStartingByte,
UInt32 *ioNumBytes,
void *outBuffer)
{
return unimpErr;
}
OSStatus AudioFileWriteBytes ( AudioFileID inAudioFile,
Boolean inUseCache,
SInt64 inStartingByte,
UInt32 *ioNumBytes,
const void *inBuffer)
{
return unimpErr;
}
OSStatus AudioFileReadPacketData ( AudioFileID inAudioFile,
Boolean inUseCache,
UInt32 * ioNumBytes,
AudioStreamPacketDescription * _Nullable outPacketDescriptions,
SInt64 inStartingPacket,
UInt32 * ioNumPackets,
void * _Nullable outBuffer)
{
return unimpErr;
}
OSStatus AudioFileReadPackets ( AudioFileID inAudioFile,
Boolean inUseCache,
UInt32 * outNumBytes,
AudioStreamPacketDescription * _Nullable outPacketDescriptions,
SInt64 inStartingPacket,
UInt32 * ioNumPackets,
void * _Nullable outBuffer)
{
return unimpErr;
}
OSStatus AudioFileWritePackets ( AudioFileID inAudioFile,
Boolean inUseCache,
UInt32 inNumBytes,
const AudioStreamPacketDescription * _Nullable inPacketDescriptions,
SInt64 inStartingPacket,
UInt32 *ioNumPackets,
const void *inBuffer)
{
return unimpErr;
}
OSStatus AudioFileCountUserData ( AudioFileID inAudioFile,
UInt32 inUserDataID,
UInt32 *outNumberItems)
{
return unimpErr;
}
OSStatus AudioFileGetUserDataSize ( AudioFileID inAudioFile,
UInt32 inUserDataID,
UInt32 inIndex,
UInt32 *outUserDataSize)
{
return unimpErr;
}
OSStatus AudioFileGetUserData ( AudioFileID inAudioFile,
UInt32 inUserDataID,
UInt32 inIndex,
UInt32 *ioUserDataSize,
void *outUserData)
{
return unimpErr;
}
OSStatus AudioFileSetUserData ( AudioFileID inAudioFile,
UInt32 inUserDataID,
UInt32 inIndex,
UInt32 inUserDataSize,
const void *inUserData)
{
return unimpErr;
}
OSStatus AudioFileRemoveUserData ( AudioFileID inAudioFile,
UInt32 inUserDataID,
UInt32 inIndex)
{
return unimpErr;
}
OSStatus AudioFileGetPropertyInfo( AudioFileID inAudioFile,
AudioFilePropertyID inPropertyID,
UInt32 * _Nullable outDataSize,
UInt32 * _Nullable isWritable)
{
return unimpErr;
}
OSStatus AudioFileGetProperty( AudioFileID inAudioFile,
AudioFilePropertyID inPropertyID,
UInt32 *ioDataSize,
void *outPropertyData)
{
return unimpErr;
}
OSStatus AudioFileSetProperty( AudioFileID inAudioFile,
AudioFilePropertyID inPropertyID,
UInt32 inDataSize,
const void *inPropertyData)
{
return unimpErr;
}
OSStatus AudioFileGetGlobalInfoSize( AudioFilePropertyID inPropertyID,
UInt32 inSpecifierSize,
void * _Nullable inSpecifier,
UInt32 *outDataSize)
{
return AudioFileGetGlobalInfo(inPropertyID, inSpecifierSize, inSpecifier, outDataSize, nullptr);
}
static void writeUInt32Set(const std::set& set, void *outPropertyData)
{
if (outPropertyData)
{
UInt32* out = static_cast(outPropertyData);
int i = 0;
for (UInt32 v : set)
out[i++] = v;
}
}
template
CFArrayRef stringContainerToArray(const ContainerType& t)
{
std::unique_ptr ptrs(new CFStringRef[t.size()]);
int i = 0;
for (const std::string& str : t)
ptrs[i++] = CFStringCreateWithCString(nullptr, str.c_str(), kCFStringEncodingUTF8);
CFArrayRef rv = CFArrayCreate(nullptr, (const void**) ptrs.get(), t.size(), &kCFTypeArrayCallBacks);
for (int i = 0; i < t.size(); i++)
CFRelease(ptrs[i]);
return rv;
}
OSStatus AudioFileGetGlobalInfo( AudioFilePropertyID inPropertyID,
UInt32 inSpecifierSize,
void * _Nullable inSpecifier,
UInt32 *ioDataSize,
void *outPropertyData)
{
switch (inPropertyID)
{
case kAudioFileGlobalInfo_ReadableTypes:
case kAudioFileGlobalInfo_WritableTypes:
{
std::set types = AudioFileFormatManager::instance()->types(inPropertyID == kAudioFileGlobalInfo_WritableTypes);
*ioDataSize = types.size() * sizeof(UInt32);
writeUInt32Set(types, outPropertyData);
return noErr;
}
case kAudioFileGlobalInfo_FileTypeName:
{
const UInt32* fileType = static_cast(inSpecifier);
if (inSpecifierSize != sizeof(*fileType))
return kAudioFileBadPropertySizeError;
const AudioFileFormatManager::ComponentInfo* ci;
ci = AudioFileFormatManager::instance()->fileType(*fileType);
if (!ci)
return kAudioFileUnsupportedFileTypeError;
CFStringRef* out = static_cast(outPropertyData);
*ioDataSize = sizeof(*out);
if (out)
*out = CFStringCreateWithCString(nullptr, ci->name.c_str(), kCFStringEncodingUTF8);
return noErr;
}
case kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat:
{
const AudioFileTypeAndFormatID* spec = static_cast(inSpecifier);
if (inSpecifierSize != sizeof(*spec))
return kAudioFileBadPropertySizeError;
break;
}
case kAudioFileGlobalInfo_AvailableFormatIDs:
{
const UInt32* fileType = static_cast(inSpecifier);
if (inSpecifierSize != sizeof(*fileType))
return kAudioFileBadPropertySizeError;
auto set = AudioFileFormatManager::instance()->availableFormatIDs(*fileType);
*ioDataSize = set.size() * sizeof(UInt32);
writeUInt32Set(set, outPropertyData);
return noErr;
}
case kAudioFileGlobalInfo_AllHFSTypeCodes:
case kAudioFileGlobalInfo_HFSTypeCodesForType:
case kAudioFileGlobalInfo_TypesForHFSTypeCode:
*ioDataSize = 0;
return noErr;
case kAudioFileGlobalInfo_AllExtensions:
case kAudioFileGlobalInfo_AllUTIs:
case kAudioFileGlobalInfo_AllMIMETypes:
{
*ioDataSize = sizeof(CFArrayRef);
if (outPropertyData)
{
std::set set;
AudioFileFormatManager* mgr = AudioFileFormatManager::instance();
if (inPropertyID == kAudioFileGlobalInfo_AllExtensions)
set = mgr->allExtensions();
else if (inPropertyID == kAudioFileGlobalInfo_AllUTIs)
set = mgr->allUTIs();
else if (inPropertyID == kAudioFileGlobalInfo_AllMIMETypes)
set = mgr->allMIMEs();
*((CFArrayRef*)outPropertyData) = stringContainerToArray(set);
}
return noErr;
}
case kAudioFileGlobalInfo_ExtensionsForType:
case kAudioFileGlobalInfo_UTIsForType:
case kAudioFileGlobalInfo_MIMETypesForType:
{
const UInt32* fileType = static_cast(inSpecifier);
if (inSpecifierSize != sizeof(*fileType))
return kAudioFileBadPropertySizeError;
*ioDataSize = sizeof(CFArrayRef);
if (outPropertyData)
{
const std::vector* vector;
const AudioFileFormatManager::ComponentInfo* ci;
ci = AudioFileFormatManager::instance()->fileType(*fileType);
if (!ci)
return kAudioFileUnsupportedFileTypeError;
if (inPropertyID == kAudioFileGlobalInfo_ExtensionsForType)
vector = &ci->extensions;
else if (inPropertyID == kAudioFileGlobalInfo_UTIsForType)
vector = &ci->utis;
else if (inPropertyID == kAudioFileGlobalInfo_MIMETypesForType)
vector = &ci->mimeTypes;
*((CFArrayRef*)outPropertyData) = stringContainerToArray(*vector);
}
return noErr;
}
case kAudioFileGlobalInfo_TypesForMIMEType:
case kAudioFileGlobalInfo_TypesForUTI:
case kAudioFileGlobalInfo_TypesForExtension:
{
CFStringRef str = static_cast(inSpecifier);
if (inSpecifierSize != sizeof(str))
return kAudioFileBadPropertySizeError;
AudioFileFormatManager* mgr = AudioFileFormatManager::instance();
const char* cstr = CFStringGetCStringPtr(str, kCFStringEncodingUTF8);
std::set set;
if (inPropertyID == kAudioFileGlobalInfo_TypesForMIMEType)
set = mgr->typesForMIME(cstr);
else if (inPropertyID == kAudioFileGlobalInfo_TypesForUTI)
set = mgr->typesForUTI(cstr);
else if (inPropertyID == kAudioFileGlobalInfo_TypesForExtension)
set = mgr->typesForExtension(cstr);
*ioDataSize = set.size() * sizeof(UInt32);
writeUInt32Set(set, outPropertyData);
return noErr;
}
}
return unimpErr;
}
OSStatus AudioFileCreate ( const struct FSRef *inParentRef,
CFStringRef inFileName,
AudioFileTypeID inFileType,
const AudioStreamBasicDescription *inFormat,
AudioFileFlags inFlags,
struct FSRef *outNewFileRef,
AudioFileID _Nullable * _Nonnull outAudioFile)
{
return unimpErr;
}
OSStatus AudioFileInitialize ( const struct FSRef *inFileRef,
AudioFileTypeID inFileType,
const AudioStreamBasicDescription *inFormat,
AudioFileFlags inFlags,
AudioFileID _Nullable * _Nonnull outAudioFile)
{
return unimpErr;
}
OSStatus AudioFileOpen ( const struct FSRef *inFileRef,
AudioFilePermissions inPermissions,
AudioFileTypeID inFileTypeHint,
AudioFileID _Nullable * _Nonnull outAudioFile)
{
return unimpErr;
}