this repo has no description
1/*
2This file is part of Darling.
3
4Copyright (C) 2020 Lubos Dolezel
5
6Darling is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11Darling is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with Darling. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include <AudioToolbox/AudioFile.h>
21#include <CarbonCore/MacErrors.h>
22#include "AudioFileFormatManager.h"
23
24OSStatus AudioFileCreateWithURL (CFURLRef inFileRef,
25 AudioFileTypeID inFileType,
26 const AudioStreamBasicDescription *inFormat,
27 AudioFileFlags inFlags,
28 AudioFileID _Nullable * _Nonnull outAudioFile)
29{
30 return unimpErr;
31}
32
33OSStatus AudioFileOpenURL ( CFURLRef inFileRef,
34 AudioFilePermissions inPermissions,
35 AudioFileTypeID inFileTypeHint,
36 AudioFileID _Nullable * _Nonnull outAudioFile)
37{
38 return unimpErr;
39}
40
41OSStatus AudioFileInitializeWithCallbacks (
42 void * inClientData,
43 AudioFile_ReadProc inReadFunc,
44 AudioFile_WriteProc inWriteFunc,
45 AudioFile_GetSizeProc inGetSizeFunc,
46 AudioFile_SetSizeProc inSetSizeFunc,
47 AudioFileTypeID inFileType,
48 const AudioStreamBasicDescription *inFormat,
49 AudioFileFlags inFlags,
50 AudioFileID _Nullable * _Nonnull outAudioFile)
51{
52 return unimpErr;
53}
54
55OSStatus AudioFileOpenWithCallbacks (
56 void * inClientData,
57 AudioFile_ReadProc inReadFunc,
58 AudioFile_WriteProc _Nullable inWriteFunc,
59 AudioFile_GetSizeProc inGetSizeFunc,
60 AudioFile_SetSizeProc _Nullable inSetSizeFunc,
61 AudioFileTypeID inFileTypeHint,
62 AudioFileID _Nullable * _Nonnull outAudioFile)
63{
64 return unimpErr;
65}
66
67OSStatus AudioFileClose (AudioFileID inAudioFile)
68{
69 return unimpErr;
70}
71
72OSStatus AudioFileOptimize (AudioFileID inAudioFile)
73{
74 return unimpErr;
75}
76
77OSStatus AudioFileReadBytes ( AudioFileID inAudioFile,
78 Boolean inUseCache,
79 SInt64 inStartingByte,
80 UInt32 *ioNumBytes,
81 void *outBuffer)
82{
83 return unimpErr;
84}
85
86OSStatus AudioFileWriteBytes ( AudioFileID inAudioFile,
87 Boolean inUseCache,
88 SInt64 inStartingByte,
89 UInt32 *ioNumBytes,
90 const void *inBuffer)
91{
92 return unimpErr;
93}
94
95OSStatus AudioFileReadPacketData ( AudioFileID inAudioFile,
96 Boolean inUseCache,
97 UInt32 * ioNumBytes,
98 AudioStreamPacketDescription * _Nullable outPacketDescriptions,
99 SInt64 inStartingPacket,
100 UInt32 * ioNumPackets,
101 void * _Nullable outBuffer)
102{
103 return unimpErr;
104}
105
106OSStatus AudioFileReadPackets ( AudioFileID inAudioFile,
107 Boolean inUseCache,
108 UInt32 * outNumBytes,
109 AudioStreamPacketDescription * _Nullable outPacketDescriptions,
110 SInt64 inStartingPacket,
111 UInt32 * ioNumPackets,
112 void * _Nullable outBuffer)
113{
114 return unimpErr;
115}
116
117OSStatus AudioFileWritePackets ( AudioFileID inAudioFile,
118 Boolean inUseCache,
119 UInt32 inNumBytes,
120 const AudioStreamPacketDescription * _Nullable inPacketDescriptions,
121 SInt64 inStartingPacket,
122 UInt32 *ioNumPackets,
123 const void *inBuffer)
124{
125 return unimpErr;
126}
127
128OSStatus AudioFileCountUserData ( AudioFileID inAudioFile,
129 UInt32 inUserDataID,
130 UInt32 *outNumberItems)
131{
132 return unimpErr;
133}
134
135OSStatus AudioFileGetUserDataSize ( AudioFileID inAudioFile,
136 UInt32 inUserDataID,
137 UInt32 inIndex,
138 UInt32 *outUserDataSize)
139{
140 return unimpErr;
141}
142
143OSStatus AudioFileGetUserData ( AudioFileID inAudioFile,
144 UInt32 inUserDataID,
145 UInt32 inIndex,
146 UInt32 *ioUserDataSize,
147 void *outUserData)
148{
149 return unimpErr;
150}
151
152OSStatus AudioFileSetUserData ( AudioFileID inAudioFile,
153 UInt32 inUserDataID,
154 UInt32 inIndex,
155 UInt32 inUserDataSize,
156 const void *inUserData)
157{
158 return unimpErr;
159}
160
161OSStatus AudioFileRemoveUserData ( AudioFileID inAudioFile,
162 UInt32 inUserDataID,
163 UInt32 inIndex)
164{
165 return unimpErr;
166}
167
168OSStatus AudioFileGetPropertyInfo( AudioFileID inAudioFile,
169 AudioFilePropertyID inPropertyID,
170 UInt32 * _Nullable outDataSize,
171 UInt32 * _Nullable isWritable)
172{
173 return unimpErr;
174}
175
176OSStatus AudioFileGetProperty( AudioFileID inAudioFile,
177 AudioFilePropertyID inPropertyID,
178 UInt32 *ioDataSize,
179 void *outPropertyData)
180{
181 return unimpErr;
182}
183
184OSStatus AudioFileSetProperty( AudioFileID inAudioFile,
185 AudioFilePropertyID inPropertyID,
186 UInt32 inDataSize,
187 const void *inPropertyData)
188{
189 return unimpErr;
190}
191
192OSStatus AudioFileGetGlobalInfoSize( AudioFilePropertyID inPropertyID,
193 UInt32 inSpecifierSize,
194 void * _Nullable inSpecifier,
195 UInt32 *outDataSize)
196{
197 return AudioFileGetGlobalInfo(inPropertyID, inSpecifierSize, inSpecifier, outDataSize, nullptr);
198}
199
200static 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
211template <typename ContainerType>
212CFArrayRef 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;
225}
226
227OSStatus AudioFileGetGlobalInfo( AudioFilePropertyID inPropertyID,
228 UInt32 inSpecifierSize,
229 void * _Nullable inSpecifier,
230 UInt32 *ioDataSize,
231 void *outPropertyData)
232{
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 }
369 return unimpErr;
370}
371
372OSStatus AudioFileCreate ( const struct FSRef *inParentRef,
373 CFStringRef inFileName,
374 AudioFileTypeID inFileType,
375 const AudioStreamBasicDescription *inFormat,
376 AudioFileFlags inFlags,
377 struct FSRef *outNewFileRef,
378 AudioFileID _Nullable * _Nonnull outAudioFile)
379{
380 return unimpErr;
381}
382
383OSStatus AudioFileInitialize ( const struct FSRef *inFileRef,
384 AudioFileTypeID inFileType,
385 const AudioStreamBasicDescription *inFormat,
386 AudioFileFlags inFlags,
387 AudioFileID _Nullable * _Nonnull outAudioFile)
388{
389 return unimpErr;
390}
391
392OSStatus AudioFileOpen ( const struct FSRef *inFileRef,
393 AudioFilePermissions inPermissions,
394 AudioFileTypeID inFileTypeHint,
395 AudioFileID _Nullable * _Nonnull outAudioFile)
396{
397 return unimpErr;
398}
399
400
401