Implement custom reader support in CoreAudio decoder, now supports archives and possibly streams

CQTexperiment
Christopher Snowhill 2020-03-08 20:05:03 -07:00
parent 117ab53343
commit 25a030a46c
2 changed files with 71 additions and 6 deletions

View File

@ -27,6 +27,9 @@
@interface CoreAudioDecoder : NSObject <CogDecoder> @interface CoreAudioDecoder : NSObject <CogDecoder>
{ {
@public long _lastPosition;
id<CogSource> _audioSource;
AudioFileID _audioFile;
ExtAudioFileRef _in; ExtAudioFileRef _in;
int bitrate; int bitrate;

View File

@ -28,6 +28,54 @@
- (BOOL) readInfoFromExtAudioFileRef; - (BOOL) readInfoFromExtAudioFileRef;
@end @end
static OSStatus readProc(void* clientData,
SInt64 position,
UInt32 requestCount,
void* buffer,
UInt32* actualCount)
{
NSObject* _handle = (__bridge NSObject *)(clientData);
CoreAudioDecoder * __unsafe_unretained pSelf = (id) _handle;
id<CogSource> source = pSelf->_audioSource;
if (position != pSelf->_lastPosition) {
if ([source seekable])
[source seek:position whence:SEEK_SET];
else
return seekErr;
}
size_t bytesRead = [source read:buffer amount:requestCount];
pSelf->_lastPosition = position + bytesRead;
if(actualCount)
*actualCount = (UInt32) bytesRead;
return noErr;
}
static SInt64 getSizeProc(void* clientData) {
NSObject* _handle = (__bridge NSObject *)(clientData);
CoreAudioDecoder * __unsafe_unretained pSelf = (id) _handle;
id<CogSource> source = pSelf->_audioSource;
SInt64 size;
if ([source seekable]) {
[source seek:0 whence:SEEK_END];
size = [source tell];
[source seek:pSelf->_lastPosition whence:SEEK_SET];
}
else {
size = INT64_MAX;
}
return size;
}
@implementation CoreAudioDecoder @implementation CoreAudioDecoder
- (void) close - (void) close
@ -38,6 +86,13 @@
if(noErr != err) { if(noErr != err) {
DLog(@"Error closing ExtAudioFile"); DLog(@"Error closing ExtAudioFile");
} }
err = AudioFileClose(_audioFile);
if(noErr != err) {
DLog(@"Error closing AudioFile");
}
_audioSource = nil;
} }
- (void) dealloc - (void) dealloc
@ -48,10 +103,17 @@
- (BOOL)open:(id<CogSource>)source; - (BOOL)open:(id<CogSource>)source;
{ {
OSStatus err; OSStatus err;
NSURL *url = [source url]; _audioSource = source;
_lastPosition = [source tell];
err = ExtAudioFileOpenURL((__bridge CFURLRef)url, &_in);
err = AudioFileOpenWithCallbacks((__bridge void *)self, readProc, 0, getSizeProc, 0, 0, &_audioFile);
if(noErr != err) {
ALog(@"Error opening callback interface to file: %d", err);
return NO;
}
err = ExtAudioFileWrapAudioFileID(_audioFile, false, &_in);
if(noErr != err) { if(noErr != err) {
ALog(@"Error opening file: %d", err); ALog(@"Error opening file: %d", err);
return NO; return NO;
@ -187,7 +249,7 @@
+ (float)priority + (float)priority
{ {
return 0.5; return 1.0;
} }
- (NSDictionary *)properties - (NSDictionary *)properties
@ -199,7 +261,7 @@
[NSNumber numberWithInt:bitrate],@"bitrate", [NSNumber numberWithInt:bitrate],@"bitrate",
[NSNumber numberWithFloat:frequency],@"sampleRate", [NSNumber numberWithFloat:frequency],@"sampleRate",
[NSNumber numberWithLong:totalFrames],@"totalFrames", [NSNumber numberWithLong:totalFrames],@"totalFrames",
[NSNumber numberWithBool:YES], @"seekable", [NSNumber numberWithBool:[_audioSource seekable]], @"seekable",
floatingPoint ? @"host" : @"big", @"endian", floatingPoint ? @"host" : @"big", @"endian",
nil]; nil];
} }