Skip to content

Commit

Permalink
manual merge of objc commenting and formatting updates
Browse files Browse the repository at this point in the history
  • Loading branch information
danomatika committed Feb 25, 2018
1 parent c2db3e3 commit ab92eb4
Show file tree
Hide file tree
Showing 12 changed files with 393 additions and 239 deletions.
20 changes: 12 additions & 8 deletions objc/AudioHelpers.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// AudioDebug.h
// AudioHelpers.h
// libpd
//
// Created on 18/10/11.
Expand All @@ -12,41 +12,42 @@

#pragma mark - Audio Unit / Audio Session Debugging

/// uncomment this to log more information from the audio classes, or define it in "Other C Flags" build settings
/// Uncomment this to log more information from the audio classes
/// or define it in "Other C Flags" build settings.
//#define AU_DEBUG_VERBOSE

/// returns the name of the const value associated with the OSStatus as a string
/// Returns name of the const value associated with the OSStatus as a string.
extern NSString *AVStatusCodeAsString(OSStatus status);
extern NSString *AUStatusCodeAsString(OSStatus status);

/// log debug info along with the class, function and line number
/// Log debug info along with the class, function and line number.
#define AU_LOG(nslog_string, ...) do {\
NSLog((@"%s[%d] " nslog_string), __func__, __LINE__, ##__VA_ARGS__);\
} while (0)

/// same as AU_Log, but only logs if AU_DEBUG_VERBOSE is defined
/// Same as AU_LOG, but only logs if AU_DEBUG_VERBOSE is defined.
#if defined(AU_DEBUG_VERBOSE)
#define AU_LOGV(nslog_string, ...) AU_LOG(nslog_string, ##__VA_ARGS__)
#else
#define AU_LOGV(nslog_string, ...)
#endif

/// a debug check, which will only log if the value is non-zero
/// A debug check, which will only log if the value is non-zero.
#define AU_LOG_IF_ERROR(value, nslog_string, ...) do {\
if(value) {\
NSLog((@"*** ERROR *** %s[%d] " nslog_string), __func__, __LINE__, ##__VA_ARGS__);\
}\
} while (0)

/// check if the audio unit had an error, and if so print it and return
/// Check if the audio unit had an error, and if so print it and return.
#define AU_RETURN_IF_ERROR(status) do {\
if(status) {\
NSLog(@"*** ERROR *** %s[%d] status code = %@", __func__, __LINE__, AUStatusCodeAsString(status));\
return;\
}\
} while (0)

/// check if the audio unit had an error, and if so print it and return false
/// Check if the audio unit had an error, and if so print it and return false.
#define AU_RETURN_FALSE_IF_ERROR(status) do {\
if(status) {\
NSLog(@"*** ERROR *** %s[%d] status code = %@", __func__, __LINE__, AUStatusCodeAsString(status));\
Expand All @@ -56,5 +57,8 @@ return false;\

#pragma mark - Math Helpers

/// Returns YES if floats are equal within 0.0001.
extern BOOL floatsAreEqual(Float64 f1, Float64 f2);

/// log shift calculation
extern int log2int(int x);
2 changes: 1 addition & 1 deletion objc/AudioHelpers.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// AudioDebug.m
// AudioHelpers.m
// libpd
//
// Created on 18/10/11.
Expand Down
56 changes: 34 additions & 22 deletions objc/PdAudioController.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@
#import <AVFoundation/AVFoundation.h>
#import "PdAudioUnit.h"

/// PdAudioStatus is used to indicate success, failure, or that parameters had
/// to be adjusted in order to work.
typedef enum PdAudioStatus {
PdAudioOK = 0, // success
PdAudioError = -1, // unrecoverable error
PdAudioPropertyChanged = 1 // some properties have changed to run correctly (not fatal)
PdAudioOK = 0, // success
PdAudioError = -1, // unrecoverable error
PdAudioPropertyChanged = 1 // some properties have changed to run correctly
} PdAudioStatus;

/// PdAudioController: A class for managing PdAudioUnit within iOS
/// by using the AVFoundation and Audio Services APIs.
/// Handles phone interruptions and provides high level configuration methods
/// The returned PdAudioStatus is used to indicate success, failure, or
/// that parameters had to be adjusted in order to work.
///
/// PdAudioController: A class for managing a PdAudioUnit instance within iOS
/// by using the AVFoundation and Audio Services APIs. Handles phone
/// interruptions and provides high level configuration methods.
@interface PdAudioController : NSObject

/// Read only properties that are set by the configure methods
Expand All @@ -39,30 +38,43 @@ typedef enum PdAudioStatus {
/// Check or set the active status of the audio unit
@property (nonatomic, getter=isActive) BOOL active;

/// Init with a custom pd audio unit. Derive PdAudioUnit when you need to access
/// to the raw samples when using, for instance, AudioBus, and call this method after init.
/// Init with a custom pd audio unit.
///
/// Derive PdAudioUnit when you need to access to the raw samples when using,
/// for instance, AudioBus, and call this method after init.
- (instancetype)initWithAudioUnit:(PdAudioUnit *)audioUnit;

/// Configure the audio with the specified samplerate, as well as number of output channels (which will also be the number of
/// input channels if input is enable). Note that this method has three possible outcomes: success, failure, or conditional
/// success, where parameters had to be adjusted to set up the audio. In the third case, you can query the sample rate and
/// channel properties to determine whether the selected configuration is acceptable. Specifying mixingEnabled = YES will
/// allow the app to continue playing audio along with other apps (such as Music).
/// Configure the audio with the specified samplerate, as well as number of
/// output channels (which will also be the number of input channels if input is
/// enabled).
///
/// Note that this method has three possible outcomes: success, failure, or
/// conditional success, where parameters had to be adjusted to set up the
/// audio. In the third case, you can query the sample rate and channel
/// properties to determine whether the selected configuration is acceptable.
///
/// Specifying mixingEnabled = YES will allow the app to continue playing audio
/// along with other apps (such as Music).
- (PdAudioStatus)configurePlaybackWithSampleRate:(int)sampleRate
numberChannels:(int)numChannels
inputEnabled:(BOOL)inputEnabled
mixingEnabled:(BOOL)mixingEnabled;

/// Configure audio for ambient use, without input channels. Specifying mixingEnabled = YES will allow the app to continue
/// playing audio along with other apps (such as iPod music player).
/// Configure audio for ambient use, without input channels.
///
/// Specifying mixingEnabled = YES will allow the app to continue playing audio
/// along with other apps (such as iPod music player).
- (PdAudioStatus)configureAmbientWithSampleRate:(int)sampleRate
numberChannels:(int)numChannels
mixingEnabled:(BOOL)mixingEnabled;

/// Configure the ticksPerBuffer parameter, which will change the audio sessions IO buffer size.
/// This can be done on the fly, while audio is running. Note that the audio session only accepts
/// values that correspond to a number of frames that are a power of 2 and sometimes this value
/// is ignored by the audio unit, which tries to work with whatever number of frames it is provided.
/// Configure the ticksPerBuffer parameter, which will change the audio session
/// IO buffer size. This can be done on the fly, while audio is running.
///
/// Note that the audio session only accepts values that correspond to a number
/// of frames that are a power of 2 and sometimes this value is ignored by the
/// audio unit, which tries to work with whatever number of frames it is
/// provided.
- (PdAudioStatus)configureTicksPerBuffer:(int)ticksPerBuffer;

/// Print current settings to the console.
Expand Down
24 changes: 13 additions & 11 deletions objc/PdAudioController.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ @interface PdAudioController ()

@property (nonatomic, strong, readwrite) PdAudioUnit *audioUnit;

// updates the sample rate while verifying it is in sync with the audio session and PdAudioUnit
// Update the sample rate while verifying it is in
// sync with the audio session and PdAudioUnit.
- (PdAudioStatus)updateSampleRate:(int)sampleRate;

// not all inputs make sense, but that's okay in the private interface
- (PdAudioStatus)selectCategoryWithInputs:(BOOL)hasInputs isAmbient:(BOOL)isAmbient allowsMixing:(BOOL)allowsMixing;
- (PdAudioStatus)configureAudioUnitWithNumberChannels:(int)numChannels inputEnabled:(BOOL)inputEnabled;
// Not all inputs make sense, but that's okay in the private interface.
- (PdAudioStatus)selectCategoryWithInputs:(BOOL)hasInputs
isAmbient:(BOOL)isAmbient
allowsMixing:(BOOL)allowsMixing;
- (PdAudioStatus)configureAudioUnitWithNumberChannels:(int)numChannels
inputEnabled:(BOOL)inputEnabled;

@end

Expand Down Expand Up @@ -170,13 +174,11 @@ - (PdAudioStatus)selectCategoryWithInputs:(BOOL)hasInputs isAmbient:(BOOL)isAmbi
return PdAudioOK;
}

/* note about the magic 0.5 added to numberFrames:
* apple is doing some horrible rounding of the bufferDuration into
* what tries to give a power of two frames to the audio unit, which
* is inconsistent accross different devices. As they are currently
* truncating, we add in this value to make sure the resulting ticks
* value is not halved.
*/
// Note about the magic 0.5 added to numberFrames:
// Apple is doing some horrible rounding of the bufferDuration into what tries
// to give a power of two frames to the audio unit, which is inconsistent across
// different devices. As they are currently truncating, we add in this value to
// make sure the resulting ticks value is not halved.
- (PdAudioStatus)configureTicksPerBuffer:(int)ticksPerBuffer {
int numberFrames = [PdBase getBlockSize] * ticksPerBuffer;
NSTimeInterval bufferDuration = (Float32) (numberFrames + 0.5) / self.sampleRate;
Expand Down
39 changes: 25 additions & 14 deletions objc/PdAudioUnit.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
a//
// PdAudioUnit.h
// libpd
//
Expand All @@ -17,14 +17,21 @@
/// which will cause the underlying audio unit to be reconstructed.
///
/// For debugging, AU_DEBUG_VERBOSE can be defined to print extra information.
///
@interface PdAudioUnit : NSObject
@interface PdAudioUnit : NSObject {
@protected
AudioUnit _audioUnit; ///< the underlying audio unit instance
BOOL _inputEnabled; ///< is audio input enabled?
BOOL _initialized; ///< has the audio unit been successfully inited?
int _blockSizeAsLog; ///< log(blockSize) for fast bitshift division
}

/// A reference to the audio unit, which can be used to query or set other properties
/// A reference to the audio unit which can be used to query or set other
/// properties.
@property (nonatomic, readonly) AudioUnit audioUnit;

/// A reference to the audio unit callback function. Override the getter method if you
/// want to subclass PdAudioUnit and implement your own custom sample rendering:
/// A reference to the audio unit callback function. Override the getter method
/// if you want to subclass PdAudioUnit and implement your own custom sample
/// rendering.
///
/// In your custom PdAudioUnit subclass .m:
///
Expand All @@ -35,7 +42,7 @@
/// UInt32 inBusNumber,
/// UInt32 inNumberFrames,
/// AudioBufferList *ioData) {
/// // do something with the samples, see AudioRenderCallback in PdAudioUnit.m
/// // do something with the samples, see PdAudioUnit.m AudioRenderCallback
/// return noErr;
/// }
///
Expand All @@ -46,20 +53,24 @@
///
@property (nonatomic, readonly) AURenderCallback renderCallback;

/// Check or set the active status of the audio unit
/// Check or set the active status of the audio unit.
@property (nonatomic, getter=isActive) BOOL active;

/// The configure method sets all parameters of the audio unit that may require it to be
/// recreated at the same time. This is an expensive process and will stop the audio unit
/// before any reconstruction, causing a momentary pause in audio and UI if
/// run from the main thread. Returns zero on success.
- (int)configureWithSampleRate:(Float64)sampleRate numberChannels:(int)numChannels inputEnabled:(BOOL)inputEnabled;
/// The configure method sets all parameters of the audio unit that may require
/// it to be recreated at the same time. This is an expensive process and will
/// stop the audio unit before any reconstruction, causing a momentary pause in
/// audio and UI if run from the main thread.
/// Returns zero on success.
- (int)configureWithSampleRate:(Float64)sampleRate
numberChannels:(int)numChannels
inputEnabled:(BOOL)inputEnabled;

/// Print info on the audio unit settings to the console
- (void)print;

/// Called by configureWithSampleRate when setting up the internal audio unit.
/// Default format: 32 bit, floating point, linear PCM, interleaved
- (AudioStreamBasicDescription)ASBDForSampleRate:(Float64)sampleRate numberChannels:(UInt32)numChannels;
- (AudioStreamBasicDescription)ASBDForSampleRate:(Float64)sampleRate
numberChannels:(UInt32)numChannels;

@end
15 changes: 5 additions & 10 deletions objc/PdAudioUnit.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,17 @@
static const AudioUnitElement kInputElement = 1;
static const AudioUnitElement kOutputElement = 0;

@interface PdAudioUnit () {
@private
BOOL _inputEnabled;
BOOL _initialized;
int _blockSizeAsLog;
}

- (BOOL)initAudioUnitWithSampleRate:(Float64)sampleRate numberChannels:(int)numChannels inputEnabled:(BOOL)inputEnabled;
@interface PdAudioUnit () {}
- (BOOL)initAudioUnitWithSampleRate:(Float64)sampleRate
numberChannels:(int)numChannels
inputEnabled:(BOOL)inputEnabled;
- (void)destroyAudioUnit;
- (AudioComponentDescription)ioDescription;
@end

@implementation PdAudioUnit

//@synthesize audioUnit = audioUnit_;
//@synthesize active = active_;
@synthesize audioUnit = audioUnit_;

#pragma mark - Init / Dealloc

Expand Down
Loading

0 comments on commit ab92eb4

Please sign in to comment.