Do not reset output sample rate automatically

This was buggy as hell, and resulted in errors. Now the user should
restart playback if they change output device formats.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
CQTexperiment
Christopher Snowhill 2022-02-07 22:02:17 -08:00
parent 4fd24838fa
commit 728c44242c
12 changed files with 34 additions and 176 deletions

View File

@ -16,9 +16,6 @@
InputNode *inputNode; InputNode *inputNode;
ConverterNode *converterNode; ConverterNode *converterNode;
AudioStreamBasicDescription inputFormat;
uint32_t inputChannelConfig;
NSURL *streamURL; NSURL *streamURL;
id userInfo; id userInfo;
NSDictionary *rgInfo; NSDictionary *rgInfo;

View File

@ -60,7 +60,8 @@
NSDictionary *properties = [inputNode properties]; NSDictionary *properties = [inputNode properties];
inputFormat = [inputNode nodeFormat]; AudioStreamBasicDescription inputFormat = [inputNode nodeFormat];
uint32_t inputChannelConfig = 0;
if([properties valueForKey:@"channelConfig"]) if([properties valueForKey:@"channelConfig"])
inputChannelConfig = [[properties valueForKey:@"channelConfig"] unsignedIntValue]; inputChannelConfig = [[properties valueForKey:@"channelConfig"] unsignedIntValue];
@ -89,7 +90,8 @@
NSDictionary *properties = [inputNode properties]; NSDictionary *properties = [inputNode properties];
inputFormat = [inputNode nodeFormat]; AudioStreamBasicDescription inputFormat = [inputNode nodeFormat];
uint32_t inputChannelConfig = 0;
if([properties valueForKey:@"channelConfig"]) if([properties valueForKey:@"channelConfig"])
inputChannelConfig = [[properties valueForKey:@"channelConfig"] unsignedIntValue]; inputChannelConfig = [[properties valueForKey:@"channelConfig"] unsignedIntValue];
@ -123,7 +125,8 @@
DLog(@"Input Properties: %@", properties); DLog(@"Input Properties: %@", properties);
inputFormat = [inputNode nodeFormat]; AudioStreamBasicDescription inputFormat = [inputNode nodeFormat];
uint32_t inputChannelConfig = 0;
if([properties valueForKey:@"channelConfig"]) if([properties valueForKey:@"channelConfig"])
inputChannelConfig = [[properties valueForKey:@"channelConfig"] unsignedIntValue]; inputChannelConfig = [[properties valueForKey:@"channelConfig"] unsignedIntValue];
@ -231,11 +234,11 @@
} }
- (AudioStreamBasicDescription)inputFormat { - (AudioStreamBasicDescription)inputFormat {
return inputFormat; return [inputNode nodeFormat];
} }
- (uint32_t)inputConfig { - (uint32_t)inputConfig {
return inputChannelConfig; return [inputNode nodeChannelConfig];
} }
- (double)secondsBuffered { - (double)secondsBuffered {

View File

@ -50,7 +50,7 @@
} }
- (BOOL)isFull { - (BOOL)isFull {
return (maxDuration - listDuration) < 0.01; return (maxDuration - listDuration) < 0.05;
} }
- (void)addChunk:(AudioChunk *)chunk { - (void)addChunk:(AudioChunk *)chunk {

View File

@ -15,7 +15,6 @@
#import <soxr.h> #import <soxr.h>
#import "Node.h" #import "Node.h"
#import "RefillNode.h"
#import "HeadphoneFilter.h" #import "HeadphoneFilter.h"
@ -31,7 +30,6 @@
BOOL stopping; BOOL stopping;
BOOL convertEntered; BOOL convertEntered;
BOOL paused; BOOL paused;
BOOL outputFormatChanged;
BOOL skipResampler; BOOL skipResampler;
@ -77,13 +75,6 @@
AudioChunk *lastChunkIn; AudioChunk *lastChunkIn;
AudioStreamBasicDescription previousOutputFormat;
uint32_t previousOutputConfig;
AudioStreamBasicDescription rememberedInputFormat;
uint32_t rememberedInputConfig;
RefillNode *refillNode;
id __weak originalPreviousNode;
void *hdcd_decoder; void *hdcd_decoder;
HeadphoneFilter *hFilter; HeadphoneFilter *hFilter;

View File

@ -53,13 +53,9 @@ void PrintStreamDesc(AudioStreamBasicDescription *inDesc) {
stopping = NO; stopping = NO;
convertEntered = NO; convertEntered = NO;
paused = NO; paused = NO;
outputFormatChanged = NO;
skipResampler = YES; skipResampler = YES;
refillNode = nil;
originalPreviousNode = nil;
extrapolateBuffer = NULL; extrapolateBuffer = NULL;
extrapolateBufferSize = 0; extrapolateBufferSize = 0;
@ -68,6 +64,8 @@ void PrintStreamDesc(AudioStreamBasicDescription *inDesc) {
hdcd_decoder = NULL; hdcd_decoder = NULL;
lastChunkIn = nil;
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.volumeScaling" options:0 context:nil]; [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.volumeScaling" options:0 context:nil];
} }
@ -423,22 +421,14 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
// and returns 0 samples when it has nothing more to process at the end of stream. // and returns 0 samples when it has nothing more to process at the end of stream.
while([self shouldContinue] == YES) { while([self shouldContinue] == YES) {
int amountConverted; int amountConverted;
while(paused) {
usleep(500);
}
@autoreleasepool { @autoreleasepool {
amountConverted = [self convert:writeBuf amount:CHUNK_SIZE]; amountConverted = [self convert:writeBuf amount:CHUNK_SIZE];
} }
if(!amountConverted) { if(!amountConverted) {
if(paused) { if(paused) {
while(paused)
usleep(500);
continue;
} else if(refillNode) {
// refill node just ended, file resumes
[self setPreviousNode:originalPreviousNode];
[self setEndOfStream:NO];
[self setShouldContinue:YES];
refillNode = nil;
[self cleanUp];
[self setupWithInputFormat:rememberedInputFormat withInputConfig:rememberedInputConfig outputFormat:outputFormat outputConfig:outputChannelConfig isLossless:rememberedLossless];
continue; continue;
} else if(streamFormatChanged) { } else if(streamFormatChanged) {
[self cleanUp]; [self cleanUp];
@ -503,7 +493,7 @@ tryagain:
ssize_t bytesReadFromInput = 0; ssize_t bytesReadFromInput = 0;
while(bytesReadFromInput < amountToWrite && !stopping && !streamFormatChanged && [self shouldContinue] == YES && [self endOfStream] == NO) { while(bytesReadFromInput < amountToWrite && !stopping && !paused && !streamFormatChanged && [self shouldContinue] == YES && [self endOfStream] == NO) {
AudioStreamBasicDescription inf; AudioStreamBasicDescription inf;
uint32_t config; uint32_t config;
if([self peekFormat:&inf channelConfig:&config]) { if([self peekFormat:&inf channelConfig:&config]) {
@ -536,16 +526,13 @@ tryagain:
} }
bytesReadFromInput += bytesRead; bytesReadFromInput += bytesRead;
if(!frameCount) { if(!frameCount) {
if(refillNode) usleep(500);
[self setEndOfStream:YES];
else
usleep(500);
} }
} }
// Pad end of track with input format silence // Pad end of track with input format silence
if(stopping || streamFormatChanged || [self shouldContinue] == NO || [self endOfStream] == YES) { if(stopping || paused || streamFormatChanged || [self shouldContinue] == NO || [self endOfStream] == YES) {
if(!skipResampler && !is_postextrapolated_) { if(!skipResampler && !is_postextrapolated_) {
if(dsd2pcm) { if(dsd2pcm) {
amountToSkip = dsd2pcmLatency * inputFormat.mBytesPerPacket; amountToSkip = dsd2pcmLatency * inputFormat.mBytesPerPacket;
@ -989,9 +976,8 @@ static float db_to_scale(float db) {
// Move this here so process call isn't running the resampler until it's allocated // Move this here so process call isn't running the resampler until it's allocated
stopping = NO; stopping = NO;
convertEntered = NO; convertEntered = NO;
paused = NO;
outputFormatChanged = NO;
streamFormatChanged = NO; streamFormatChanged = NO;
paused = NO;
return YES; return YES;
} }
@ -1007,46 +993,18 @@ static float db_to_scale(float db) {
- (void)setOutputFormat:(AudioStreamBasicDescription)format outputConfig:(uint32_t)outputConfig { - (void)setOutputFormat:(AudioStreamBasicDescription)format outputConfig:(uint32_t)outputConfig {
DLog(@"SETTING OUTPUT FORMAT!"); DLog(@"SETTING OUTPUT FORMAT!");
previousOutputFormat = outputFormat;
previousOutputConfig = outputChannelConfig;
outputFormat = format; outputFormat = format;
outputChannelConfig = outputConfig; outputChannelConfig = outputConfig;
outputFormatChanged = YES;
} }
- (void)inputFormatDidChange:(AudioStreamBasicDescription)format inputConfig:(uint32_t)inputConfig { - (void)inputFormatDidChange:(AudioStreamBasicDescription)format inputConfig:(uint32_t)inputConfig {
DLog(@"FORMAT CHANGED"); DLog(@"FORMAT CHANGED");
paused = YES; paused = YES;
[self cleanUp]; while(convertEntered) {
if(outputFormatChanged && ![buffer isEmpty] && usleep(500);
(outputChannelConfig != previousOutputConfig ||
memcmp(&outputFormat, &previousOutputFormat, sizeof(outputFormat)) != 0)) {
// Transfer previously buffered data, remember input format
rememberedInputFormat = format;
rememberedInputConfig = inputChannelConfig;
originalPreviousNode = previousNode;
refillNode = [[RefillNode alloc] initWithController:controller previous:nil];
[self setPreviousNode:refillNode];
[refillNode setFormat:previousOutputFormat];
[refillNode setChannelConfig:previousOutputConfig];
for(;;) {
@autoreleasepool {
AudioChunk *chunk = [buffer removeSamples:16384];
size_t frameCount = [chunk frameCount];
if(frameCount) {
NSData *samples = [chunk removeSamples:frameCount];
[refillNode writeData:[samples bytes] amount:frameCount];
} else
break;
}
}
[self setupWithInputFormat:previousOutputFormat withInputConfig:[AudioChunk guessChannelConfig:previousOutputFormat.mChannelsPerFrame] outputFormat:outputFormat outputConfig:outputChannelConfig isLossless:rememberedLossless];
} else {
[self setupWithInputFormat:format withInputConfig:inputConfig outputFormat:outputFormat outputConfig:outputChannelConfig isLossless:rememberedLossless];
} }
[self cleanUp];
[self setupWithInputFormat:format withInputConfig:inputConfig outputFormat:outputFormat outputConfig:outputChannelConfig isLossless:rememberedLossless];
} }
- (void)setRGInfo:(NSDictionary *)rgi { - (void)setRGInfo:(NSDictionary *)rgi {

View File

@ -147,13 +147,12 @@ static void downmix_to_mono(const float *inBuffer, int channels, uint32_t config
inBuffer = tempBuffer; inBuffer = tempBuffer;
channels = 2; channels = 2;
config = AudioConfigStereo; config = AudioConfigStereo;
float invchannels = 1.0 / (float)channels;
for(size_t i = 0; i < count; ++i) { for(size_t i = 0; i < count; ++i) {
float sample = 0; float sample = 0;
for(int j = 0; j < channels; ++j) { for(int j = 0; j < channels; ++j) {
sample += inBuffer[i * channels + j]; sample += inBuffer[i * channels + j];
} }
outBuffer[i] = sample * invchannels; outBuffer[i] = sample;
} }
} }

View File

@ -20,7 +20,6 @@
uint32_t config; uint32_t config;
double amountPlayed; double amountPlayed;
double sampleRatio;
OutputCoreAudio *output; OutputCoreAudio *output;
BOOL paused; BOOL paused;

View File

@ -17,7 +17,6 @@
- (void)setup { - (void)setup {
amountPlayed = 0.0; amountPlayed = 0.0;
sampleRatio = 0.0;
paused = YES; paused = YES;
started = NO; started = NO;
@ -100,7 +99,6 @@
config = channelConfig; config = channelConfig;
// Calculate a ratio and add to double(seconds) instead, as format may change // Calculate a ratio and add to double(seconds) instead, as format may change
// double oldSampleRatio = sampleRatio; // double oldSampleRatio = sampleRatio;
sampleRatio = 1.0 / (format.mSampleRate * format.mBytesPerPacket);
BufferChain *bufferChain = [controller bufferChain]; BufferChain *bufferChain = [controller bufferChain];
if(bufferChain) { if(bufferChain) {
ConverterNode *converter = [bufferChain converter]; ConverterNode *converter = [bufferChain converter];
@ -108,13 +106,16 @@
// This clears the resampler buffer, but not the input buffer // This clears the resampler buffer, but not the input buffer
// We also have to jump the play position ahead accounting for // We also have to jump the play position ahead accounting for
// the data we are flushing // the data we are flushing
#if 0 amountPlayed += [[converter buffer] listDuration];
// We no longer need to do this, because outputchanged converter
// now uses the RefillNode to slap the previous samples into AudioStreamBasicDescription inf = [bufferChain inputFormat];
// itself uint32_t config = [bufferChain inputConfig];
if (oldSampleRatio)
amountPlayed += oldSampleRatio * [[converter buffer] bufferedLength]; format.mChannelsPerFrame = inf.mChannelsPerFrame;
#endif format.mBytesPerFrame = ((inf.mBitsPerChannel + 7) / 8) * format.mChannelsPerFrame;
format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket;
channelConfig = config;
[converter setOutputFormat:format [converter setOutputFormat:format
outputConfig:channelConfig]; outputConfig:channelConfig];
[converter inputFormatDidChange:[bufferChain inputFormat] inputConfig:[bufferChain inputConfig]]; [converter inputFormatDidChange:[bufferChain inputFormat] inputConfig:[bufferChain inputConfig]];

View File

@ -1,27 +0,0 @@
//
// RefillNode.h
// Cog
//
// Created by Christopher SNowhill on 1/13/22.
// Copyright 2022 __LoSnoCo__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AudioUnit/AudioUnit.h>
#import <CoreAudio/AudioHardware.h>
#import "Node.h"
#import "Plugin.h"
#define INPUT_NODE_SEEK
@interface RefillNode : Node {
// This node just slaps pre-converted data into its buffer for re-buffering
}
- (void)setFormat:(AudioStreamBasicDescription)format;
- (void)setChannelConfig:(uint32_t)config;
@end

View File

@ -1,49 +0,0 @@
//
// RefillNode.m
// Cog
//
// Created by Christopher Snowhill on 1/13/22.
// Copyright 2022 __LoSnoCo__. All rights reserved.
//
#import "RefillNode.h"
#import "Plugin.h"
#import "Logging.h"
@implementation RefillNode
- (id)initWithController:(id)c previous:(id)p {
self = [super init];
if(self) {
// This special node should be able to handle up to four buffers
buffer = [[ChunkList alloc] initWithMaximumDuration:12.0];
semaphore = [[Semaphore alloc] init];
initialBufferFilled = NO;
controller = c;
endOfStream = NO;
shouldContinue = YES;
nodeLossless = NO;
[self setPreviousNode:p];
}
return self;
}
- (void)dealloc {
DLog(@"Refill Node dealloc");
}
- (void)setFormat:(AudioStreamBasicDescription)format {
nodeFormat = format;
}
- (void)setChannelConfig:(uint32_t)config {
nodeChannelConfig = config;
}
@end

View File

@ -66,8 +66,6 @@
8384912718080FF100E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384912618080FF100E7332D /* Logging.h */; }; 8384912718080FF100E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384912618080FF100E7332D /* Logging.h */; };
839366671815923C006DD712 /* CogPluginMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 839366651815923C006DD712 /* CogPluginMulti.h */; }; 839366671815923C006DD712 /* CogPluginMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 839366651815923C006DD712 /* CogPluginMulti.h */; };
839366681815923C006DD712 /* CogPluginMulti.m in Sources */ = {isa = PBXBuildFile; fileRef = 839366661815923C006DD712 /* CogPluginMulti.m */; }; 839366681815923C006DD712 /* CogPluginMulti.m in Sources */ = {isa = PBXBuildFile; fileRef = 839366661815923C006DD712 /* CogPluginMulti.m */; };
83A44A01279119B50049B6E2 /* RefillNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A449FF279119B50049B6E2 /* RefillNode.m */; };
83A44A02279119B50049B6E2 /* RefillNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A44A00279119B50049B6E2 /* RefillNode.h */; };
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; };
8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */; }; 8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */; };
@ -162,8 +160,6 @@
8384912618080FF100E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 8384912618080FF100E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
839366651815923C006DD712 /* CogPluginMulti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogPluginMulti.h; sourceTree = "<group>"; }; 839366651815923C006DD712 /* CogPluginMulti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogPluginMulti.h; sourceTree = "<group>"; };
839366661815923C006DD712 /* CogPluginMulti.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CogPluginMulti.m; sourceTree = "<group>"; }; 839366661815923C006DD712 /* CogPluginMulti.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CogPluginMulti.m; sourceTree = "<group>"; };
83A449FF279119B50049B6E2 /* RefillNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RefillNode.m; sourceTree = "<group>"; };
83A44A00279119B50049B6E2 /* RefillNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefillNode.h; sourceTree = "<group>"; };
8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8DC2EF5B0486A6940098B216 /* CogAudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CogAudio.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8DC2EF5B0486A6940098B216 /* CogAudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CogAudio.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContainer.h; sourceTree = "<group>"; }; 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContainer.h; sourceTree = "<group>"; };
@ -298,8 +294,6 @@
834FD4EF27AF93680063BC83 /* ChunkList.m */, 834FD4EF27AF93680063BC83 /* ChunkList.m */,
834FD4F227AFA2150063BC83 /* Downmix.h */, 834FD4F227AFA2150063BC83 /* Downmix.h */,
834FD4F327AFA2150063BC83 /* Downmix.m */, 834FD4F327AFA2150063BC83 /* Downmix.m */,
83A44A00279119B50049B6E2 /* RefillNode.h */,
83A449FF279119B50049B6E2 /* RefillNode.m */,
17D21C760B8BE4BA00D1EBDE /* BufferChain.h */, 17D21C760B8BE4BA00D1EBDE /* BufferChain.h */,
17D21C770B8BE4BA00D1EBDE /* BufferChain.m */, 17D21C770B8BE4BA00D1EBDE /* BufferChain.m */,
8EC1225D0B993BD500C5B3AD /* ConverterNode.h */, 8EC1225D0B993BD500C5B3AD /* ConverterNode.h */,
@ -457,7 +451,6 @@
839366671815923C006DD712 /* CogPluginMulti.h in Headers */, 839366671815923C006DD712 /* CogPluginMulti.h in Headers */,
17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */, 17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */,
835C88B1279811A500E28EAE /* hdcd_decode2.h in Headers */, 835C88B1279811A500E28EAE /* hdcd_decode2.h in Headers */,
83A44A02279119B50049B6E2 /* RefillNode.h in Headers */,
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */, 8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */,
8384912718080FF100E7332D /* Logging.h in Headers */, 8384912718080FF100E7332D /* Logging.h in Headers */,
8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */, 8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */,
@ -560,7 +553,6 @@
17C940240B900909008627D6 /* AudioMetadataReader.m in Sources */, 17C940240B900909008627D6 /* AudioMetadataReader.m in Sources */,
17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */, 17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */,
17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */, 17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */,
83A44A01279119B50049B6E2 /* RefillNode.m in Sources */,
834FD4F127AF93680063BC83 /* ChunkList.m in Sources */, 834FD4F127AF93680063BC83 /* ChunkList.m in Sources */,
8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */, 8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */,
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */, 8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */,

View File

@ -211,16 +211,10 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const
running = YES; running = YES;
started = NO; started = NO;
stopNext = NO; stopNext = NO;
size_t eventCount = 0;
atomic_store(&bytesRendered, 0); atomic_store(&bytesRendered, 0);
NSMutableArray *delayedEvents = [[NSMutableArray alloc] init]; NSMutableArray *delayedEvents = [[NSMutableArray alloc] init];
BOOL delayedEventsPopped = YES; BOOL delayedEventsPopped = YES;
while(!stopping) { while(!stopping) {
if(++eventCount == 128) {
[self updateDeviceFormat];
eventCount = 0;
}
if([outputController shouldReset]) { if([outputController shouldReset]) {
@autoreleasepool { @autoreleasepool {
[[outputController buffer] reset]; [[outputController buffer] reset];
@ -671,7 +665,7 @@ default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const
#endif #endif
inputData->mBuffers[0].mNumberChannels = channels; inputData->mBuffers[0].mNumberChannels = channels;
return 0; return 0;
}; };