Attempt to add rewinding to CoreAudio for streamed source files, but it doesn't work, it still fails to play anything from a stream
parent
18acc7fdd2
commit
b37a6f0f0d
|
@ -32,6 +32,9 @@
|
||||||
AudioFileID _audioFile;
|
AudioFileID _audioFile;
|
||||||
ExtAudioFileRef _in;
|
ExtAudioFileRef _in;
|
||||||
|
|
||||||
|
long rewindStart;
|
||||||
|
NSMutableData * rewindBuffer;
|
||||||
|
|
||||||
int bitrate;
|
int bitrate;
|
||||||
int bitsPerSample;
|
int bitsPerSample;
|
||||||
BOOL floatingPoint;
|
BOOL floatingPoint;
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
|
|
||||||
|
#define REWIND_SIZE 131072
|
||||||
|
|
||||||
@interface CoreAudioDecoder (Private)
|
@interface CoreAudioDecoder (Private)
|
||||||
- (BOOL) readInfoFromExtAudioFileRef;
|
- (BOOL) readInfoFromExtAudioFileRef;
|
||||||
@end
|
@end
|
||||||
|
@ -42,16 +44,49 @@ static OSStatus readProc(void* clientData,
|
||||||
if (position != pSelf->_lastPosition) {
|
if (position != pSelf->_lastPosition) {
|
||||||
if ([source seekable])
|
if ([source seekable])
|
||||||
[source seek:position whence:SEEK_SET];
|
[source seek:position whence:SEEK_SET];
|
||||||
else
|
else if (position < pSelf->rewindStart)
|
||||||
return seekErr;
|
return seekErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bytesRead = [source read:buffer amount:requestCount];
|
size_t copyMax = 0;
|
||||||
|
size_t bytesRead = 0;
|
||||||
|
size_t rewindBytes = 0;
|
||||||
|
|
||||||
|
if (![source seekable]) {
|
||||||
|
long rewindStart = pSelf->rewindStart;
|
||||||
|
rewindBytes = [pSelf->rewindBuffer length];
|
||||||
|
|
||||||
|
if ( position < rewindStart + rewindBytes ) {
|
||||||
|
const uint8_t * rewindBuffer = (const uint8_t *)([pSelf->rewindBuffer bytes]);
|
||||||
|
copyMax = rewindStart + rewindBytes - position;
|
||||||
|
if (copyMax > requestCount)
|
||||||
|
copyMax = requestCount;
|
||||||
|
memcpy(buffer, rewindBuffer + (position - rewindStart), copyMax);
|
||||||
|
requestCount -= copyMax;
|
||||||
|
position += copyMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( requestCount )
|
||||||
|
bytesRead = [source read:(((uint8_t *)buffer) + copyMax) amount:requestCount];
|
||||||
|
|
||||||
|
if (![source seekable]) {
|
||||||
|
size_t copyBytes = bytesRead;
|
||||||
|
if (copyBytes) {
|
||||||
|
ssize_t removeBytes = ((rewindBytes + copyBytes) - REWIND_SIZE);
|
||||||
|
if (removeBytes > 0) {
|
||||||
|
NSRange range = NSMakeRange(0, removeBytes);
|
||||||
|
[pSelf->rewindBuffer replaceBytesInRange:range withBytes:NULL length:0];
|
||||||
|
pSelf->rewindStart += removeBytes;
|
||||||
|
}
|
||||||
|
[pSelf->rewindBuffer appendBytes:buffer length:copyBytes];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pSelf->_lastPosition = position + bytesRead;
|
pSelf->_lastPosition = position + bytesRead;
|
||||||
|
|
||||||
if(actualCount)
|
if(actualCount)
|
||||||
*actualCount = (UInt32) bytesRead;
|
*actualCount = (UInt32) (copyMax + bytesRead);
|
||||||
|
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
@ -107,6 +142,9 @@ static SInt64 getSizeProc(void* clientData) {
|
||||||
_audioSource = source;
|
_audioSource = source;
|
||||||
_lastPosition = [source tell];
|
_lastPosition = [source tell];
|
||||||
|
|
||||||
|
rewindStart = _lastPosition;
|
||||||
|
rewindBuffer = [[NSMutableData alloc] init];
|
||||||
|
|
||||||
err = AudioFileOpenWithCallbacks((__bridge void *)self, readProc, 0, getSizeProc, 0, 0, &_audioFile);
|
err = AudioFileOpenWithCallbacks((__bridge void *)self, readProc, 0, getSizeProc, 0, 0, &_audioFile);
|
||||||
if(noErr != err) {
|
if(noErr != err) {
|
||||||
ALog(@"Error opening callback interface to file: %d", err);
|
ALog(@"Error opening callback interface to file: %d", err);
|
||||||
|
@ -244,9 +282,19 @@ static SInt64 getSizeProc(void* clientData) {
|
||||||
|
|
||||||
+ (NSArray *)mimeTypes
|
+ (NSArray *)mimeTypes
|
||||||
{
|
{
|
||||||
|
OSStatus err;
|
||||||
|
UInt32 size;
|
||||||
|
NSArray *sAudioMIMETypes;
|
||||||
|
|
||||||
|
size = sizeof(sAudioMIMETypes);
|
||||||
|
err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AllMIMETypes, 0, NULL, &size, &sAudioMIMETypes);
|
||||||
|
if(noErr != err) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return sAudioMIMETypes;
|
||||||
|
}
|
||||||
|
|
||||||
+ (float)priority
|
+ (float)priority
|
||||||
{
|
{
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
|
Loading…
Reference in New Issue