I'm using this library to build a radio iOS app that has a directory of Icecast streams that the user can click on and listen to.
This library works very well 95% of the time, but 5% of the time, the player gets stuck in the STKAudioPlayerStateBuffering state and never changes, not reporting any errors at all. It seems like some kind of a race condition. Any idea why this could be happening?
- (BOOL)startAudioIO
{
NSError *error = nil;
AVAudioSessionCategory category = AVAudioSessionCategoryPlayAndRecord;
AVAudioSessionCategoryOptions options = AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionDefaultToSpeaker;
if ([AVAudioSession sharedInstance].category != category || [AVAudioSession sharedInstance].categoryOptions != options) {
[[AVAudioSession sharedInstance] setCategory:category withOptions:options error:&error];
if (error) {
NSLog(@"STKAudioPlayer: Error setting category on audio session.");
return NO;
}
}
[[AVAudioSession sharedInstance] setActive:YES error:&error];
if (error) {
NSLog(@"STKAudioPlayer: Error starting audio session.");
return NO;
}
return YES;
}
- (void)setupPlayer
{
STKAudioPlayerOptions options;
options.bufferSizeInSeconds = 2;
_audioPlayer = [[STKAudioPlayer alloc] initWithOptions:options];
_audioPlayer.delegate = self;
[_audioPlayer appendFrameFilterWithName:@"FFT" block:^(UInt32 channelsPerFrame, UInt32 bytesPerFrame, UInt32 frameCount, void* frames)
{
uint16_t bytesPerSample = bytesPerFrame / channelsPerFrame;
if (bytesPerSample == 2) {
vDSP_vflt16((short *)frames, 1, self->_floatInputBuffer, 1, frameCount * channelsPerFrame);
} else if (bytesPerSample == 4) {
vDSP_vflt32((int *)frames, 1, self->_floatInputBuffer, 1, frameCount * channelsPerFrame);
} else {
NSLog(@"STKAudioPlayer: Other bytePerSample sizes are not supported. TODO(zsaraf): Test for this now!");
}
// 2^(n-1) because it is a signed number where n = 16 (short *)
const float nBits = pow(2, (bytesPerSample * 8) - 1);
vDSP_vsdiv(self->_floatInputBuffer, 1, &nBits, self->_floatNormalizedInputBuffer, 1, channelsPerFrame * frameCount);
[[DFFTManager shared] processFFTWithInputBuffers:self->_fftArgBuffer inputChannels:channelsPerFrame numberOfSamples:frameCount interleaved:YES];
}];
}
- (void)startStreamWithUrl:(NSString *)streamUrl
streamName:(NSString *)streamName
streamImage:(NSString *)streamImage
streamCreatorUsername:(NSString *)streamCreatorUsername
{
// Set values in case we get disconnected and need to reconnect.
self->_streamUrl = streamUrl;
self->_streamName = streamName;
self->_streamImage = streamImage;
self->_streamCreatorUsername = streamCreatorUsername;
// Begin stream.
dispatch_async(dispatch_get_main_queue(), ^{
[self startAudioIO];
if (self->_audioPlayer == nil) {
[self setupPlayer];
}
[self->_audioPlayer play:streamUrl];
});
}
- (void)stopStream
{
dispatch_async(dispatch_get_main_queue(), ^{
[self->_audioPlayer stop];
[self cleanupStream];
});
}
I'm using this library to build a radio iOS app that has a directory of Icecast streams that the user can click on and listen to.
This library works very well 95% of the time, but 5% of the time, the player gets stuck in the
STKAudioPlayerStateBuffering
state and never changes, not reporting any errors at all. It seems like some kind of a race condition. Any idea why this could be happening?Any ideas at all on where to look?
Thanks Zach