Bug Fix: Attempt to make seeking more performant
Seeking should clear the buffers completely now, and will be nearly instant, depending on how fast the input can decode. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
53291b570d
commit
4ed4ea906b
10 changed files with 42 additions and 83 deletions
|
@ -25,7 +25,6 @@
|
|||
BufferChain *bufferChain;
|
||||
OutputNode *output;
|
||||
|
||||
BOOL muted;
|
||||
double volume;
|
||||
double pitch;
|
||||
double tempo;
|
||||
|
@ -77,9 +76,6 @@
|
|||
- (double)volumeUp:(double)amount;
|
||||
- (double)volumeDown:(double)amount;
|
||||
|
||||
- (void)mute;
|
||||
- (void)unmute;
|
||||
|
||||
- (double)amountPlayed;
|
||||
- (double)amountPlayedInterval;
|
||||
|
||||
|
|
|
@ -78,9 +78,6 @@
|
|||
output = [[OutputNode alloc] initWithController:self previous:nil];
|
||||
}
|
||||
[output setup];
|
||||
if(muted) {
|
||||
[output mute];
|
||||
}
|
||||
@synchronized(chainQueue) {
|
||||
for(id anObject in chainQueue) {
|
||||
[anObject setShouldContinue:NO];
|
||||
|
@ -179,10 +176,6 @@
|
|||
[output resume];
|
||||
|
||||
[self setPlaybackStatus:CogStatusPlaying waitUntilDone:YES];
|
||||
|
||||
if(muted) {
|
||||
[self unmute];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)seekToTimeBG:(NSNumber *)time {
|
||||
|
@ -190,7 +183,6 @@
|
|||
}
|
||||
|
||||
- (void)seekToTime:(double)time {
|
||||
[self mute];
|
||||
if(endOfInputReached) {
|
||||
// This is a dirty hack in case the playback has finished with the track
|
||||
// that the user thinks they're seeking into
|
||||
|
@ -225,20 +217,6 @@
|
|||
return volume;
|
||||
}
|
||||
|
||||
- (void)mute {
|
||||
if(!muted) {
|
||||
[output mute];
|
||||
muted = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)unmute {
|
||||
if(muted) {
|
||||
[output unmute];
|
||||
muted = NO;
|
||||
}
|
||||
}
|
||||
|
||||
// This is called by the delegate DURING a requestNextStream request.
|
||||
- (void)setNextStream:(NSURL *)url {
|
||||
[self setNextStream:url withUserInfo:nil withRGInfo:nil];
|
||||
|
|
|
@ -230,7 +230,6 @@
|
|||
AudioPlayer * audioPlayer = controller;
|
||||
OutputNode *outputNode = [audioPlayer output];
|
||||
|
||||
[audioPlayer mute];
|
||||
[inputNode seek:frame];
|
||||
}
|
||||
|
||||
|
|
|
@ -160,30 +160,11 @@ static void *kInputNodeContext = &kInputNodeContext;
|
|||
while([self shouldContinue] == YES && [self endOfStream] == NO) {
|
||||
if(shouldSeek == YES) {
|
||||
BufferChain *bufferChain = controller;
|
||||
AudioPlayer *audioPlayer = [controller controller];
|
||||
[audioPlayer mute];
|
||||
AudioPlayer *audioPlayer = [bufferChain controller];
|
||||
OutputNode *outputNode = [audioPlayer output];
|
||||
[outputNode resetBuffer];
|
||||
|
||||
ConverterNode *converter = [bufferChain converter];
|
||||
DSPRubberbandNode *rubberband = [bufferChain rubberband];
|
||||
DSPFSurroundNode *fsurround = [bufferChain fsurround];
|
||||
DSPEqualizerNode *equalizer = [bufferChain equalizer];
|
||||
DSPHRTFNode *hrtf = [bufferChain hrtf];
|
||||
DSPDownmixNode *downmix = [bufferChain downmix];
|
||||
VisualizationNode *visualization = [bufferChain visualization];
|
||||
DLog(@"SEEKING! Resetting Buffer");
|
||||
|
||||
// This resets the converter's buffer
|
||||
[self resetBuffer];
|
||||
[converter resetBuffer];
|
||||
[converter inputFormatDidChange:[bufferChain inputFormat] inputConfig:[bufferChain inputConfig]];
|
||||
[rubberband resetBuffer];
|
||||
[fsurround resetBuffer];
|
||||
[equalizer resetBuffer];
|
||||
[hrtf resetBuffer];
|
||||
[downmix resetBuffer];
|
||||
[visualization resetBuffer];
|
||||
[outputNode resetBackwards];
|
||||
|
||||
DLog(@"Reset buffer!");
|
||||
|
||||
|
@ -199,8 +180,6 @@ static void *kInputNodeContext = &kInputNodeContext;
|
|||
if(seekError) {
|
||||
[controller setError:YES];
|
||||
}
|
||||
|
||||
[audioPlayer unmute];
|
||||
}
|
||||
|
||||
AudioChunk *chunk;
|
||||
|
@ -214,6 +193,11 @@ static void *kInputNodeContext = &kInputNodeContext;
|
|||
chunk = nil;
|
||||
}
|
||||
} else {
|
||||
if(chunk) {
|
||||
@autoreleasepool {
|
||||
chunk = nil;
|
||||
}
|
||||
}
|
||||
DLog(@"End of stream? %@", [self properties]);
|
||||
|
||||
endOfStream = YES;
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
|
||||
- (void)setShouldReset:(BOOL)s;
|
||||
- (BOOL)shouldReset;
|
||||
- (void)resetBackwards;
|
||||
|
||||
- (void)setPreviousNode:(id _Nullable)p;
|
||||
- (id _Nullable)previousNode;
|
||||
|
|
|
@ -523,6 +523,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)lockedResetBuffer {
|
||||
@autoreleasepool {
|
||||
[buffer reset];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)unlockedResetBuffer {
|
||||
@autoreleasepool {
|
||||
[accessLock lock];
|
||||
[buffer reset];
|
||||
[accessLock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
// Implementations should override
|
||||
- (BOOL)paused {
|
||||
return NO;
|
||||
|
@ -556,4 +570,23 @@
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
// Reset everything in the chain
|
||||
- (void)resetBackwards {
|
||||
[accessLock lock];
|
||||
if(buffer) {
|
||||
[self lockedResetBuffer];
|
||||
[writeSemaphore signal];
|
||||
[readSemaphore signal];
|
||||
}
|
||||
Node *node = previousNode;
|
||||
while(node) {
|
||||
[node unlockedResetBuffer];
|
||||
[node setShouldReset:YES];
|
||||
[[node writeSemaphore] signal];
|
||||
[[node readSemaphore] signal];
|
||||
node = [node previousNode];
|
||||
}
|
||||
[accessLock unlock];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -62,9 +62,6 @@
|
|||
- (double)volume;
|
||||
- (void)setVolume:(double)v;
|
||||
|
||||
- (void)mute;
|
||||
- (void)unmute;
|
||||
|
||||
- (void)setShouldContinue:(BOOL)s;
|
||||
|
||||
- (void)setShouldPlayOutBuffer:(BOOL)s;
|
||||
|
|
|
@ -50,14 +50,6 @@
|
|||
[output resume];
|
||||
}
|
||||
|
||||
- (void)mute {
|
||||
[output mute];
|
||||
}
|
||||
|
||||
- (void)unmute {
|
||||
[output unmute];
|
||||
}
|
||||
|
||||
- (void)incrementAmountPlayed:(double)seconds {
|
||||
amountPlayed += seconds;
|
||||
amountPlayedInterval += seconds;
|
||||
|
@ -189,7 +181,6 @@
|
|||
}
|
||||
}
|
||||
if(formatChanged) {
|
||||
[audioPlayer mute];
|
||||
InputNode *inputNode = [bufferChain inputNode];
|
||||
if(converter) {
|
||||
[converter setOutputFormat:format];
|
||||
|
|
|
@ -105,7 +105,6 @@ using std::atomic_long;
|
|||
float tempBuffer[512 * 32];
|
||||
float inputBuffer[4096 * 32]; // 4096 samples times maximum supported channel count
|
||||
|
||||
BOOL muted;
|
||||
#ifdef OUTPUT_LOG
|
||||
FILE *_logFile;
|
||||
#endif
|
||||
|
@ -126,9 +125,6 @@ using std::atomic_long;
|
|||
- (double)volume;
|
||||
- (void)setVolume:(double)v;
|
||||
|
||||
- (void)mute;
|
||||
- (void)unmute;
|
||||
|
||||
- (void)setShouldPlayOutBuffer:(BOOL)enabled;
|
||||
|
||||
- (void)sustainHDCD;
|
||||
|
|
|
@ -203,6 +203,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
|||
started = NO;
|
||||
restarted = NO;
|
||||
lastClippedSampleRate = 0.0;
|
||||
inputRemain = 0;
|
||||
[outputLock unlock];
|
||||
}
|
||||
|
||||
|
@ -618,12 +619,6 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
|||
|
||||
@autoreleasepool {
|
||||
while(renderedSamples < frameCount) {
|
||||
if(_self->muted) {
|
||||
inputData->mBuffers[0].mDataByteSize = frameCount * format->mBytesPerPacket;
|
||||
inputData->mBuffers[0].mNumberChannels = channels;
|
||||
bzero(inputData->mBuffers[0].mData, inputData->mBuffers[0].mDataByteSize);
|
||||
return 0;
|
||||
}
|
||||
int inputRemain = _self->inputRemain;
|
||||
while(!inputRemain) {
|
||||
inputRemain = [_self renderAndConvert];
|
||||
|
@ -746,17 +741,6 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
|||
volume = v * 0.01f;
|
||||
}
|
||||
|
||||
- (void)mute {
|
||||
if(!muted) {
|
||||
muted = YES;
|
||||
inputRemain = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)unmute {
|
||||
muted = NO;
|
||||
}
|
||||
|
||||
- (double)latency {
|
||||
return 0.0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue