Cog Audio: Implement play position skip ahead when output format changes, based on how much converter output is being discarded
This commit is contained in:
parent
52b17bd4d8
commit
73348b1616
2 changed files with 17 additions and 11 deletions
|
@ -18,7 +18,8 @@
|
|||
@interface OutputNode : Node {
|
||||
AudioStreamBasicDescription format;
|
||||
|
||||
unsigned long long amountPlayed;
|
||||
double amountPlayed;
|
||||
double sampleRatio;
|
||||
OutputCoreAudio *output;
|
||||
|
||||
BOOL paused;
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
- (void)setup
|
||||
{
|
||||
amountPlayed = 0;
|
||||
amountPlayed = 0.0;
|
||||
sampleRatio = 0.0;
|
||||
|
||||
paused = YES;
|
||||
|
||||
|
@ -30,7 +31,7 @@
|
|||
{
|
||||
// [output pause];
|
||||
|
||||
amountPlayed = time*format.mBytesPerFrame*(format.mSampleRate);
|
||||
amountPlayed = time;
|
||||
}
|
||||
|
||||
- (void)process
|
||||
|
@ -58,11 +59,11 @@
|
|||
[self setPreviousNode:[[controller bufferChain] finalNode]];
|
||||
|
||||
n = [super readData:ptr amount:amount];
|
||||
amountPlayed += n;
|
||||
amountPlayed += (double)n * sampleRatio;
|
||||
|
||||
if (endOfStream == YES && !n)
|
||||
{
|
||||
amountPlayed = 0;
|
||||
amountPlayed = 0.0;
|
||||
[controller endOfInputPlayed]; //Updates shouldContinue appropriately?
|
||||
}
|
||||
|
||||
|
@ -78,7 +79,7 @@
|
|||
|
||||
- (double)amountPlayed
|
||||
{
|
||||
return (amountPlayed/format.mBytesPerFrame)/(format.mSampleRate);
|
||||
return amountPlayed;
|
||||
}
|
||||
|
||||
- (AudioStreamBasicDescription) format
|
||||
|
@ -89,16 +90,20 @@
|
|||
- (void)setFormat:(AudioStreamBasicDescription *)f
|
||||
{
|
||||
format = *f;
|
||||
// Calculate a ratio and add to double(seconds) instead, as format may change
|
||||
double oldSampleRatio = sampleRatio;
|
||||
sampleRatio = 1.0 / (format.mSampleRate * format.mBytesPerPacket);
|
||||
BufferChain *bufferChain = [controller bufferChain];
|
||||
if (bufferChain)
|
||||
{
|
||||
InputNode *input = [bufferChain inputNode];
|
||||
ConverterNode *converter = [bufferChain converter];
|
||||
if (input && converter)
|
||||
if (converter)
|
||||
{
|
||||
// Need to clear the buffer, as it contains converted output
|
||||
// targeting the previous output format
|
||||
[input resetBuffer];
|
||||
// This clears the resampler buffer, but not the input buffer
|
||||
// We also have to jump the play position ahead accounting for
|
||||
// the data we are flushing
|
||||
if (oldSampleRatio)
|
||||
amountPlayed += oldSampleRatio * [[converter buffer] bufferedLength];
|
||||
[converter setOutputFormat:format];
|
||||
[converter inputFormatDidChange:[bufferChain inputFormat]];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue