diff --git a/ExampleApp/ExampleApp.xcodeproj/project.pbxproj b/ExampleApp/ExampleApp.xcodeproj/project.pbxproj index 046b397..53b60b7 100644 --- a/ExampleApp/ExampleApp.xcodeproj/project.pbxproj +++ b/ExampleApp/ExampleApp.xcodeproj/project.pbxproj @@ -230,7 +230,7 @@ A1115929188D686000641365 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0510; + LastUpgradeCheck = 0710; ORGANIZATIONNAME = "Thong Nguyen"; TargetAttributes = { A111594B188D686000641365 = { @@ -346,6 +346,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -422,6 +423,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 6.0; LLVM_LTO = YES; OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = "abstractpath.com.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -438,6 +440,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 6.0; LLVM_LTO = YES; OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = "abstractpath.com.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -459,6 +462,7 @@ "$(inherited)", ); INFOPLIST_FILE = "ExampleAppTests/ExampleAppTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "abstractpath.com.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; WRAPPER_EXTENSION = xctest; @@ -477,6 +481,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ExampleApp/ExampleApp-Prefix.pch"; INFOPLIST_FILE = "ExampleAppTests/ExampleAppTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "abstractpath.com.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; WRAPPER_EXTENSION = xctest; diff --git a/ExampleApp/ExampleApp/AppDelegate.m b/ExampleApp/ExampleApp/AppDelegate.m index d0680af..bb3d37c 100644 --- a/ExampleApp/ExampleApp/AppDelegate.m +++ b/ExampleApp/ExampleApp/AppDelegate.m @@ -32,6 +32,7 @@ AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(bufferLength), &bufferLength); self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + self.window.rootViewController = [[UIViewController alloc] init]; self.window.backgroundColor = [UIColor whiteColor]; @@ -39,7 +40,6 @@ audioPlayer.meteringEnabled = YES; audioPlayer.volume = 1; - AudioPlayerView* audioPlayerView = [[AudioPlayerView alloc] initWithFrame:self.window.bounds andAudioPlayer:audioPlayer]; audioPlayerView.delegate = self; @@ -47,9 +47,9 @@ [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; [self becomeFirstResponder]; - [self.window addSubview:audioPlayerView]; - [self.window makeKeyAndVisible]; + + [self.window.rootViewController.view addSubview:audioPlayerView]; return YES; } diff --git a/ExampleApp/ExampleApp/AudioPlayerView.m b/ExampleApp/ExampleApp/AudioPlayerView.m index a93ea0b..5be5e70 100644 --- a/ExampleApp/ExampleApp/AudioPlayerView.m +++ b/ExampleApp/ExampleApp/AudioPlayerView.m @@ -58,27 +58,27 @@ CGSize size = CGSizeMake(220, 50); playFromHTTPButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - playFromHTTPButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10, size.width, size.height); + playFromHTTPButton.frame = CGRectMake((frame.size.width - size.width) / 2, frame.size.height * 0.10, size.width, size.height); [playFromHTTPButton addTarget:self action:@selector(playFromHTTPButtonTouched) forControlEvents:UIControlEventTouchUpInside]; [playFromHTTPButton setTitle:@"Play from HTTP" forState:UIControlStateNormal]; playFromIcecastButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - playFromIcecastButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 35, size.width, size.height); + playFromIcecastButton.frame = CGRectMake((frame.size.width - size.width) / 2, frame.size.height * 0.10 + 35, size.width, size.height); [playFromIcecastButton addTarget:self action:@selector(playFromIcecasButtonTouched) forControlEvents:UIControlEventTouchUpInside]; [playFromIcecastButton setTitle:@"Play from Icecast" forState:UIControlStateNormal]; playFromLocalFileButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - playFromLocalFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 70, size.width, size.height); + playFromLocalFileButton.frame = CGRectMake((frame.size.width - size.width) / 2, frame.size.height * 0.10 + 70, size.width, size.height); [playFromLocalFileButton addTarget:self action:@selector(playFromLocalFileButtonTouched) forControlEvents:UIControlEventTouchUpInside]; [playFromLocalFileButton setTitle:@"Play from Local File" forState:UIControlStateNormal]; queueShortFileButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - queueShortFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 105, size.width, size.height); + queueShortFileButton.frame = CGRectMake((frame.size.width - size.width) / 2, frame.size.height * 0.10 + 105, size.width, size.height); [queueShortFileButton addTarget:self action:@selector(queueShortFileButtonTouched) forControlEvents:UIControlEventTouchUpInside]; [queueShortFileButton setTitle:@"Queue short file" forState:UIControlStateNormal]; queuePcmWaveFileFromHTTPButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - queuePcmWaveFileFromHTTPButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 140, size.width, size.height); + queuePcmWaveFileFromHTTPButton.frame = CGRectMake((frame.size.width - size.width) / 2, frame.size.height * 0.10 + 140, size.width, size.height); [queuePcmWaveFileFromHTTPButton addTarget:self action:@selector(queuePcmWaveFileButtonTouched) forControlEvents:UIControlEventTouchUpInside]; [queuePcmWaveFileFromHTTPButton setTitle:@"Queue PCM/WAVE from HTTP" forState:UIControlStateNormal]; @@ -89,12 +89,12 @@ [playButton addTarget:self action:@selector(playButtonPressed) forControlEvents:UIControlEventTouchUpInside]; stopButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - stopButton.frame = CGRectMake((320 - size.width) - 30, 400, size.width, size.height); + stopButton.frame = CGRectMake((frame.size.width - size.width) - 30, 400, size.width, size.height); [stopButton addTarget:self action:@selector(stopButtonPressed) forControlEvents:UIControlEventTouchUpInside]; [stopButton setTitle:@"Stop" forState:UIControlStateNormal]; muteButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; - muteButton.frame = CGRectMake((320 - size.width) - 30, 430, size.width, size.height); + muteButton.frame = CGRectMake((frame.size.width - size.width) - 30, 430, size.width, size.height); [muteButton addTarget:self action:@selector(muteButtonPressed) forControlEvents:UIControlEventTouchUpInside]; [muteButton setTitle:@"Mute" forState:UIControlStateNormal]; @@ -106,7 +106,7 @@ repeatSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(30, frame.size.height * 0.15 + 180, size.width, size.height)]; - enableEqSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(320 - size.width - 30, frame.size.height * 0.15 + 180, size.width, size.height)]; + enableEqSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(frame.size.width - size.width - 30, frame.size.height * 0.15 + 180, size.width, size.height)]; enableEqSwitch.on = audioPlayer.equalizerEnabled; [enableEqSwitch addTarget:self action:@selector(onEnableEqSwitch) forControlEvents:UIControlEventAllTouchEvents]; diff --git a/ExampleApp/ExampleApp/ExampleApp-Info.plist b/ExampleApp/ExampleApp/ExampleApp-Info.plist index f2f0135..ef8abcd 100644 --- a/ExampleApp/ExampleApp/ExampleApp-Info.plist +++ b/ExampleApp/ExampleApp/ExampleApp-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - abstractpath.com.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/ExampleApp/ExampleApp/Images.xcassets/AppIcon.appiconset/Contents.json b/ExampleApp/ExampleApp/Images.xcassets/AppIcon.appiconset/Contents.json index 91bf9c1..36d2c80 100644 --- a/ExampleApp/ExampleApp/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/ExampleApp/ExampleApp/Images.xcassets/AppIcon.appiconset/Contents.json @@ -5,16 +5,31 @@ "size" : "29x29", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, { "idiom" : "ipad", "size" : "29x29", diff --git a/ExampleApp/ExampleApp/Images.xcassets/Contents.json b/ExampleApp/ExampleApp/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/ExampleApp/ExampleApp/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/Contents.json b/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/Contents.json index 6f870a4..83b8ad2 100644 --- a/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/Contents.json +++ b/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -1,5 +1,31 @@ { "images" : [ + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "TX6sV.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "3x" + }, + { + "orientation" : "landscape", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "8.0", + "subtype" : "736h", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "667h", + "filename" : "dBEHd.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "2x" + }, { "orientation" : "portrait", "idiom" : "iphone", @@ -10,9 +36,9 @@ { "orientation" : "portrait", "idiom" : "iphone", - "subtype" : "retina4", "extent" : "full-screen", "minimum-system-version" : "7.0", + "subtype" : "retina4", "scale" : "2x" }, { diff --git a/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/TX6sV.png b/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/TX6sV.png new file mode 100644 index 0000000..2f5242b Binary files /dev/null and b/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/TX6sV.png differ diff --git a/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/dBEHd.png b/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/dBEHd.png new file mode 100644 index 0000000..8f82b77 Binary files /dev/null and b/ExampleApp/ExampleApp/Images.xcassets/LaunchImage.launchimage/dBEHd.png differ diff --git a/ExampleApp/ExampleAppTests/ExampleAppTests-Info.plist b/ExampleApp/ExampleAppTests/ExampleAppTests-Info.plist index 12b70c6..169b6f7 100644 --- a/ExampleApp/ExampleAppTests/ExampleAppTests-Info.plist +++ b/ExampleApp/ExampleAppTests/ExampleAppTests-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - abstractpath.com.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/StreamingKit/StreamingKit.xcodeproj/project.pbxproj b/StreamingKit/StreamingKit.xcodeproj/project.pbxproj index 5f8109d..e013273 100644 --- a/StreamingKit/StreamingKit.xcodeproj/project.pbxproj +++ b/StreamingKit/StreamingKit.xcodeproj/project.pbxproj @@ -425,7 +425,7 @@ isa = PBXProject; attributes = { CLASSPREFIX = STK; - LastUpgradeCheck = 0610; + LastUpgradeCheck = 0710; ORGANIZATIONNAME = "Thong Nguyen"; }; buildConfigurationList = A1E7C4C3188D57F50010896F /* Build configuration list for PBXProject "StreamingKit" */; @@ -633,6 +633,7 @@ ); INFOPLIST_FILE = "StreamingKitMacTests/StreamingKitMacTests-Info.plist"; MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_BUNDLE_IDENTIFIER = "com.abstractpath.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; WRAPPER_EXTENSION = xctest; @@ -653,6 +654,7 @@ GCC_PREFIX_HEADER = "StreamingKitMac/StreamingKitMac-Prefix.pch"; INFOPLIST_FILE = "StreamingKitMacTests/StreamingKitMacTests-Info.plist"; MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_BUNDLE_IDENTIFIER = "com.abstractpath.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; WRAPPER_EXTENSION = xctest; @@ -676,6 +678,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -776,6 +779,7 @@ "$(inherited)", ); INFOPLIST_FILE = "StreamingKitTests/StreamingKitTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "abstractpath.com.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = xctest; }; @@ -792,6 +796,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "StreamingKit/StreamingKit-Prefix.pch"; INFOPLIST_FILE = "StreamingKitTests/StreamingKitTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "abstractpath.com.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = xctest; }; diff --git a/StreamingKit/StreamingKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/StreamingKit/StreamingKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/StreamingKit/StreamingKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.h b/StreamingKit/StreamingKit/STKAudioPlayer.h index 0ce6d53..e4dd707 100644 --- a/StreamingKit/StreamingKit/STKAudioPlayer.h +++ b/StreamingKit/StreamingKit/STKAudioPlayer.h @@ -80,6 +80,11 @@ typedef enum } STKAudioPlayerErrorCode; +/// +/// Options to initiailise the Audioplayer with. +/// By default if you set buffer size or seconds to 0, the non-zero default will be used +/// If you would like to disable the buffer option completely set to STK_DISABLE_BUFFER +/// typedef struct { /// If YES then seeking a track will cause all pending items to be flushed from the queue @@ -91,7 +96,7 @@ typedef struct /// The size of the internal I/O read buffer. This data in this buffer is transient and does not need to be larger. UInt32 readBufferSize; /// The size of the decompressed buffer (Default is 10 seconds which uses about 1.7MB of RAM) - UInt32 bufferSizeInSeconds; + Float32 bufferSizeInSeconds; /// Number of seconds of decompressed audio is required before playback first starts for each item (Default is 0.5 seconds. Must be larger than bufferSizeInSeconds) Float32 secondsRequiredToStartPlaying; /// Seconds after a seek is performed before data needs to come in (after which the state will change to playing/buffering) @@ -101,6 +106,8 @@ typedef struct } STKAudioPlayerOptions; +#define STK_DISABLE_BUFFER (0xffffffff) + typedef void(^STKFrameFilter)(UInt32 channelsPerFrame, UInt32 bytesPerFrame, UInt32 frameCount, void* frames); @interface STKFrameFilterEntry : NSObject diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.m b/StreamingKit/StreamingKit/STKAudioPlayer.m index c5fa73b..cb15d47 100755 --- a/StreamingKit/StreamingKit/STKAudioPlayer.m +++ b/StreamingKit/StreamingKit/STKAudioPlayer.m @@ -96,6 +96,34 @@ static void PopulateOptionsWithDefault(STKAudioPlayerOptions* options) } } +static void NormalizeDisabledBuffers(STKAudioPlayerOptions* options) +{ + if (options->bufferSizeInSeconds == STK_DISABLE_BUFFER) + { + options->bufferSizeInSeconds = 0; + } + + if (options->readBufferSize == STK_DISABLE_BUFFER) + { + options->readBufferSize = 0; + } + + if (options->secondsRequiredToStartPlaying == STK_DISABLE_BUFFER) + { + options->secondsRequiredToStartPlaying = 0; + } + + if (options->secondsRequiredToStartPlayingAfterBufferUnderun == STK_DISABLE_BUFFER) + { + options->secondsRequiredToStartPlayingAfterBufferUnderun = 0; + } + + if (options->gracePeriodAfterSeekInSeconds == STK_DISABLE_BUFFER) + { + options->gracePeriodAfterSeekInSeconds = 0; + } +} + #define CHECK_STATUS_AND_REPORT(call) \ if ((status = (call))) \ { \ @@ -491,6 +519,7 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn self->equalizerEnabled = optionsIn.equalizerBandFrequencies[0] != 0; PopulateOptionsWithDefault(&options); + NormalizeDisabledBuffers(&options); framesRequiredToStartPlaying = canonicalAudioStreamBasicDescription.mSampleRate * options.secondsRequiredToStartPlaying; framesRequiredToPlayAfterRebuffering = canonicalAudioStreamBasicDescription.mSampleRate * options.secondsRequiredToStartPlayingAfterBufferUnderun; @@ -877,7 +906,7 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn } case kAudioFileStreamProperty_ReadyToProducePackets: { - if (!audioConverterAudioStreamBasicDescription.mFormatID == kAudioFormatLinearPCM) + if (audioConverterAudioStreamBasicDescription.mFormatID != kAudioFormatLinearPCM) { discontinuous = YES; } diff --git a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m index 37fa5e5..445d44d 100644 --- a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m +++ b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m @@ -101,6 +101,8 @@ static void PopulateOptionsWithDefault(STKAutoRecoveringHTTPDataSourceOptions* o @implementation STKAutoRecoveringHTTPDataSource +@dynamic innerDataSource; + -(STKHTTPDataSource*) innerHTTPDataSource { return (STKHTTPDataSource*)self.innerDataSource; diff --git a/StreamingKit/StreamingKitMacTests/StreamingKitMacTests-Info.plist b/StreamingKit/StreamingKitMacTests/StreamingKitMacTests-Info.plist index 552d5b1..169b6f7 100644 --- a/StreamingKit/StreamingKitMacTests/StreamingKitMacTests-Info.plist +++ b/StreamingKit/StreamingKitMacTests/StreamingKitMacTests-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.abstractpath.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/StreamingKit/StreamingKitTests/StreamingKitTests-Info.plist b/StreamingKit/StreamingKitTests/StreamingKitTests-Info.plist index 12b70c6..169b6f7 100644 --- a/StreamingKit/StreamingKitTests/StreamingKitTests-Info.plist +++ b/StreamingKit/StreamingKitTests/StreamingKitTests-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - abstractpath.com.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType