Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 34dc468f16 | |||
| 3bb1b914a2 | |||
| 6d00378ab0 | |||
| ac07210263 | |||
| 5920e7a61e | |||
| 4ef91004ea | |||
| 1c6213c9c6 | |||
| 59bd612164 | |||
| b89b2254f0 | |||
| 086ce50a54 | |||
| 6684a874aa | |||
| 0c7226b3b0 | |||
| 9516768b1c | |||
| cf9dafc961 | |||
| a74b1cf612 | |||
| 1e7975e6cc | |||
| cdd1372e30 | |||
| 9f9c352f43 | |||
| 9aab703069 | |||
| 3706a21e83 | |||
| effa122525 | |||
| 825e22e135 | |||
| 33c9ca84a2 | |||
| 1a74a7def5 | |||
| dcaadd43ce | |||
| 03db74e842 | |||
| ec19d44d86 | |||
| 1e23f95dc2 | |||
| 4d0b40d730 | |||
| 732cf79963 | |||
| 7e84f8744f | |||
| 556ac8390a | |||
| 700bd4bbce | |||
| 7df85ed2b8 | |||
| 68ad54d824 | |||
| 4f31db3d0e | |||
| c6ed4c48b6 | |||
| d65c918f00 | |||
| e771fe257a | |||
| 7fc587d3af | |||
| 7bcf2517cb | |||
| 47de71d817 | |||
| cdee3dadd5 | |||
| 4b76949836 | |||
| 55172b2356 | |||
| 302a047f6a | |||
| 2705a7b559 | |||
| e620db225a | |||
| 6f51b2b387 | |||
| a8202b44ad | |||
| ddfe22106f | |||
| 64a9e963ee | |||
| 2309329709 | |||
| bb19920533 | |||
| 44429ec91a | |||
| 3936165aeb | |||
| 996744ffc4 | |||
| 3ae090c761 | |||
| 33bdcee78a | |||
| 081c7047f5 | |||
| 4d952e2fa5 | |||
| f2084dab2a | |||
| 115dc2b8a0 | |||
| a832f27a5a | |||
| 199f63d7e2 | |||
| f5f40304d0 | |||
| 6ea04c0f7b |
+26
-17
@@ -1,18 +1,27 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "EZAudio"
|
||||
s.version = "0.4.0"
|
||||
s.summary = "A simple, intuitive audio framework for iOS and OSX useful for anyone doing audio processing and/or audio-based visualizations."
|
||||
s.homepage = "https://github.com/syedhali/EZAudio"
|
||||
s.screenshots = "https://s3-us-west-1.amazonaws.com/ezaudio-media/EZAudioSummary.png"
|
||||
s.license = { :type => 'MIT', :file => 'LICENSE' }
|
||||
s.author = { "Syed Haris Ali" => "syedhali07@gmail.com" }
|
||||
s.ios.deployment_target = '6.0'
|
||||
s.osx.deployment_target = '10.8'
|
||||
s.source = { :git => "https://github.com/syedhali/EZAudio.git", :tag => s.version }
|
||||
s.source_files = 'EZAudio/*.{h,m,c}'
|
||||
s.exclude_files = [ 'EZAudio/VERSION', 'EZAudio/TPCircularBuffer.{h,c}' ]
|
||||
s.ios.frameworks = 'AudioToolbox','AVFoundation','GLKit'
|
||||
s.osx.frameworks = 'AudioToolbox','AudioUnit','CoreAudio','QuartzCore','OpenGL','GLKit'
|
||||
s.dependency 'TPCircularBuffer', '~> 0.0'
|
||||
s.requires_arc = true;
|
||||
end
|
||||
s.name = "EZAudio"
|
||||
s.version = "0.9.1"
|
||||
s.summary = "A simple, intuitive audio framework for iOS and OSX useful for anyone doing audio processing and/or audio-based visualizations."
|
||||
s.homepage = "https://github.com/syedhali/EZAudio"
|
||||
s.screenshots = "https://s3-us-west-1.amazonaws.com/ezaudio-media/EZAudioSummary.png"
|
||||
s.license = { :type => 'MIT', :file => 'LICENSE' }
|
||||
s.author = { "Syed Haris Ali" => "syedhali07@gmail.com" }
|
||||
s.ios.deployment_target = '6.0'
|
||||
s.osx.deployment_target = '10.8'
|
||||
s.source = { :git => "https://github.com/syedhali/EZAudio.git", :tag => s.version }
|
||||
s.exclude_files = [ 'EZAudio/VERSION', 'EZAudio/TPCircularBuffer.{h,c}' ]
|
||||
s.ios.frameworks = 'AudioToolbox','AVFoundation','GLKit'
|
||||
s.osx.frameworks = 'AudioToolbox','AudioUnit','CoreAudio','QuartzCore','OpenGL','GLKit'
|
||||
s.requires_arc = true;
|
||||
s.default_subspec = 'Full'
|
||||
|
||||
s.subspec 'Core' do |core|
|
||||
core.source_files = 'EZAudio/*.{h,m,c}'
|
||||
end
|
||||
|
||||
s.subspec 'Full' do |full|
|
||||
full.dependency 'TPCircularBuffer', '~> 0.0'
|
||||
full.dependency 'EZAudio/Core'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
+16
-8
@@ -25,25 +25,33 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#pragma mark - 3rd Party Utilties
|
||||
#import "TPCircularBuffer.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Core Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#import "EZAudioDevice.h"
|
||||
#import "EZAudioFile.h"
|
||||
#import "EZAudioFloatData.h"
|
||||
#import "EZMicrophone.h"
|
||||
#import "EZOutput.h"
|
||||
#import "EZRecorder.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
#pragma mark - Extended Components
|
||||
#import "EZAudioPlayer.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Interface Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#import "EZPlot.h"
|
||||
#import "EZAudioDisplayLink.h"
|
||||
#import "EZAudioPlot.h"
|
||||
#import "EZAudioPlotGL.h"
|
||||
#import "EZAudioPlotGLKViewController.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Utility Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#import "EZAudioFloatConverter.h"
|
||||
#import "EZAudioFloatData.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
+16
-14
@@ -27,6 +27,22 @@
|
||||
// @name Getting The Devices
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current EZAudioDevice that is being used to pull input.
|
||||
@return An EZAudioDevice instance representing the currently selected input device.
|
||||
*/
|
||||
+ (EZAudioDevice *)currentInputDevice;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current EZAudioDevice that is being used to output audio.
|
||||
@return An EZAudioDevice instance representing the currently selected ouotput device.
|
||||
*/
|
||||
+ (EZAudioDevice *)currentOutputDevice;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Enumerates all the available input devices and returns the result in an NSArray of EZAudioDevice instances.
|
||||
@return An NSArray containing EZAudioDevice instances, one for each available input device.
|
||||
@@ -43,20 +59,6 @@
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
/**
|
||||
Provides the current EZAudioDevice that is being used to pull input.
|
||||
- iOS only
|
||||
@return An EZAudioDevice instance representing the currently selected input device.
|
||||
*/
|
||||
+ (EZAudioDevice *)currentInputDevice;
|
||||
|
||||
/**
|
||||
Provides the current EZAudioDevice that is being used to output audio.
|
||||
- iOS only
|
||||
@return An EZAudioDevice instance representing the currently selected ouotput device.
|
||||
*/
|
||||
+ (EZAudioDevice *)currentOutputDevice;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
+43
-5
@@ -217,11 +217,11 @@
|
||||
AudioObjectPropertyAddress address = [self addressForPropertySelector:kAudioHardwarePropertyDevices];
|
||||
UInt32 devicesDataSize;
|
||||
[EZAudioUtilities checkResult:AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
|
||||
&address,
|
||||
0,
|
||||
NULL,
|
||||
&devicesDataSize)
|
||||
operation:"Failed to get data size"];
|
||||
&address,
|
||||
0,
|
||||
NULL,
|
||||
&devicesDataSize)
|
||||
operation:"Failed to get data size"];
|
||||
|
||||
// enumerate devices
|
||||
NSInteger count = devicesDataSize / sizeof(AudioDeviceID);
|
||||
@@ -271,6 +271,44 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (EZAudioDevice *)deviceWithPropertySelector:(AudioObjectPropertySelector)propertySelector
|
||||
{
|
||||
AudioDeviceID deviceID;
|
||||
UInt32 propSize = sizeof(AudioDeviceID);
|
||||
AudioObjectPropertyAddress address = [self addressForPropertySelector:propertySelector];
|
||||
[EZAudioUtilities checkResult:AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
||||
&address,
|
||||
0,
|
||||
NULL,
|
||||
&propSize,
|
||||
&deviceID)
|
||||
operation:"Failed to get device device on OSX"];
|
||||
EZAudioDevice *device = [[EZAudioDevice alloc] init];
|
||||
device.deviceID = deviceID;
|
||||
device.manufacturer = [self manufacturerForDeviceID:deviceID];
|
||||
device.name = [self namePropertyForDeviceID:deviceID];
|
||||
device.UID = [self UIDPropertyForDeviceID:deviceID];
|
||||
device.inputChannelCount = [self channelCountForScope:kAudioObjectPropertyScopeInput forDeviceID:deviceID];
|
||||
device.outputChannelCount = [self channelCountForScope:kAudioObjectPropertyScopeOutput forDeviceID:deviceID];
|
||||
return device;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (EZAudioDevice *)currentInputDevice
|
||||
{
|
||||
return [self deviceWithPropertySelector:kAudioHardwarePropertyDefaultInputDevice];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (EZAudioDevice *)currentOutputDevice
|
||||
{
|
||||
return [self deviceWithPropertySelector:kAudioHardwarePropertyDefaultOutputDevice];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (NSArray *)inputDevices
|
||||
{
|
||||
__block NSMutableArray *devices = [NSMutableArray array];
|
||||
|
||||
+16
-4
@@ -65,12 +65,23 @@ typedef void (^EZAudioWaveformDataCompletionBlock)(float **waveformData, int len
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Occurs when the audio file's internal seek position has been updated by the EZAudioFile functions `readFrames:audioBufferList:bufferSize:eof:` or `audioFile:updatedPosition:`. As of 0.8.0 this is the preferred method of listening for position updates on the audio file since a user may want the pull the currentTime, formattedCurrentTime, or the frame index from the EZAudioFile instance provided.
|
||||
@param audioFile The instance of the EZAudio in which the change occured.
|
||||
*/
|
||||
- (void)audioFileUpdatedPosition:(EZAudioFile *)audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Occurs when the audio file's internal seek position has been updated by the EZAudioFile functions `readFrames:audioBufferList:bufferSize:eof:` or `audioFile:updatedPosition:`.
|
||||
@param audioFile The instance of the EZAudio in which the change occured
|
||||
@param framePosition The new frame index as a 64-bit signed integer
|
||||
@deprecated This property is deprecated starting in version 0.8.0.
|
||||
@note Please use `audioFileUpdatedPosition:` property instead.
|
||||
*/
|
||||
- (void)audioFile:(EZAudioFile *)audioFile updatedPosition:(SInt64)framePosition;
|
||||
- (void)audioFile:(EZAudioFile *)audioFile
|
||||
updatedPosition:(SInt64)framePosition __attribute__((deprecated));
|
||||
|
||||
@end
|
||||
|
||||
@@ -80,11 +91,12 @@ typedef void (^EZAudioWaveformDataCompletionBlock)(float **waveformData, int len
|
||||
/**
|
||||
The EZAudioFile provides a lightweight and intuitive way to asynchronously interact with audio files. These interactions included reading audio data, seeking within an audio file, getting information about the file, and pulling the waveform data for visualizing the contents of the audio file. The EZAudioFileDelegate provides event callbacks for when reads, seeks, and various updates happen within the audio file to allow the caller to interact with the action in meaningful ways. Common use cases here could be to read the audio file's data as AudioBufferList structures for output (see EZOutput) and visualizing the audio file's data as a float array using an audio plot (see EZAudioPlot).
|
||||
*/
|
||||
@interface EZAudioFile : NSObject
|
||||
@interface EZAudioFile : NSObject <NSCopying>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A EZAudioFileDelegate for the audio file that is used to return events such as new seek positions within the file and the read audio data as a float array.
|
||||
*/
|
||||
@@ -232,7 +244,7 @@ typedef void (^EZAudioWaveformDataCompletionBlock)(float **waveformData, int len
|
||||
*/
|
||||
|
||||
/**
|
||||
Provides the AudioStreamBasicDescription structure used within the app. The file's format will be converted to this format and then sent back as either a float array or a `AudioBufferList` pointer. For instance, the file on disk could be a 22.5 kHz, float format, but we might have an audio processing graph that has a 44.1 kHz, signed integer format that we'd like to interact with. The client format lets us set that 44.1 kHz format on the audio file to properly read samples from it with any interpolation or format conversion that must take place done automatically within the EZAudioFile `readFrames:audioBufferList:bufferSize:eof:` method. Default is stereo, non-interleaved, 44.1 kHz.
|
||||
Provides the common AudioStreamBasicDescription that will be used for in-app interaction. The file's format will be converted to this format and then sent back as either a float array or a `AudioBufferList` pointer. For instance, the file on disk could be a 22.5 kHz, float format, but we might have an audio processing graph that has a 44.1 kHz, signed integer format that we'd like to interact with. The client format lets us set that 44.1 kHz format on the audio file to properly read samples from it with any interpolation or format conversion that must take place done automatically within the EZAudioFile `readFrames:audioBufferList:bufferSize:eof:` method. Default is stereo, non-interleaved, 44.1 kHz.
|
||||
@warning This must be a linear PCM format!
|
||||
@return An AudioStreamBasicDescription structure describing the format of the audio file.
|
||||
*/
|
||||
@@ -299,7 +311,7 @@ typedef void (^EZAudioWaveformDataCompletionBlock)(float **waveformData, int len
|
||||
@note Please use `duration` property instead.
|
||||
@return The total duration of the audio file as a Float32.
|
||||
*/
|
||||
@property (readonly) NSTimeInterval totalDuration __attribute__((deprecated));;
|
||||
@property (readonly) NSTimeInterval totalDuration __attribute__((deprecated));
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
+62
-5
@@ -160,6 +160,15 @@ typedef struct
|
||||
clientFormat:clientFormat];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - NSCopying
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
return [EZAudioFile audioFileWithURL:self.url];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Methods
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -304,11 +313,24 @@ typedef struct
|
||||
*bufferSize = frames;
|
||||
*eof = frames == 0;
|
||||
|
||||
// notify delegate
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(audioFileUpdatedPosition:)])
|
||||
{
|
||||
[self.delegate audioFileUpdatedPosition:self];
|
||||
}
|
||||
|
||||
//
|
||||
// Deprecated, but supported until 1.0
|
||||
//
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
if ([self.delegate respondsToSelector:@selector(audioFile:updatedPosition:)])
|
||||
{
|
||||
[self.delegate audioFile:self updatedPosition:self.frameIndex];
|
||||
[self.delegate audioFile:self updatedPosition:[self frameIndex]];
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(audioFile:readAudio:withBufferSize:withNumberOfChannels:)])
|
||||
{
|
||||
@@ -342,12 +364,24 @@ typedef struct
|
||||
|
||||
pthread_mutex_unlock(&_lock);
|
||||
|
||||
// notify delegate
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(audioFileUpdatedPosition:)])
|
||||
{
|
||||
[self.delegate audioFileUpdatedPosition:self];
|
||||
}
|
||||
|
||||
//
|
||||
// Deprecated, but supported until 1.0
|
||||
//
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
if ([self.delegate respondsToSelector:@selector(audioFile:updatedPosition:)])
|
||||
{
|
||||
[self.delegate audioFile:self
|
||||
updatedPosition:self.frameIndex];
|
||||
[self.delegate audioFile:self updatedPosition:[self frameIndex]];
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -667,6 +701,29 @@ typedef struct
|
||||
[self seekToFrame:frame];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Description
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ {\n"
|
||||
" url: %@,\n"
|
||||
" duration: %f,\n"
|
||||
" totalFrames: %lld,\n"
|
||||
" metadata: %@,\n"
|
||||
" fileFormat: { %@ },\n"
|
||||
" clientFormat: { %@ } \n"
|
||||
"}",
|
||||
[super description],
|
||||
[self url],
|
||||
[self duration],
|
||||
[self totalFrames],
|
||||
[self metadata],
|
||||
[EZAudioUtilities stringForAudioStreamBasicDescription:[self fileFormat]],
|
||||
[EZAudioUtilities stringForAudioStreamBasicDescription:[self clientFormat]]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
+227
-105
@@ -28,41 +28,60 @@
|
||||
#import "EZAudioFile.h"
|
||||
#import "EZOutput.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
|
||||
@class EZAudioPlayer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Notifications
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioPlayerDelegate provides event callbacks for the EZAudioPlayer. These type of events are triggered by changes in the EZAudioPlayer's state and allow someone implementing the EZAudioPlayer to more easily update their user interface. Events are triggered anytime the EZAudioPlayer resumes/pauses playback, reaches the end of the file, reads audio data and converts it to float data visualizations (using the EZAudioFile), and updates its cursor position within the audio file during playback (use this for the play position on a slider on the user interface).
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `audioFile` property. Check the new value using the EZAudioPlayer's `audioFile` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangeAudioFileNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `device` property. Check the new value using the EZAudioPlayer's `device` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangeOutputDeviceNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `output` component's `pan` property. Check the new value using the EZAudioPlayer's `pan` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangePanNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `output` component's play state. Check the new value using the EZAudioPlayer's `isPlaying` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangePlayStateNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `output` component's `volume` property. Check the new value using the EZAudioPlayer's `volume` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangeVolumeNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer has reached the end of a file and its `shouldLoop` property has been set to NO.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidReachEndOfFileNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer performs a seek via the `seekToFrame` method or `setCurrentTime:` property setter. Check the new `currentTime` or `frameIndex` value using the EZAudioPlayer's `currentTime` or `frameIndex` property, respectively.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidSeekNotification;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayerDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioPlayerDelegate provides event callbacks for the EZAudioPlayer. Since 0.5.0 the EZAudioPlayerDelegate provides a smaller set of delegate methods in favor of notifications to allow multiple receivers of the EZAudioPlayer event callbacks since only one player is typically used in an application. Specifically, these methods are provided for high frequency callbacks that wrap the EZAudioPlayer's internal EZAudioFile and EZOutput instances.
|
||||
@warning These callbacks don't necessarily occur on the main thread so make sure you wrap any UI code in a GCD block like: dispatch_async(dispatch_get_main_queue(), ^{ // Update UI });
|
||||
*/
|
||||
@protocol EZAudioPlayerDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
/**
|
||||
Triggered by the EZAudioPlayer when the playback has been resumed or started.
|
||||
@param audioPlayer The instance of the EZAudioPlayer that triggered the event
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
-(void)audioPlayer:(EZAudioPlayer*)audioPlayer didResumePlaybackOnAudioFile:(EZAudioFile*)audioFile;
|
||||
|
||||
/**
|
||||
Triggered by the EZAudioPlayer when the playback has been paused.
|
||||
@param audioPlayer The instance of the EZAudioPlayer that triggered the event
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
-(void)audioPlayer:(EZAudioPlayer*)audioPlayer didPausePlaybackOnAudioFile:(EZAudioFile*)audioFile;
|
||||
|
||||
/**
|
||||
Triggered by the EZAudioPlayer when the output has reached the end of the EZAudioFile it's playing. If the EZAudioPlayer has its `shouldLoop` property set to true this will trigger, but playback will continue to loop once its hit the end of the audio file.
|
||||
@param audioPlayer The instance of the EZAudioPlayer that triggered the event
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
-(void)audioPlayer:(EZAudioPlayer*)audioPlayer reachedEndOfAudioFile:(EZAudioFile*)audioFile;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Triggered by the EZAudioPlayer's internal EZAudioFile's EZAudioFileDelegate callback and notifies the delegate of the read audio data as a float array instead of a buffer list. Common use case of this would be to visualize the float data using an audio plot or audio data dependent OpenGL sketch.
|
||||
@@ -72,11 +91,13 @@
|
||||
@param numberOfChannels The number of channels. 2 for stereo, 1 for mono.
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
-(void) audioPlayer:(EZAudioPlayer*)audioPlayer
|
||||
readAudio:(float**)buffer
|
||||
- (void) audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
playedAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
inAudioFile:(EZAudioFile*)audioFile;;
|
||||
inAudioFile:(EZAudioFile *)audioFile;;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Triggered by EZAudioPlayer's internal EZAudioFile's EZAudioFileDelegate callback and notifies the delegate of the current playback position. The framePosition provides the current frame position and can be calculated against the EZAudioPlayer's total frames using the `totalFrames` function from the EZAudioPlayer.
|
||||
@@ -84,18 +105,36 @@
|
||||
@param framePosition The new frame index as a 64-bit signed integer
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
-(void)audioPlayer:(EZAudioPlayer*)audioPlayer
|
||||
updatedPosition:(SInt64)framePosition
|
||||
inAudioFile:(EZAudioFile*)audioFile;
|
||||
- (void)audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
updatedPosition:(SInt64)framePosition
|
||||
inAudioFile:(EZAudioFile *)audioFile;
|
||||
|
||||
|
||||
/**
|
||||
Triggered by EZAudioPlayer's internal EZAudioFile's EZAudioFileDelegate callback and notifies the delegate that the end of the file has been reached.
|
||||
@param audioPlayer The instance of the EZAudioPlayer that triggered the event
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
- (void)audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
reachedEndOfAudioFile:(EZAudioFile *)audioFile;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
The EZAudioPlayer acts as the master delegate (the EZAudioFileDelegate) over whatever EZAudioFile it is using for playback. Classes that want to get the EZAudioFileDelegate callbacks should implement the EZAudioPlayer's EZAudioPlayerDelegate on the EZAudioPlayer instance.
|
||||
*/
|
||||
@interface EZAudioPlayer : NSObject
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayer
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioPlayer provides an interface that combines the EZAudioFile and EZOutput to play local audio files. This class acts as the master delegate (the EZAudioFileDelegate) over whatever EZAudioFile instance, the `audioFile` property, it is using for playback as well as the EZOutputDelegate and EZOutputDataSource over whatever EZOutput instance is set as the `output`. Classes that want to get the EZAudioFileDelegate callbacks should implement the EZAudioPlayer's EZAudioPlayerDelegate on the EZAudioPlayer instance. Since 0.5.0 the EZAudioPlayer offers notifications over the usual delegate methods to allow multiple receivers to get the EZAudioPlayer's state changes since one player will typically be used in one application. The EZAudioPlayerDelegate, the `delegate`, provides callbacks for high frequency methods that simply wrap the EZAudioFileDelegate and EZOutputDelegate callbacks for providing the audio buffer played as well as the position updating (you will typically have one scrub bar in an application).
|
||||
*/
|
||||
@interface EZAudioPlayer : NSObject <EZAudioFileDelegate,
|
||||
EZOutputDataSource,
|
||||
EZOutputDelegate>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Properties
|
||||
///-----------------------------------------------------------
|
||||
@@ -103,14 +142,19 @@
|
||||
/**
|
||||
The EZAudioPlayerDelegate that will handle the audio player callbacks
|
||||
*/
|
||||
@property (nonatomic,assign) id<EZAudioPlayerDelegate> audioPlayerDelegate;
|
||||
@property (nonatomic, weak) id<EZAudioPlayerDelegate> delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A BOOL indicating whether the player should loop the file
|
||||
*/
|
||||
@property (nonatomic,assign) BOOL shouldLoop;
|
||||
@property (nonatomic, assign) BOOL shouldLoop;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Initializers
|
||||
///-----------------------------------------------------------
|
||||
@@ -120,72 +164,114 @@
|
||||
@param audioFile The instance of the EZAudioFile to use for initializing the EZAudioPlayer
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
-(EZAudioPlayer*)initWithEZAudioFile:(EZAudioFile*)audioFile;
|
||||
- (instancetype)initWithAudioFile:(EZAudioFile *)audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes the EZAudioPlayer with an EZAudioFile instance and provides a way to assign the EZAudioPlayerDelegate on instantiation. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
@param audioFile The instance of the EZAudioFile to use for initializing the EZAudioPlayer
|
||||
@param audioPlayerDelegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithEZAudioFile: function instead.
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithAudioFile: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
-(EZAudioPlayer*)initWithEZAudioFile:(EZAudioFile*)audioFile
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate;
|
||||
- (instancetype)initWithAudioFile:(EZAudioFile *)audioFile
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes the EZAudioPlayer with an EZAudioPlayerDelegate.
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithAudioFile: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
- (instancetype)initWithDelegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes the EZAudioPlayer with an NSURL instance representing the file path of the audio file.
|
||||
@param url The NSURL instance representing the file path of the audio file.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
-(EZAudioPlayer*)initWithURL:(NSURL*)url;
|
||||
- (instancetype)initWithURL:(NSURL*)url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes the EZAudioPlayer with an NSURL instance representing the file path of the audio file and a caller to assign as the EZAudioPlayerDelegate on instantiation.
|
||||
@param url The NSURL instance representing the file path of the audio file.
|
||||
@param audioPlayerDelegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithEZAudioFile: function instead.
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithAudioFile: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
-(EZAudioPlayer*)initWithURL:(NSURL*)url
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate;
|
||||
|
||||
- (instancetype)initWithURL:(NSURL*)url
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class initializer that initializes the EZAudioPlayer with an EZAudioFile instance. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
Class initializer that creates a default EZAudioPlayer.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+ (instancetype)audioPlayer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class initializer that creates the EZAudioPlayer with an EZAudioFile instance. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
@param audioFile The instance of the EZAudioFile to use for initializing the EZAudioPlayer
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+(EZAudioPlayer*)audioPlayerWithEZAudioFile:(EZAudioFile*)audioFile;
|
||||
+ (instancetype)audioPlayerWithAudioFile:(EZAudioFile *)audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class initializer that initializes the EZAudioPlayer with an EZAudioFile instance and provides a way to assign the EZAudioPlayerDelegate on instantiation. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
Class initializer that creates the EZAudioPlayer with an EZAudioFile instance and provides a way to assign the EZAudioPlayerDelegate on instantiation. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
@param audioFile The instance of the EZAudioFile to use for initializing the EZAudioPlayer
|
||||
@param audioPlayerDelegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the audioPlayerWithEZAudioFile: function instead.
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the audioPlayerWithAudioFile: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+(EZAudioPlayer*)audioPlayerWithEZAudioFile:(EZAudioFile*)audioFile
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate;
|
||||
+ (instancetype)audioPlayerWithAudioFile:(EZAudioFile *)audioFile
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class initializer that initializes the EZAudioPlayer with an NSURL instance representing the file path of the audio file.
|
||||
Class initializer that creates a default EZAudioPlayer with an EZAudioPlayerDelegate..
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+ (instancetype)audioPlayerWithDelegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class initializer that creates the EZAudioPlayer with an NSURL instance representing the file path of the audio file.
|
||||
@param url The NSURL instance representing the file path of the audio file.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+(EZAudioPlayer*)audioPlayerWithURL:(NSURL*)url;
|
||||
+ (instancetype)audioPlayerWithURL:(NSURL*)url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class initializer that initializes the EZAudioPlayer with an NSURL instance representing the file path of the audio file and a caller to assign as the EZAudioPlayerDelegate on instantiation.
|
||||
Class initializer that creates the EZAudioPlayer with an NSURL instance representing the file path of the audio file and a caller to assign as the EZAudioPlayerDelegate on instantiation.
|
||||
@param url The NSURL instance representing the file path of the audio file.
|
||||
@param audioPlayerDelegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the audioPlayerWithURL: function instead.
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the audioPlayerWithURL: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+(EZAudioPlayer*)audioPlayerWithURL:(NSURL*)url
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate;
|
||||
+ (instancetype)audioPlayerWithURL:(NSURL*)url
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Singleton
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Shared Instance
|
||||
///-----------------------------------------------------------
|
||||
@@ -194,108 +280,144 @@
|
||||
The shared instance (singleton) of the audio player. Most applications will only have one instance of the EZAudioPlayer that can be reused with multiple different audio files.
|
||||
* @return The shared instance of the EZAudioPlayer.
|
||||
*/
|
||||
+(EZAudioPlayer*)sharedAudioPlayer;
|
||||
+ (instancetype)sharedAudioPlayer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - Getters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Getting The Audio Player's Properties
|
||||
/// @name Properties
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the EZAudioFile instance that is being used as the datasource for playback.
|
||||
@return The EZAudioFile instance that is currently being used for playback.
|
||||
Provides the EZAudioFile instance that is being used as the datasource for playback. When set it creates a copy of the EZAudioFile provided for internal use. This does not use the EZAudioFile by reference, but instead creates a copy of the EZAudioFile instance provided.
|
||||
*/
|
||||
-(EZAudioFile*)audioFile;
|
||||
@property (nonatomic, readwrite, copy) EZAudioFile *audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current time (a.k.a. the seek position) in seconds within the audio file that's being used for playback. This can be helpful when displaying the audio player's current time over duration.
|
||||
@return A float representing the current time within the audio file used for playback.
|
||||
Provides the current offset in the audio file as an NSTimeInterval (i.e. in seconds). When setting this it will determine the correct frame offset and perform a `seekToFrame` to the new time offset.
|
||||
@warning Make sure the new current time offset is less than the `duration` or you will receive an invalid seek assertion.
|
||||
*/
|
||||
-(float)currentTime;
|
||||
@property (nonatomic, readwrite) NSTimeInterval currentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides a flag indicating whether the EZAudioPlayer has reached the end of the audio file used for playback.
|
||||
@return A BOOL indicating whether or not the EZAudioPlayer has reached the end of the file it is using for playback.
|
||||
The EZAudioDevice instance that is being used by the `output`. Similarly, setting this just sets the `device` property of the `output`.
|
||||
*/
|
||||
-(BOOL)endOfFile;
|
||||
@property (readwrite) EZAudioDevice *device;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration of the audio file in seconds.
|
||||
*/
|
||||
@property (readonly) NSTimeInterval duration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current time as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedCurrentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedDuration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the EZOutput that is being used to handle the actual playback of the audio data. This property is also settable, but note that the EZAudioPlayer will become the output's EZOutputDataSource and EZOutputDelegate. To listen for the EZOutput's delegate methods your view should implement the EZAudioPlayerDelegate and set itself as the EZAudioPlayer's `delegate`.
|
||||
*/
|
||||
@property (nonatomic, strong, readwrite) EZOutput *output;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the frame index (a.k.a the seek positon) within the audio file being used for playback. This can be helpful when seeking through the audio file.
|
||||
@return An SInt64 representing the current frame index within the audio file used for playback.
|
||||
*/
|
||||
-(SInt64)frameIndex;
|
||||
@property (readonly) SInt64 frameIndex;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides a flag indicating whether the EZAudioPlayer is currently playing back any audio.
|
||||
@return A BOOL indicating whether or not the EZAudioPlayer is performing playback,
|
||||
*/
|
||||
-(BOOL)isPlaying;
|
||||
@property (readonly) BOOL isPlaying;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the EZOutput instance that is being used to provide playback to the system output.
|
||||
@return The EZOutput instance that is currently being used for output playback.
|
||||
Provides the current pan from the audio player's internal `output` component. Setting the pan adjusts the direction of the audio signal from left (0) to right (1). Default is 0.5 (middle).
|
||||
*/
|
||||
-(EZOutput*)output;
|
||||
@property (nonatomic, assign) float pan;
|
||||
|
||||
/**
|
||||
Provides the total duration of the current audio file being used for playback (in seconds).
|
||||
@return A float representing the total duration of the current audio file being used for playback in seconds.
|
||||
*/
|
||||
-(float)totalDuration;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the total amount of frames in the current audio file being used for playback.
|
||||
@return A SInt64 representing the total amount of frames in the current audio file being used for playback.
|
||||
*/
|
||||
-(SInt64)totalFrames;
|
||||
@property (readonly) SInt64 totalFrames;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the file path that's currently being used by the player for playback.
|
||||
@return The NSURL representing the file path of the audio file being used for playback.
|
||||
*/
|
||||
-(NSURL*)url;
|
||||
@property (nonatomic, copy, readonly) NSURL *url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current volume from the audio player's internal `output` component. Setting the volume adjusts the gain of the output between 0 and 1. Default is 1.
|
||||
*/
|
||||
@property (nonatomic, assign) float volume;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - Setters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Setting The File/Output
|
||||
/// @name Controlling Playback
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the EZAudioFile to use for playback. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
@param audioFile The new EZAudioFile instance that should be used for playback
|
||||
Starts playback.
|
||||
*/
|
||||
-(void)setAudioFile:(EZAudioFile*)audioFile;
|
||||
- (void)play;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the EZOutput to route playback. By default this uses the [EZOutput sharedOutput] singleton.
|
||||
@param output The new EZOutput instance that should be used for playback
|
||||
Loads an EZAudioFile and immediately starts playing it.
|
||||
@param audioFile An EZAudioFile to use for immediate playback.
|
||||
*/
|
||||
-(void)setOutput:(EZOutput*)output;
|
||||
- (void)playAudioFile:(EZAudioFile *)audioFile;
|
||||
|
||||
#pragma mark - Methods
|
||||
///-----------------------------------------------------------
|
||||
/// @name Play/Pause/Seeking the Player
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Starts or resumes playback.
|
||||
*/
|
||||
-(void)play;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Pauses playback.
|
||||
*/
|
||||
-(void)pause;
|
||||
- (void)pause;
|
||||
|
||||
/**
|
||||
Stops playback.
|
||||
*/
|
||||
-(void)stop;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Seeks playback to a specified frame within the internal EZAudioFile. This will notify the EZAudioFileDelegate (if specified) with the audioPlayer:updatedPosition:inAudioFile: function.
|
||||
@param frame The new frame position to seek to as a SInt64.
|
||||
*/
|
||||
-(void)seekToFrame:(SInt64)frame;
|
||||
- (void)seekToFrame:(SInt64)frame;
|
||||
|
||||
@end
|
||||
|
||||
+335
-191
@@ -26,259 +26,340 @@
|
||||
#import "EZAudioPlayer.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
@interface EZAudioPlayer () <EZAudioFileDelegate,EZOutputDataSource>
|
||||
{
|
||||
BOOL _eof;
|
||||
}
|
||||
@property (nonatomic,strong,setter=setAudioFile:) EZAudioFile *audioFile;
|
||||
@property (nonatomic,strong,setter=setOutput:) EZOutput *output;
|
||||
@end
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Notifications
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
NSString * const EZAudioPlayerDidChangeAudioFileNotification = @"EZAudioPlayerDidChangeAudioFileNotification";
|
||||
NSString * const EZAudioPlayerDidChangeOutputDeviceNotification = @"EZAudioPlayerDidChangeOutputDeviceNotification";
|
||||
NSString * const EZAudioPlayerDidChangePanNotification = @"EZAudioPlayerDidChangePanNotification";
|
||||
NSString * const EZAudioPlayerDidChangePlayStateNotification = @"EZAudioPlayerDidChangePlayStateNotification";
|
||||
NSString * const EZAudioPlayerDidChangeVolumeNotification = @"EZAudioPlayerDidChangeVolumeNotification";
|
||||
NSString * const EZAudioPlayerDidReachEndOfFileNotification = @"EZAudioPlayerDidReachEndOfFileNotification";
|
||||
NSString * const EZAudioPlayerDidSeekNotification = @"EZAudioPlayerDidSeekNotification";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayer (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation EZAudioPlayer
|
||||
@synthesize audioFile = _audioFile;
|
||||
@synthesize audioPlayerDelegate = _audioPlayerDelegate;
|
||||
@synthesize output = _output;
|
||||
@synthesize shouldLoop = _shouldLoop;
|
||||
|
||||
#pragma mark - Initializers
|
||||
-(id)init {
|
||||
self = [super init];
|
||||
if(self){
|
||||
[self _configureAudioPlayer];
|
||||
}
|
||||
return self;
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Methods
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayer
|
||||
{
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
-(EZAudioPlayer*)initWithEZAudioFile:(EZAudioFile *)audioFile {
|
||||
return [self initWithEZAudioFile:audioFile withDelegate:nil];
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithDelegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithDelegate:delegate];
|
||||
}
|
||||
|
||||
-(EZAudioPlayer *)initWithEZAudioFile:(EZAudioFile *)audioFile
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate {
|
||||
self = [super init];
|
||||
if(self){
|
||||
// This should make a separate reference to the audio file
|
||||
[self _configureAudioPlayer];
|
||||
self.audioFile = audioFile;
|
||||
self.audioPlayerDelegate = audioPlayerDelegate;
|
||||
}
|
||||
return self;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
return [[self alloc] initWithAudioFile:audioFile];
|
||||
}
|
||||
|
||||
-(EZAudioPlayer *)initWithURL:(NSURL *)url {
|
||||
return [self initWithURL:url withDelegate:nil];
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithAudioFile:(EZAudioFile *)audioFile
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithAudioFile:audioFile
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
-(EZAudioPlayer *)initWithURL:(NSURL *)url
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate {
|
||||
self = [super init];
|
||||
if(self){
|
||||
[self _configureAudioPlayer];
|
||||
self.audioFile = [[EZAudioFile alloc] initWithURL:url];
|
||||
self.audioFile.delegate = self;
|
||||
self.audioPlayerDelegate = audioPlayerDelegate;
|
||||
}
|
||||
return self;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithURL:(NSURL *)url
|
||||
{
|
||||
return [[self alloc] initWithURL:url];
|
||||
}
|
||||
|
||||
#pragma mark - Class Initializers
|
||||
+(EZAudioPlayer *)audioPlayerWithEZAudioFile:(EZAudioFile *)audioFile {
|
||||
return [[EZAudioPlayer alloc] initWithEZAudioFile:audioFile];
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithURL:url delegate:delegate];
|
||||
}
|
||||
|
||||
+(EZAudioPlayer *)audioPlayerWithEZAudioFile:(EZAudioFile *)audioFile
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate {
|
||||
return [[EZAudioPlayer alloc] initWithEZAudioFile:audioFile
|
||||
withDelegate:audioPlayerDelegate];
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initialization
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
[self setup];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+(EZAudioPlayer *)audioPlayerWithURL:(NSURL *)url {
|
||||
return [[EZAudioPlayer alloc] initWithURL:url];
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithDelegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
self = [self init];
|
||||
if (self)
|
||||
{
|
||||
self.delegate = delegate;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+(EZAudioPlayer *)audioPlayerWithURL:(NSURL *)url
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate {
|
||||
return [[EZAudioPlayer alloc] initWithURL:url
|
||||
withDelegate:audioPlayerDelegate];
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
return [self initWithAudioFile:audioFile delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithAudioFile:(EZAudioFile *)audioFile
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
self = [self initWithDelegate:delegate];
|
||||
if (self)
|
||||
{
|
||||
self.audioFile = audioFile;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
{
|
||||
return [self initWithURL:url delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
self = [self initWithDelegate:delegate];
|
||||
if (self)
|
||||
{
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:url delegate:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Singleton
|
||||
+(EZAudioPlayer *)sharedAudioPlayer {
|
||||
static EZAudioPlayer *_sharedAudioPlayer = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_sharedAudioPlayer = [[EZAudioPlayer alloc] init];
|
||||
});
|
||||
return _sharedAudioPlayer;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)sharedAudioPlayer
|
||||
{
|
||||
static EZAudioPlayer *player;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^
|
||||
{
|
||||
player = [[self alloc] init];
|
||||
});
|
||||
return player;
|
||||
}
|
||||
|
||||
#pragma mark - Private Configuration
|
||||
-(void)_configureAudioPlayer {
|
||||
|
||||
// Defaults
|
||||
self.output = [EZOutput sharedOutput];
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// Configure the AVSession
|
||||
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
|
||||
NSError *err = NULL;
|
||||
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];
|
||||
if (err){
|
||||
NSLog(@"There was an error creating the audio session");
|
||||
}
|
||||
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:NULL];
|
||||
if (err){
|
||||
NSLog(@"There was an error sending the audio to the speakers");
|
||||
}
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setup
|
||||
{
|
||||
self.output = [EZOutput output];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Getters
|
||||
-(EZAudioFile*)audioFile {
|
||||
return _audioFile;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)currentTime
|
||||
{
|
||||
return [self.audioFile currentTime];
|
||||
}
|
||||
|
||||
-(float)currentTime {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return [EZAudioUtilities MAP:self.audioFile.frameIndex
|
||||
leftMin:0
|
||||
leftMax:self.audioFile.totalFrames
|
||||
rightMin:0
|
||||
rightMax:self.audioFile.duration];
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (EZAudioDevice *)device
|
||||
{
|
||||
return [self.output device];
|
||||
}
|
||||
|
||||
-(BOOL)endOfFile {
|
||||
return _eof;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)duration
|
||||
{
|
||||
return [self.audioFile duration];
|
||||
}
|
||||
|
||||
-(SInt64)frameIndex {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return _audioFile.frameIndex;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedCurrentTime
|
||||
{
|
||||
return [self.audioFile formattedCurrentTime];
|
||||
}
|
||||
|
||||
-(BOOL)isPlaying {
|
||||
return self.output.isPlaying;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedDuration
|
||||
{
|
||||
return [self.audioFile formattedDuration];
|
||||
}
|
||||
|
||||
-(EZOutput*)output {
|
||||
NSAssert(_output,@"No output was found, this should by default be the EZOutput shared instance");
|
||||
return _output;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)frameIndex
|
||||
{
|
||||
return [self.audioFile frameIndex];
|
||||
}
|
||||
|
||||
-(float)totalDuration {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return _audioFile.duration;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (BOOL)isPlaying
|
||||
{
|
||||
return [self.output isPlaying];
|
||||
}
|
||||
|
||||
-(SInt64)totalFrames {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return _audioFile.totalFrames;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float)pan
|
||||
{
|
||||
return [self.output pan];
|
||||
}
|
||||
|
||||
-(NSURL *)url {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return _audioFile.url;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)totalFrames
|
||||
{
|
||||
return [self.audioFile totalFrames];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float)volume
|
||||
{
|
||||
return [self.output volume];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setters
|
||||
-(void)setAudioFile:(EZAudioFile *)audioFile {
|
||||
if (_audioFile){
|
||||
_audioFile.delegate = nil;
|
||||
}
|
||||
_eof = NO;
|
||||
_audioFile = [EZAudioFile audioFileWithURL:audioFile.url];
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
_audioFile = [audioFile copy];
|
||||
_audioFile.delegate = self;
|
||||
NSAssert(_output,@"No output was found, this should by default be the EZOutput shared instance");
|
||||
[_output setInputFormat:self.audioFile.clientFormat];
|
||||
AudioStreamBasicDescription inputFormat = _audioFile.clientFormat;
|
||||
[self.output setInputFormat:inputFormat];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangeAudioFileNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
-(void)setOutput:(EZOutput*)output {
|
||||
_output = output;
|
||||
_output.dataSource = self;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setCurrentTime:(NSTimeInterval)currentTime
|
||||
{
|
||||
[self.audioFile setCurrentTime:currentTime];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidSeekNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
#pragma mark - Methods
|
||||
-(void)play {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
if (_audioFile){
|
||||
[_output startPlayback];
|
||||
if (self.frameIndex != self.totalFrames){
|
||||
_eof = NO;
|
||||
}
|
||||
if (self.audioPlayerDelegate){
|
||||
if ([self.audioPlayerDelegate respondsToSelector:@selector(audioPlayer:didResumePlaybackOnAudioFile:)]){
|
||||
// Notify the delegate we're starting playback
|
||||
[self.audioPlayerDelegate audioPlayer:self didResumePlaybackOnAudioFile:_audioFile];
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setDevice:(EZAudioDevice *)device
|
||||
{
|
||||
[self.output setDevice:device];
|
||||
}
|
||||
|
||||
-(void)pause {
|
||||
NSAssert(self.audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
if (_audioFile){
|
||||
[_output stopPlayback];
|
||||
if (self.audioPlayerDelegate){
|
||||
if ([self.audioPlayerDelegate respondsToSelector:@selector(audioPlayer:didPausePlaybackOnAudioFile:)]){
|
||||
// Notify the delegate we're pausing playback
|
||||
[self.audioPlayerDelegate audioPlayer:self didPausePlaybackOnAudioFile:_audioFile];
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setOutput:(EZOutput *)output
|
||||
{
|
||||
_output = output;
|
||||
_output.dataSource = self;
|
||||
_output.delegate = self;
|
||||
}
|
||||
|
||||
-(void)seekToFrame:(SInt64)frame {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
if (_audioFile){
|
||||
[_audioFile seekToFrame:frame];
|
||||
}
|
||||
if (self.frameIndex != self.totalFrames){
|
||||
_eof = NO;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setPan:(float)pan
|
||||
{
|
||||
[self.output setPan:pan];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangePanNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
-(void)stop {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
if (_audioFile){
|
||||
[_output stopPlayback];
|
||||
[_audioFile seekToFrame:0];
|
||||
_eof = NO;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setVolume:(float)volume
|
||||
{
|
||||
[self.output setVolume:volume];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangeVolumeNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
#pragma mark - EZAudioFileDelegate
|
||||
-(void)audioFile:(EZAudioFile *)audioFile
|
||||
readAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
if (self.audioPlayerDelegate){
|
||||
if ([self.audioPlayerDelegate respondsToSelector:@selector(audioPlayer:readAudio:withBufferSize:withNumberOfChannels:inAudioFile:)]){
|
||||
[self.audioPlayerDelegate audioPlayer:self
|
||||
readAudio:buffer
|
||||
withBufferSize:bufferSize
|
||||
withNumberOfChannels:numberOfChannels
|
||||
inAudioFile:audioFile];
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)play
|
||||
{
|
||||
[self.output startPlayback];
|
||||
}
|
||||
|
||||
-(void)audioFile:(EZAudioFile *)audioFile updatedPosition:(SInt64)framePosition {
|
||||
if (self.audioPlayerDelegate){
|
||||
if ([self.audioPlayerDelegate respondsToSelector:@selector(audioPlayer:updatedPosition:inAudioFile:)]){
|
||||
[self.audioPlayerDelegate audioPlayer:self
|
||||
updatedPosition:framePosition
|
||||
inAudioFile:audioFile];
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)playAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
//
|
||||
// stop playing anything that might currently be playing
|
||||
//
|
||||
[self pause];
|
||||
|
||||
//
|
||||
// set new stream
|
||||
//
|
||||
self.audioFile = audioFile;
|
||||
|
||||
//
|
||||
// begin playback
|
||||
//
|
||||
[self play];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)pause
|
||||
{
|
||||
[self.output stopPlayback];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)seekToFrame:(SInt64)frame
|
||||
{
|
||||
[self.audioFile seekToFrame:frame];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidSeekNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDataSource
|
||||
-(OSStatus) output:(EZOutput *)output
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (OSStatus) output:(EZOutput *)output
|
||||
shouldFillAudioBufferList:(AudioBufferList *)audioBufferList
|
||||
withNumberOfFrames:(UInt32)frames
|
||||
timestamp:(const AudioTimeStamp *)timestamp
|
||||
@@ -286,16 +367,79 @@ withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
if (self.audioFile)
|
||||
{
|
||||
UInt32 bufferSize;
|
||||
BOOL eof;
|
||||
[self.audioFile readFrames:frames
|
||||
audioBufferList:audioBufferList
|
||||
bufferSize:&bufferSize
|
||||
eof:&_eof];
|
||||
if (_eof && self.shouldLoop)
|
||||
eof:&eof];
|
||||
if (eof && [self.delegate respondsToSelector:@selector(audioPlayer:reachedEndOfAudioFile:)])
|
||||
{
|
||||
[self.delegate audioPlayer:self reachedEndOfAudioFile:self.audioFile];
|
||||
}
|
||||
if (eof && self.shouldLoop)
|
||||
{
|
||||
[self seekToFrame:0];
|
||||
}
|
||||
else if (eof)
|
||||
{
|
||||
[self pause];
|
||||
[self seekToFrame:0];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidReachEndOfFileNotification
|
||||
object:self];
|
||||
}
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFileDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioFileUpdatedPosition:(EZAudioFile *)audioFile
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(audioPlayer:updatedPosition:inAudioFile:)])
|
||||
{
|
||||
[self.delegate audioPlayer:self
|
||||
updatedPosition:[audioFile frameIndex]
|
||||
inAudioFile:audioFile];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)output:(EZOutput *)output changedDevice:(EZAudioDevice *)device
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangeOutputDeviceNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)output:(EZOutput *)output changedPlayingState:(BOOL)isPlaying
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangePlayStateNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) output:(EZOutput *)output
|
||||
playedAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(audioPlayer:playedAudio:withBufferSize:withNumberOfChannels:inAudioFile:)])
|
||||
{
|
||||
[self.delegate audioPlayer:self
|
||||
playedAudio:buffer
|
||||
withBufferSize:bufferSize
|
||||
withNumberOfChannels:numberOfChannels
|
||||
inAudioFile:self.audioFile];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
+11
-7
@@ -24,8 +24,6 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import "TargetConditionals.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
#import "EZPlot.h"
|
||||
|
||||
@class EZAudio;
|
||||
@@ -115,16 +113,16 @@ FOUNDATION_EXPORT UInt32 const EZAudioPlotDefaultMaxHistoryBufferLength;
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
The length of the rolling history display. Can grow or shrink the display up to the maximum size specified by the kEZAudioPlotMaxHistoryBufferLength macro. Will return the actual set value, which will be either the given value if smaller than the kEZAudioPlotMaxHistoryBufferLength or kEZAudioPlotMaxHistoryBufferLength if a larger value is attempted to be set.
|
||||
Sets the length of the rolling history buffer (i.e. the number of points in the rolling plot's buffer). Can grow or shrink the display up to the maximum size specified by the `maximumRollingHistoryLength` method. Will return the actual set value, which will be either the given value if smaller than the `maximumRollingHistoryLength` or `maximumRollingHistoryLength` if a larger value is attempted to be set.
|
||||
@param historyLength The new length of the rolling history buffer.
|
||||
@return The new value equal to the historyLength or the kEZAudioPlotMaxHistoryBufferLength.
|
||||
@return The new value equal to the historyLength or the `maximumRollingHistoryLength`.
|
||||
*/
|
||||
-(int)setRollingHistoryLength:(int)historyLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the length of the rolling history buffer
|
||||
Provides the length of the rolling history buffer (i.e. the number of points in the rolling plot's buffer).
|
||||
* @return An int representing the length of the rolling history buffer
|
||||
*/
|
||||
-(int)rollingHistoryLength;
|
||||
@@ -158,6 +156,13 @@ FOUNDATION_EXPORT UInt32 const EZAudioPlotDefaultMaxHistoryBufferLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called after the view has been created. Subclasses should use to add any additional methods needed instead of overriding the init methods.
|
||||
*/
|
||||
- (void)setupPlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the default number of points that will be used to initialize the graph's points data structure that holds. Essentially the plot starts off as a flat line of this many points. Default is 100.
|
||||
@return An int describing the initial number of points the plot should have when flat lined.
|
||||
@@ -187,8 +192,7 @@ FOUNDATION_EXPORT UInt32 const EZAudioPlotDefaultMaxHistoryBufferLength;
|
||||
@param data A float array of the sample data. Subclasses should copy this data to a separate array to avoid threading issues.
|
||||
@param length The length of the float array as an int.
|
||||
*/
|
||||
-(void)setSampleData:(float *)data
|
||||
length:(int)length;
|
||||
-(void)setSampleData:(float *)data length:(int)length;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
+17
-3
@@ -41,9 +41,9 @@ UInt32 const EZAudioPlotDefaultMaxHistoryBufferLength = 8192;
|
||||
|
||||
@interface EZAudioPlot () <EZAudioDisplayLinkDelegate>
|
||||
@property (nonatomic, strong) EZAudioDisplayLink *displayLink;
|
||||
@property (nonatomic, assign) EZPlotHistoryInfo *historyInfo;
|
||||
@property (nonatomic, assign) CGPoint *points;
|
||||
@property (nonatomic, assign) UInt32 pointCount;
|
||||
@property (nonatomic, assign) EZPlotHistoryInfo *historyInfo;
|
||||
@property (nonatomic, assign) CGPoint *points;
|
||||
@property (nonatomic, assign) UInt32 pointCount;
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -151,11 +151,25 @@ UInt32 const EZAudioPlotDefaultMaxHistoryBufferLength = 8192;
|
||||
self.backgroundColor = nil;
|
||||
[self.layer insertSublayer:self.waveformLayer atIndex:0];
|
||||
|
||||
//
|
||||
// Allow subclass to initialize plot
|
||||
//
|
||||
[self setupPlot];
|
||||
|
||||
self.points = calloc(EZAudioPlotDefaultMaxHistoryBufferLength, sizeof(CGPoint));
|
||||
self.pointCount = [self initialPointCount];
|
||||
[self redraw];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setupPlot
|
||||
{
|
||||
//
|
||||
// Override in subclass
|
||||
//
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+155
-87
@@ -23,126 +23,134 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "TargetConditionals.h"
|
||||
#import <GLKit/GLKit.h>
|
||||
#import "EZPlot.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <GLKit/GLKit.h>
|
||||
@class EZAudioPlotGLKViewController;
|
||||
#elif TARGET_OS_MAC
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <GLKit/GLKit.h>
|
||||
#import <OpenGL/gl3.h>
|
||||
#import <QuartzCore/CVDisplayLink.h>
|
||||
#if !TARGET_OS_IPHONE
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#endif
|
||||
|
||||
#pragma mark - Enumerations
|
||||
/**
|
||||
Constant drawing types wrapping around the OpenGL equivalents. In the audio drawings the line strip will be the stroked graph while the triangle will provide the filled equivalent.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger,EZAudioPlotGLDrawType){
|
||||
/**
|
||||
* Maps to the OpenGL constant for a line strip, which for the audio graph will correspond to a stroked drawing (no fill).
|
||||
*/
|
||||
EZAudioPlotGLDrawTypeLineStrip = GL_LINE_STRIP,
|
||||
/**
|
||||
* Maps to the OpenGL constant for a triangle strip, which for the audio graph will correspond to a filled drawing.
|
||||
*/
|
||||
EZAudioPlotGLDrawTypeTriangleStrip = GL_TRIANGLE_STRIP
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Data Structures
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - Structures
|
||||
/**
|
||||
A structure describing a 2D point (x,y) in space for an audio plot.
|
||||
*/
|
||||
typedef struct {
|
||||
GLfloat x;
|
||||
GLfloat y;
|
||||
typedef struct
|
||||
{
|
||||
GLfloat x;
|
||||
GLfloat y;
|
||||
} EZAudioPlotGLPoint;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlotGL
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
EZAudioPlotGL is a subclass of either the EZPlot on iOS or an NSOpenGLView on OSX. I apologize ahead of time for the weirdness in the docs for this class, but I had to do a bit of hackery to get a universal namespace for something works on both iOS and OSX without any additional components. The EZAudioPlotGL provides an the same utilities and interface as the EZAudioPlot with the added benefit of being GPU-accelerated. This is the recommended plot to use on iOS devices to get super fast real-time drawings of audio streams. For the methods and properties below I've included notes on the bottom just indicating which OS they correspond to. In most (if not all) use cases you can just refer to the EZPlot documentation to see which custom properties can be setup. There update function is the same as the EZPlot as well: `updateBuffer:withBufferSize:`
|
||||
EZAudioPlotGL is a subclass of either a GLKView on iOS or an NSOpenGLView on OSX. As of 0.6.0 this class no longer depends on an embedded GLKViewController for iOS as the display link is just manually managed within this single view instead. The EZAudioPlotGL provides the same kind of audio plot as the EZAudioPlot, but uses OpenGL to GPU-accelerate the drawing of the points, which means you can fit a lot more points and complex geometries.
|
||||
*/
|
||||
#if TARGET_OS_IPHONE
|
||||
@interface EZAudioPlotGL : EZPlot
|
||||
@interface EZAudioPlotGL : GLKView
|
||||
#elif TARGET_OS_MAC
|
||||
@interface EZAudioPlotGL : NSOpenGLView
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
// Inherited from EZPlot
|
||||
|
||||
#elif TARGET_OS_MAC
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Plot's Appearance
|
||||
///-----------------------------------------------------------
|
||||
/**
|
||||
The default background color of the plot. For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is black.
|
||||
*/
|
||||
@property (nonatomic,strong) id backgroundColor;
|
||||
|
||||
/**
|
||||
The default color of the plot's data (i.e. waveform, y-axis values). For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is red.
|
||||
The default background color of the plot. For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is a sweet looking green.
|
||||
@warning On OSX, if you set the background to a value where the alpha component is 0 then the EZAudioPlotGL will automatically set its superview to be layer-backed.
|
||||
*/
|
||||
@property (nonatomic,strong) id color;
|
||||
#if TARGET_OS_IPHONE
|
||||
@property (nonatomic, strong) IBInspectable UIColor *backgroundColor;
|
||||
#elif TARGET_OS_MAC
|
||||
@property (nonatomic, strong) IBInspectable NSColor *backgroundColor;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The default color of the plot's data (i.e. waveform, y-axis values). For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is white.
|
||||
*/
|
||||
#if TARGET_OS_IPHONE
|
||||
@property (nonatomic, strong) IBInspectable UIColor *color;
|
||||
#elif TARGET_OS_MAC
|
||||
@property (nonatomic, strong) IBInspectable NSColor *color;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The plot's gain value, which controls the scale of the y-axis values. The default value of the gain is 1.0f and should always be greater than 0.0f.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setGain:) float gain;
|
||||
@property (nonatomic, assign) IBInspectable float gain;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The type of plot as specified by the `EZPlotType` enumeration (i.e. a buffer or rolling plot type).
|
||||
The type of plot as specified by the `EZPlotType` enumeration (i.e. a buffer or rolling plot type). Default is EZPlotTypeBuffer.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setPlotType:) EZPlotType plotType;
|
||||
@property (nonatomic, assign) EZPlotType plotType;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A BOOL indicating whether or not to fill in the graph. A value of YES will make a filled graph (filling in the space between the x-axis and the y-value), while a value of NO will create a stroked graph (connecting the points along the y-axis).
|
||||
A BOOL indicating whether or not to fill in the graph. A value of YES will make a filled graph (filling in the space between the x-axis and the y-value), while a value of NO will create a stroked graph (connecting the points along the y-axis). Default is NO.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setShouldFill:) BOOL shouldFill;
|
||||
@property (nonatomic, assign) IBInspectable BOOL shouldFill;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A boolean indicating whether the graph should be rotated along the x-axis to give a mirrored reflection. This is typical for audio plots to produce the classic waveform look. A value of YES will produce a mirrored reflection of the y-values about the x-axis, while a value of NO will only plot the y-values.
|
||||
A boolean indicating whether the graph should be rotated along the x-axis to give a mirrored reflection. This is typical for audio plots to produce the classic waveform look. A value of YES will produce a mirrored reflection of the y-values about the x-axis, while a value of NO will only plot the y-values. Default is NO.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setShouldMirror:) BOOL shouldMirror;
|
||||
@property (nonatomic, assign) IBInspectable BOOL shouldMirror;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Updating The Plot
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - Get Samples
|
||||
///-----------------------------------------------------------
|
||||
/// @name Updating The Plot
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Updates the plot with the new buffer data and tells the view to redraw itself. Caller will provide a float array with the values they expect to see on the y-axis. The plot will internally handle mapping the x-axis and y-axis to the current view port, any interpolation for fills effects, and mirroring.
|
||||
@param buffer A float array of values to map to the y-axis.
|
||||
@param bufferSize The size of the float array that will be mapped to the y-axis.
|
||||
@warning The bufferSize is expected to be the same, constant value once initial triggered. For plots using OpenGL a vertex buffer object will be allocated with a maximum buffersize of (2 * the initial given buffer size) to account for any interpolation necessary for filling in the graph. Updates use the glBufferSubData(...) function, which will crash if the buffersize exceeds the initial maximum allocated size.
|
||||
*/
|
||||
-(void)updateBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
#endif
|
||||
-(void)updateBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Adjust Resolution
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Adjusting The Resolution
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the length of the rolling history display. Can grow or shrink the display up to the maximum size specified by the kEZAudioPlotMaxHistoryBufferLength macro. Will return the actual set value, which will be either the given value if smaller than the kEZAudioPlotMaxHistoryBufferLength or kEZAudioPlotMaxHistoryBufferLength if a larger value is attempted to be set.
|
||||
Sets the length of the rolling history buffer (i.e. the number of points in the rolling plot's buffer). Can grow or shrink the display up to the maximum size specified by the `maximumRollingHistoryLength` method. Will return the actual set value, which will be either the given value if smaller than the `maximumRollingHistoryLength` or `maximumRollingHistoryLength` if a larger value is attempted to be set.
|
||||
@param historyLength The new length of the rolling history buffer.
|
||||
@return The new value equal to the historyLength or the kEZAudioPlotMaxHistoryBufferLength.
|
||||
@return The new value equal to the historyLength or the `maximumRollingHistoryLength`.
|
||||
*/
|
||||
-(int)setRollingHistoryLength:(int)historyLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the length of the rolling history buffer
|
||||
Provides the length of the rolling history buffer (i.e. the number of points in the rolling plot's buffer).
|
||||
* @return An int representing the length of the rolling history buffer
|
||||
*/
|
||||
-(int)rollingHistoryLength;
|
||||
|
||||
#pragma mark - Shared Methods
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Clearing The Plot
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Clearing The Plot
|
||||
///-----------------------------------------------------------
|
||||
@@ -152,32 +160,92 @@ typedef struct {
|
||||
*/
|
||||
-(void)clear;
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Shared OpenGL Methods
|
||||
///-----------------------------------------------------------
|
||||
/**
|
||||
Converts a float array to an array of EZAudioPlotGLPoint structures that hold the (x,y) values the OpenGL buffer needs to properly plot its points.
|
||||
@param graph A pointer to the array that should hold the EZAudioPlotGLPoint structures.
|
||||
@param graphSize The size (or length) of the array with the EZAudioPlotGLPoint structures.
|
||||
@param drawingType The EZAudioPlotGLDrawType constant defining whether the plot should interpolate between points for a triangle strip (filled waveform) or not for a line strip (stroked waveform)
|
||||
@param buffer The float array holding the audio data
|
||||
@param bufferSize The size of the float array holding the audio data
|
||||
@param gain The gain (always greater than 0.0) to apply to the amplitudes (y-values) of the graph. Y-values can only range from -1.0 to 1.0 so any value that's greater will be rounded to -1.0 or 1.0.
|
||||
*/
|
||||
+(void)fillGraph:(EZAudioPlotGLPoint*)graph
|
||||
withGraphSize:(UInt32)graphSize
|
||||
forDrawingType:(EZAudioPlotGLDrawType)drawingType
|
||||
withBuffer:(float*)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withGain:(float)gain;
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Start/Stop Display Link
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Determines the proper size of a graph given a EZAudioPlotGLDrawType (line strip or triangle strip) and the size of the incoming buffer. Triangle strips require interpolating between points so the buffer becomes 2*bufferSize
|
||||
@param drawingType The EZAudioPlotGLDraw type (line strip or triangle strip)
|
||||
@param bufferSize The size of the float array holding the audio data coming in.
|
||||
@return A Int32 representing the proper graph size that should be used to account for any necessary interpolating between points.
|
||||
Call this method to tell the EZAudioDisplayLink to stop drawing temporarily.
|
||||
*/
|
||||
+(UInt32)graphSizeForDrawingType:(EZAudioPlotGLDrawType)drawingType
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
- (void)pauseDrawing;
|
||||
|
||||
@end
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Call this method to manually tell the EZAudioDisplayLink to start drawing again.
|
||||
*/
|
||||
- (void)resumeDrawing;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Subclass
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Drawing
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
This method is used to perform the actual OpenGL drawing code to clear the background and draw the lines representing the 2D audio plot. Subclasses can use the current implementation as an example and implement their own custom geometries. This is the analogy of overriding the drawRect: method in an NSView or UIView.
|
||||
@param points An array of EZAudioPlotGLPoint structures representing the mapped audio data to x,y coordinates. The x-axis goes from 0 to the number of points (pointCount) while the y-axis goes from -1 to 1. Check out the implementation of this method to see how the model view matrix of the base effect is transformed to map this properly to the viewport.
|
||||
@param pointCount A UInt32 representing the number of points contained in the points array.
|
||||
@param baseEffect An optional GLKBaseEffect to use as a default shader. Call prepareToDraw on the base effect before any glDrawArrays call.
|
||||
@param vbo The Vertex Buffer Object used to buffer the point data.
|
||||
@param vab The Vertex Array Buffer used to bind the Vertex Buffer Object. This is a Mac only thing, you can ignore this completely on iOS.
|
||||
@param interpolated A BOOL indicating whether the data has been interpolated. This means the point data is twice as long, where every other point is 0 on the y-axis to allow drawing triangle stripes for filled in waveforms. Typically if the point data is interpolated you will be using the GL_TRIANGLE_STRIP drawing mode, while non-interpolated plots will just use a GL_LINE_STRIP drawing mode.
|
||||
@param mirrored A BOOL indicating whether the plot should be mirrored about the y-axis (or whatever geometry you come up with).
|
||||
@param gain A float representing a gain that should be used to influence the height or intensity of your geometry's shape. A gain of 0.0 means silence, a gain of 1.0 means full volume (you're welcome to boost this to whatever you want).
|
||||
*/
|
||||
- (void)redrawWithPoints:(EZAudioPlotGLPoint *)points
|
||||
pointCount:(UInt32)pointCount
|
||||
baseEffect:(GLKBaseEffect *)baseEffect
|
||||
vertexBufferObject:(GLuint)vbo
|
||||
vertexArrayBuffer:(GLuint)vab
|
||||
interpolated:(BOOL)interpolated
|
||||
mirrored:(BOOL)mirrored
|
||||
gain:(float)gain;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called during the OpenGL run loop to constantly update the drawing 60 fps. Callers can use this force update the screen while subclasses can override this for complete control over their rendering. However, subclasses are more encouraged to use the `redrawWithPoints:pointCount:baseEffect:vertexBufferObject:vertexArrayBuffer:interpolated:mirrored:gain:`
|
||||
*/
|
||||
- (void)redraw;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called after the view has been created. Subclasses should use to add any additional methods needed instead of overriding the init methods.
|
||||
*/
|
||||
- (void)setup;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Main method used to copy the sample data from the source buffer and update the
|
||||
plot. Subclasses can overwrite this method for custom behavior.
|
||||
@param data A float array of the sample data. Subclasses should copy this data to a separate array to avoid threading issues.
|
||||
@param length The length of the float array as an int.
|
||||
*/
|
||||
- (void)setSampleData:(float *)data length:(int)length;
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Subclass Methods
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the default length of the rolling history buffer when the plot is initialized. Default is `EZAudioPlotDefaultHistoryBufferLength` constant.
|
||||
@return An int describing the initial length of the rolling history buffer.
|
||||
*/
|
||||
- (int)defaultRollingHistoryLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the default maximum rolling history length - that is, the maximum amount of points the `setRollingHistoryLength:` method may be set to. If a length higher than this is set then the plot will likely crash because the appropriate resources are only allocated once during the plot's initialization step. Defualt is `EZAudioPlotDefaultMaxHistoryBufferLength` constant.
|
||||
@return An int describing the maximum length of the absolute rolling history buffer.
|
||||
*/
|
||||
- (int)maximumRollingHistoryLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
+495
-718
File diff suppressed because it is too large
Load Diff
@@ -1,127 +0,0 @@
|
||||
//
|
||||
// EZAudioPlotGLKViewController.h
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 11/22/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "TargetConditionals.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
#import "EZAudioPlotGL.h"
|
||||
|
||||
@class EZAudio;
|
||||
|
||||
/**
|
||||
EZAudioPlotGLKViewController is a subclass of the GLKViewController and handles the OpenGL drawing routine for iOS OpenGL ES views. This class has not been used outside the scope of the EZAudioPlotGL, but should be safe to use by itself if the intended use case is to have a view controller take up the whole screen.
|
||||
*/
|
||||
@interface EZAudioPlotGLKViewController : GLKViewController
|
||||
|
||||
#pragma mark - Properties
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Plot's Appearance
|
||||
///-----------------------------------------------------------
|
||||
/**
|
||||
The default background color of the plot. For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is black.
|
||||
*/
|
||||
@property (nonatomic,strong) UIColor *backgroundColor;
|
||||
|
||||
/**
|
||||
The default shader to use to fill the graph.
|
||||
*/
|
||||
@property (nonatomic,strong) GLKBaseEffect *baseEffect;
|
||||
|
||||
/**
|
||||
The default color of the plot's data (i.e. waveform, y-axis values). For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is red.
|
||||
*/
|
||||
@property (nonatomic,strong) UIColor *color;
|
||||
|
||||
/**
|
||||
The OpenGL ES context (EAGLContext) in which to perform the drawing
|
||||
*/
|
||||
@property (nonatomic,strong) EAGLContext *context;
|
||||
|
||||
/**
|
||||
The EZAudioPlotGLDrawType specifying which OpenGL primitive to use for drawing (either line strip for stroke and no fill or triangle strip for fill)
|
||||
*/
|
||||
@property (nonatomic,assign) EZAudioPlotGLDrawType drawingType;
|
||||
|
||||
/**
|
||||
The plot's gain value, which controls the scale of the y-axis values. The default value of the gain is 1.0f and should always be greater than 0.0f.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setGain:) float gain;
|
||||
|
||||
/**
|
||||
The type of plot as specified by the `EZPlotType` enumeration (i.e. a buffer or rolling plot type).
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setPlotType:) EZPlotType plotType;
|
||||
|
||||
/**
|
||||
A boolean indicating whether the graph should be rotated along the x-axis to give a mirrored reflection. This is typical for audio plots to produce the classic waveform look. A value of YES will produce a mirrored reflection of the y-values about the x-axis, while a value of NO will only plot the y-values.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setShouldMirror:) BOOL shouldMirror;
|
||||
|
||||
#pragma mark - Adjust Resolution
|
||||
///-----------------------------------------------------------
|
||||
/// @name Adjusting The Resolution
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the length of the rolling history display. Can grow or shrink the display up to the maximum size specified by the kEZAudioPlotMaxHistoryBufferLength macro. Will return the actual set value, which will be either the given value if smaller than the kEZAudioPlotMaxHistoryBufferLength or kEZAudioPlotMaxHistoryBufferLength if a larger value is attempted to be set.
|
||||
@param historyLength The new length of the rolling history buffer.
|
||||
@return The new value equal to the historyLength or the kEZAudioPlotMaxHistoryBufferLength.
|
||||
*/
|
||||
-(int)setRollingHistoryLength:(int)historyLength;
|
||||
|
||||
/**
|
||||
Provides the length of the rolling history buffer
|
||||
* @return An int representing the length of the rolling history buffer
|
||||
*/
|
||||
-(int)rollingHistoryLength;
|
||||
|
||||
#pragma mark - Clearing
|
||||
///-----------------------------------------------------------
|
||||
/// @name Clearing The Plot
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Clears all data from the audio plot (includes both EZPlotTypeBuffer and EZPlotTypeRolling)
|
||||
*/
|
||||
-(void)clear;
|
||||
|
||||
#pragma mark - Get Samples
|
||||
///-----------------------------------------------------------
|
||||
/// @name Updating The Plot
|
||||
///-----------------------------------------------------------
|
||||
/**
|
||||
Updates the plot with the new buffer data and tells the view to redraw itself. Caller will provide a float array with the values they expect to see on the y-axis. The plot will internally handle mapping the x-axis and y-axis to the current view port, any interpolation for fills effects, and mirroring.
|
||||
@param buffer A float array of values to map to the y-axis.
|
||||
@param bufferSize The size of the float array that will be mapped to the y-axis.
|
||||
@warning The bufferSize is expected to be the same, constant value once initial triggered. For plots using OpenGL a vertex buffer object will be allocated with a maximum buffersize of (2 * the initial given buffer size) to account for any interpolation necessary for filling in the graph. Updates use the glBufferSubData(...) function, which will crash if the buffersize exceeds the initial maximum allocated size.
|
||||
*/
|
||||
-(void)updateBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
@end
|
||||
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
@@ -1,486 +0,0 @@
|
||||
//
|
||||
// EZAudioPlotGLKViewController.m
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 11/22/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
#import "EZAudioPlotGLKViewController.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
#import "EZAudioPlot.h"
|
||||
|
||||
@interface EZAudioPlotGLKViewController () {
|
||||
|
||||
// Flags indicating whether the plots have been instantiated
|
||||
BOOL _hasBufferPlotData;
|
||||
BOOL _hasRollingPlotData;
|
||||
|
||||
// The buffers
|
||||
GLuint _bufferPlotVBO;
|
||||
GLuint _rollingPlotVBO;
|
||||
|
||||
// Buffers size
|
||||
UInt32 _bufferPlotGraphSize;
|
||||
UInt32 _rollingPlotGraphSize;
|
||||
|
||||
// Rolling History
|
||||
BOOL _setMaxLength;
|
||||
float *_scrollHistory;
|
||||
int _scrollHistoryIndex;
|
||||
UInt32 _scrollHistoryLength;
|
||||
BOOL _changingHistorySize;
|
||||
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation EZAudioPlotGLKViewController
|
||||
@synthesize baseEffect = _baseEffect;
|
||||
@synthesize context = _context;
|
||||
@synthesize drawingType = _drawingType;
|
||||
@synthesize plotType = _plotType;
|
||||
@synthesize shouldMirror = _shouldMirror;
|
||||
|
||||
#pragma mark - Initialization
|
||||
-(id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self initializeView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if(self){
|
||||
[self initializeView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if(self){
|
||||
[self initializeView];
|
||||
}
|
||||
return self;
|
||||
|
||||
}
|
||||
#pragma mark - Initialize Properties Here
|
||||
-(void)initializeView {
|
||||
// Setup the base effect
|
||||
self.baseEffect = [[GLKBaseEffect alloc] init];
|
||||
self.baseEffect.useConstantColor = GL_TRUE;
|
||||
self.preferredFramesPerSecond = 60;
|
||||
_scrollHistory = NULL;
|
||||
_scrollHistoryLength = EZAudioPlotDefaultHistoryBufferLength;
|
||||
}
|
||||
|
||||
#pragma mark - View Did Load
|
||||
-(void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
// Setup the context
|
||||
if (![EAGLContext currentContext])
|
||||
{
|
||||
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.context = [EAGLContext currentContext];
|
||||
}
|
||||
|
||||
if (!self.context) {
|
||||
NSLog(@"Failed to create ES context");
|
||||
}
|
||||
else {
|
||||
EAGLContext.currentContext = self.context;
|
||||
}
|
||||
|
||||
// Set the view's context
|
||||
GLKView *view = (GLKView *)self.view;
|
||||
view.context = self.context;
|
||||
view.drawableMultisample = GLKViewDrawableMultisample4X;
|
||||
view.opaque = NO;
|
||||
|
||||
// Generate both the buffer id references
|
||||
glGenBuffers(1, &_bufferPlotVBO);
|
||||
glGenBuffers(1, &_rollingPlotVBO);
|
||||
|
||||
// Refresh color values
|
||||
[self _refreshWithBackgroundColor: self.backgroundColor];
|
||||
[self _refreshWithColor: self.color];
|
||||
|
||||
// Set the line width for the context
|
||||
glLineWidth(2.0);
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Adjust Resolution
|
||||
-(int)setRollingHistoryLength:(int)historyLength {
|
||||
_changingHistorySize = YES;
|
||||
historyLength = MIN(historyLength, EZAudioPlotDefaultMaxHistoryBufferLength);
|
||||
size_t floatByteSize = sizeof(float);
|
||||
if (_scrollHistoryLength != historyLength){
|
||||
_scrollHistoryLength = historyLength;
|
||||
}
|
||||
_scrollHistory = realloc(_scrollHistory,_scrollHistoryLength*floatByteSize);
|
||||
if (_scrollHistoryIndex < _scrollHistoryLength){
|
||||
memset(&_scrollHistory[_scrollHistoryIndex],
|
||||
0,
|
||||
(_scrollHistoryLength-_scrollHistoryIndex)*floatByteSize);
|
||||
}
|
||||
else {
|
||||
_scrollHistoryIndex = _scrollHistoryLength;
|
||||
}
|
||||
[self _updateRollingPlotDisplay];
|
||||
_changingHistorySize = NO;
|
||||
return historyLength;
|
||||
}
|
||||
|
||||
-(int)rollingHistoryLength {
|
||||
return _scrollHistoryLength;
|
||||
}
|
||||
|
||||
#pragma mark - Clearing
|
||||
-(void)clear
|
||||
{
|
||||
_scrollHistoryIndex = 0;
|
||||
[self _clearBufferPlot];
|
||||
[self _clearRollingPlot];
|
||||
}
|
||||
|
||||
-(void)_clearBufferPlot
|
||||
{
|
||||
if (_hasBufferPlotData)
|
||||
{
|
||||
float empty[_bufferPlotGraphSize];
|
||||
memset( empty, 0.0f, sizeof(float));
|
||||
[self _updateBufferPlotBufferWithAudioReceived:empty
|
||||
withBufferSize:_bufferPlotGraphSize];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)_clearRollingPlot
|
||||
{
|
||||
if (_hasRollingPlotData)
|
||||
{
|
||||
float empty[_rollingPlotGraphSize];
|
||||
EZAudioPlotGLPoint graph[_rollingPlotGraphSize];
|
||||
// Figure out better way to do this
|
||||
for(int i = 0; i < _rollingPlotGraphSize; i++)
|
||||
{
|
||||
empty[i] = 0.0f;
|
||||
}
|
||||
for(int i = 0; i < _scrollHistoryLength; i++)
|
||||
{
|
||||
_scrollHistory[i] = 0.0f;
|
||||
}
|
||||
// Update the scroll history datasource
|
||||
[EZAudioUtilities updateScrollHistory:&_scrollHistory
|
||||
withLength:_scrollHistoryLength
|
||||
atIndex:&_scrollHistoryIndex
|
||||
withBuffer:empty
|
||||
withBufferSize:_rollingPlotGraphSize
|
||||
isResolutionChanging:&_changingHistorySize];
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_rollingPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:_scrollHistory
|
||||
withBufferSize:_scrollHistoryLength
|
||||
withGain:self.gain];
|
||||
// Update the drawing
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(graph), graph);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Get Samples
|
||||
-(void)updateBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize {
|
||||
|
||||
// Make sure the update render loop is active
|
||||
if (self.paused) self.paused = NO;
|
||||
|
||||
// Make sure we are updating the buffers on the correct gl context.
|
||||
EAGLContext.currentContext = self.context;
|
||||
|
||||
// Draw based on plot type
|
||||
switch(_plotType) {
|
||||
case EZPlotTypeBuffer:
|
||||
[self _updateBufferPlotBufferWithAudioReceived:buffer
|
||||
withBufferSize:bufferSize];
|
||||
break;
|
||||
case EZPlotTypeRolling:
|
||||
[self _updateRollingPlotBufferWithAudioReceived:buffer
|
||||
withBufferSize:bufferSize];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Buffer Updating By Type
|
||||
-(void)_updateBufferPlotBufferWithAudioReceived:(float*)buffer
|
||||
withBufferSize:(UInt32)bufferSize {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _bufferPlotVBO);
|
||||
|
||||
// If starting with a VBO of half of our max size make sure we initialize it to anticipate
|
||||
// a filled graph (which needs 2 * bufferSize) to allocate its resources properly
|
||||
if (!_hasBufferPlotData && _drawingType == EZAudioPlotGLDrawTypeLineStrip){
|
||||
EZAudioPlotGLPoint maxGraph[2*bufferSize];
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(maxGraph), maxGraph, GL_STREAM_DRAW);
|
||||
_hasBufferPlotData = YES;
|
||||
}
|
||||
|
||||
// Setup the buffer plot's graph size
|
||||
_bufferPlotGraphSize = [EZAudioPlotGL graphSizeForDrawingType:_drawingType
|
||||
withBufferSize:bufferSize];
|
||||
|
||||
// Setup the graph
|
||||
EZAudioPlotGLPoint graph[_bufferPlotGraphSize];
|
||||
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_bufferPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
withGain:self.gain];
|
||||
|
||||
if (!_hasBufferPlotData){
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(graph), graph, GL_STREAM_DRAW);
|
||||
_hasBufferPlotData = YES;
|
||||
}
|
||||
else {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(graph), graph);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
}
|
||||
|
||||
-(void)_updateRollingPlotBufferWithAudioReceived:(float*)buffer
|
||||
withBufferSize:(UInt32)bufferSize {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _rollingPlotVBO);
|
||||
|
||||
|
||||
|
||||
// If starting with a VBO of half of our max size make sure we initialize it to anticipate
|
||||
// a filled graph (which needs 2 * bufferSize) to allocate its resources properly
|
||||
if (!_hasRollingPlotData){
|
||||
EZAudioPlotGLPoint maxGraph[2*EZAudioPlotDefaultMaxHistoryBufferLength];
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(maxGraph), maxGraph, GL_STREAM_DRAW);
|
||||
_hasRollingPlotData = YES;
|
||||
}
|
||||
|
||||
// Setup the plot
|
||||
_rollingPlotGraphSize = [EZAudioPlotGL graphSizeForDrawingType:_drawingType
|
||||
withBufferSize:_scrollHistoryLength];
|
||||
|
||||
// Fill the graph with data
|
||||
EZAudioPlotGLPoint graph[_rollingPlotGraphSize];
|
||||
|
||||
// Update the scroll history datasource
|
||||
[EZAudioUtilities updateScrollHistory:&_scrollHistory
|
||||
withLength:_scrollHistoryLength
|
||||
atIndex:&_scrollHistoryIndex
|
||||
withBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
isResolutionChanging:&_changingHistorySize];
|
||||
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_rollingPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:_scrollHistory
|
||||
withBufferSize:_scrollHistoryLength
|
||||
withGain:self.gain];
|
||||
|
||||
// Update the drawing
|
||||
if (!_hasRollingPlotData){
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(graph) , graph, GL_STREAM_DRAW);
|
||||
_hasRollingPlotData = YES;
|
||||
}
|
||||
else {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(graph), graph);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
}
|
||||
|
||||
-(void)_updateRollingPlotDisplay {
|
||||
// Setup the plot
|
||||
_rollingPlotGraphSize = [EZAudioPlotGL graphSizeForDrawingType:_drawingType
|
||||
withBufferSize:_scrollHistoryLength];
|
||||
|
||||
// Fill the graph with data
|
||||
EZAudioPlotGLPoint graph[_rollingPlotGraphSize];
|
||||
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_rollingPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:_scrollHistory
|
||||
withBufferSize:_scrollHistoryLength
|
||||
withGain:self.gain];
|
||||
|
||||
// Update the drawing
|
||||
if (_hasRollingPlotData){
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(graph), graph);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Drawing
|
||||
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
|
||||
|
||||
EAGLContext.currentContext = self.context;
|
||||
|
||||
// Clear the context
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (_hasBufferPlotData || _hasRollingPlotData){
|
||||
// Prepare the effect for drawing
|
||||
[self.baseEffect prepareToDraw];
|
||||
|
||||
// Plot either a buffer plot or a rolling plot
|
||||
switch(_plotType) {
|
||||
case EZPlotTypeBuffer:
|
||||
[self _drawBufferPlotWithView:view
|
||||
drawInRect:rect];
|
||||
break;
|
||||
case EZPlotTypeRolling:
|
||||
[self _drawRollingPlotWithView:view
|
||||
drawInRect:rect];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Private Drawing
|
||||
-(void)_drawBufferPlotWithView:(GLKView*)view drawInRect:(CGRect)rect {
|
||||
if (_hasBufferPlotData){
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _bufferPlotVBO);
|
||||
glEnableVertexAttribArray(GLKVertexAttribPosition);
|
||||
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(EZAudioPlotGLPoint), NULL);
|
||||
|
||||
// Normal plot
|
||||
|
||||
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(0);
|
||||
glDrawArrays(_drawingType, 0, _bufferPlotGraphSize);
|
||||
|
||||
|
||||
if (self.shouldMirror){
|
||||
// Mirrored plot
|
||||
[self.baseEffect prepareToDraw];
|
||||
|
||||
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(M_PI);
|
||||
glDrawArrays(_drawingType, 0, _bufferPlotGraphSize);
|
||||
|
||||
}
|
||||
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER,0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
-(void)_drawRollingPlotWithView:(GLKView*)view drawInRect:(CGRect)rect {
|
||||
if (_hasRollingPlotData){
|
||||
|
||||
// Normal plot
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _rollingPlotVBO);
|
||||
glEnableVertexAttribArray(GLKVertexAttribPosition);
|
||||
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(EZAudioPlotGLPoint), NULL);
|
||||
|
||||
// Normal plot
|
||||
|
||||
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(0);
|
||||
glDrawArrays(_drawingType, 0, _rollingPlotGraphSize);
|
||||
|
||||
|
||||
if (self.shouldMirror){
|
||||
// Mirrored plot
|
||||
[self.baseEffect prepareToDraw];
|
||||
|
||||
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(3.14159265359);
|
||||
glDrawArrays(_drawingType, 0, _rollingPlotGraphSize);
|
||||
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER,0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Setters
|
||||
-(void)setBackgroundColor:(UIColor *)backgroundColor {
|
||||
// Set the background color
|
||||
_backgroundColor = backgroundColor;
|
||||
// Refresh background color (map to GL vector)
|
||||
[self _refreshWithBackgroundColor:backgroundColor];
|
||||
}
|
||||
|
||||
-(void)setColor:(UIColor *)color {
|
||||
// Set the color
|
||||
_color = color;
|
||||
// Refresh the color (map to GL vector)
|
||||
[self _refreshWithColor:color];
|
||||
}
|
||||
|
||||
#pragma mark - Private Setters
|
||||
-(void)_refreshWithBackgroundColor:(UIColor*)backgroundColor {
|
||||
// Extract colors
|
||||
CGFloat red; CGFloat green; CGFloat blue; CGFloat alpha;
|
||||
[backgroundColor getRed:&red
|
||||
green:&green
|
||||
blue:&blue
|
||||
alpha:&alpha];
|
||||
// Set them on the context
|
||||
glClearColor((GLclampf)red,(GLclampf)green,(GLclampf)blue,(GLclampf)alpha);
|
||||
}
|
||||
|
||||
-(void)_refreshWithColor:(UIColor*)color {
|
||||
// Extract colors
|
||||
CGFloat red; CGFloat green; CGFloat blue; CGFloat alpha;
|
||||
[color getRed:&red
|
||||
green:&green
|
||||
blue:&blue
|
||||
alpha:&alpha];
|
||||
// Set them on the base shader
|
||||
self.baseEffect.constantColor = GLKVector4Make((GLclampf)red,(GLclampf)green,(GLclampf)blue,(GLclampf)alpha);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#elif TARGET_OS_MAC
|
||||
|
||||
#endif
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <TargetConditionals.h>
|
||||
#import "TPCircularBuffer.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#elif TARGET_OS_MAC
|
||||
@@ -404,6 +404,28 @@ typedef NSRect EZRect;
|
||||
*/
|
||||
+ (NSString *)stringFromUInt32Code:(UInt32)code;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Color Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Color Utility
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Helper function to get the color components from a CGColorRef in the RGBA colorspace.
|
||||
@param color A CGColorRef that represents a color.
|
||||
@param red A pointer to a CGFloat to hold the value of the red component. This value will be between 0 and 1.
|
||||
@param green A pointer to a CGFloat to hold the value of the green component. This value will be between 0 and 1.
|
||||
@param blue A pointer to a CGFloat to hold the value of the blue component. This value will be between 0 and 1.
|
||||
@param alpha A pointer to a CGFloat to hold the value of the alpha component. This value will be between 0 and 1.
|
||||
*/
|
||||
+ (void)getColorComponentsFromCGColor:(CGColorRef)color
|
||||
red:(CGFloat *)red
|
||||
green:(CGFloat *)green
|
||||
blue:(CGFloat *)blue
|
||||
alpha:(CGFloat *)alpha;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Plot Utility
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -478,6 +500,14 @@ typedef NSRect EZRect;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Zeroes out a EZPlotHistoryInfo data structure without freeing the resources.
|
||||
@param historyInfo A pointer to a EZPlotHistoryInfo data structure
|
||||
*/
|
||||
+ (void)clearHistoryInfo:(EZPlotHistoryInfo *)historyInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Frees a EZPlotHistoryInfo data structure
|
||||
@param historyInfo A pointer to a EZPlotHistoryInfo data structure
|
||||
|
||||
@@ -150,7 +150,7 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
NULL,
|
||||
&propSize,
|
||||
&asbd)
|
||||
operation:"Failed to fill out the rest of the m4a AudioStreamBasicDescription"];
|
||||
operation:"Failed to fill out the rest of the iLBC AudioStreamBasicDescription"];
|
||||
|
||||
return asbd;
|
||||
}
|
||||
@@ -534,6 +534,31 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Color Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Color Utility
|
||||
///-----------------------------------------------------------
|
||||
|
||||
+ (void)getColorComponentsFromCGColor:(CGColorRef)color
|
||||
red:(CGFloat *)red
|
||||
green:(CGFloat *)green
|
||||
blue:(CGFloat *)blue
|
||||
alpha:(CGFloat *)alpha
|
||||
{
|
||||
size_t componentCount = CGColorGetNumberOfComponents(color);
|
||||
if (componentCount == 4)
|
||||
{
|
||||
const CGFloat *components = CGColorGetComponents(color);
|
||||
*red = components[0];
|
||||
*green = components[1];
|
||||
*blue = components[2];
|
||||
*alpha = components[3];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - TPCircularBuffer Utility
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -591,17 +616,25 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
memmove(historyInfo->buffer, historyBuffer, bytes);
|
||||
if (targetBytes <= availableBytes)
|
||||
{
|
||||
TPCircularBufferConsume(&historyInfo->circularBuffer, sizeof(src));
|
||||
TPCircularBufferConsume(&historyInfo->circularBuffer, availableBytes - targetBytes);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (void)clearHistoryInfo:(EZPlotHistoryInfo *)historyInfo
|
||||
{
|
||||
memset(historyInfo->buffer, 0, historyInfo->bufferSize * sizeof(float));
|
||||
TPCircularBufferClear(&historyInfo->circularBuffer);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (void)freeHistoryInfo:(EZPlotHistoryInfo *)historyInfo
|
||||
{
|
||||
free(historyInfo->buffer);
|
||||
free(historyInfo);
|
||||
TPCircularBufferClear(&historyInfo->circularBuffer);
|
||||
TPCircularBufferCleanup(&historyInfo->circularBuffer);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -54,6 +54,15 @@
|
||||
/// @name Audio Data Description
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called anytime the EZMicrophone starts or stops.
|
||||
@param output The instance of the EZMicrophone that triggered the event.
|
||||
@param isPlaying A BOOL indicating whether the EZMicrophone instance is playing or not.
|
||||
*/
|
||||
- (void)microphone:(EZMicrophone *)microphone changedPlayingState:(BOOL)isPlaying;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called anytime the input device changes on an `EZMicrophone` instance.
|
||||
@param microphone The instance of the EZMicrophone that triggered the event.
|
||||
|
||||
+27
-17
@@ -70,7 +70,8 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[EZAudioUtilities checkResult:AudioUnitUninitialize(self.info->audioUnit) operation:"Failed to unintialize audio unit for microphone"];
|
||||
[EZAudioUtilities checkResult:AudioUnitUninitialize(self.info->audioUnit)
|
||||
operation:"Failed to unintialize audio unit for microphone"];
|
||||
[EZAudioUtilities freeBufferList:self.info->audioBufferList];
|
||||
[EZAudioUtilities freeFloatBuffers:self.info->floatData
|
||||
numberOfChannels:self.info->streamFormat.mChannelsPerFrame];
|
||||
@@ -116,11 +117,7 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
self = [self initWithMicrophoneDelegate:delegate];
|
||||
if(self)
|
||||
{
|
||||
self.info = (EZMicrophoneInfo *)malloc(sizeof(EZMicrophoneInfo));
|
||||
memset(self.info, 0, sizeof(EZMicrophoneInfo));
|
||||
self.info->streamFormat = audioStreamBasicDescription;
|
||||
_delegate = delegate;
|
||||
[self setup];
|
||||
[self setAudioStreamBasicDescription:audioStreamBasicDescription];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -239,13 +236,8 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
&flag,
|
||||
sizeof(flag))
|
||||
operation:"Couldn't enable input on remote IO unit."];
|
||||
EZAudioDevice *currentInputDevice = [EZAudioDevice currentInputDevice];
|
||||
[self setDevice:currentInputDevice];
|
||||
#elif TARGET_OS_MAC
|
||||
NSArray *inputDevices = [EZAudioDevice inputDevices];
|
||||
EZAudioDevice *defaultMicrophone = [inputDevices lastObject];
|
||||
[self setDevice:defaultMicrophone];
|
||||
#endif
|
||||
[self setDevice:[EZAudioDevice currentInputDevice]];
|
||||
|
||||
UInt32 propSize = sizeof(self.info->inputFormat);
|
||||
[EZAudioUtilities checkResult:AudioUnitGetProperty(self.info->audioUnit,
|
||||
@@ -260,11 +252,7 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
NSAssert(self.info->inputFormat.mSampleRate, @"Expected AVAudioSession sample rate to be greater than 0.0. Did you setup the audio session?");
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
if (self.info->streamFormat.mSampleRate == 0.0)
|
||||
{
|
||||
self.info->streamFormat = [self defaultStreamFormat];
|
||||
}
|
||||
[self setAudioStreamBasicDescription:self.info->streamFormat];
|
||||
[self setAudioStreamBasicDescription:[self defaultStreamFormat]];
|
||||
|
||||
// render callback
|
||||
AURenderCallbackStruct renderCallbackStruct;
|
||||
@@ -349,16 +337,38 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
|
||||
-(void)startFetchingAudio
|
||||
{
|
||||
//
|
||||
// Start output unit
|
||||
//
|
||||
[EZAudioUtilities checkResult:AudioOutputUnitStart(self.info->audioUnit)
|
||||
operation:"Failed to start microphone audio unit"];
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(microphone:changedPlayingState:)])
|
||||
{
|
||||
[self.delegate microphone:self changedPlayingState:YES];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void)stopFetchingAudio
|
||||
{
|
||||
//
|
||||
// Stop output unit
|
||||
//
|
||||
[EZAudioUtilities checkResult:AudioOutputUnitStop(self.info->audioUnit)
|
||||
operation:"Failed to stop microphone audio unit"];
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(microphone:changedPlayingState:)])
|
||||
{
|
||||
[self.delegate microphone:self changedPlayingState:NO];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+5
-8
@@ -108,8 +108,8 @@ OSStatus EZOutputGraphRenderCallback(void *inRefCon,
|
||||
operation:"Failed to stop graph"];
|
||||
[EZAudioUtilities checkResult:AUGraphClose(self.info->graph)
|
||||
operation:"Failed to close graph"];
|
||||
[EZAudioUtilities checkResult:AUGraphUninitialize(self.info->graph)
|
||||
operation:"Failed to uninitialize graph"];
|
||||
[EZAudioUtilities checkResult:DisposeAUGraph(self.info->graph)
|
||||
operation:"Failed to dispose of graph"];
|
||||
free(self.info);
|
||||
}
|
||||
|
||||
@@ -314,14 +314,11 @@ OSStatus EZOutputGraphRenderCallback(void *inRefCon,
|
||||
[self setClientFormat:[self defaultClientFormat]];
|
||||
[self setInputFormat:[self defaultInputFormat]];
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
//
|
||||
// Use the default device
|
||||
//
|
||||
EZAudioDevice *currentOutputDevice = [EZAudioDevice currentOutputDevice];
|
||||
[self setDevice:currentOutputDevice];
|
||||
#elif TARGET_OS_MAC
|
||||
NSArray *outputDevices = [EZAudioDevice outputDevices];
|
||||
EZAudioDevice *defaultOutput = [outputDevices firstObject];
|
||||
[self setDevice:defaultOutput];
|
||||
#endif
|
||||
|
||||
//
|
||||
// Set maximum frames per slice to 4096 to allow playback during
|
||||
|
||||
+16
-8
@@ -43,6 +43,7 @@ typedef NS_ENUM(NSInteger, EZPlotType)
|
||||
Plot that displays only the samples of the current buffer
|
||||
*/
|
||||
EZPlotTypeBuffer,
|
||||
|
||||
/**
|
||||
Plot that displays a rolling history of values using the RMS calculated for each incoming buffer
|
||||
*/
|
||||
@@ -74,32 +75,40 @@ typedef NS_ENUM(NSInteger, EZPlotType)
|
||||
/**
|
||||
The default background color of the plot. For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is black.
|
||||
*/
|
||||
@property (nonatomic,strong) id backgroundColor;
|
||||
#if TARGET_OS_IPHONE
|
||||
@property (nonatomic, strong) IBInspectable UIColor *backgroundColor;
|
||||
#elif TARGET_OS_MAC
|
||||
@property (nonatomic, strong) IBInspectable NSColor *backgroundColor;
|
||||
#endif
|
||||
|
||||
/**
|
||||
The default color of the plot's data (i.e. waveform, y-axis values). For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is red.
|
||||
*/
|
||||
@property (nonatomic,strong) id color;
|
||||
#if TARGET_OS_IPHONE
|
||||
@property (nonatomic, strong) IBInspectable UIColor *color;
|
||||
#elif TARGET_OS_MAC
|
||||
@property (nonatomic, strong) IBInspectable NSColor *color;
|
||||
#endif
|
||||
|
||||
/**
|
||||
The plot's gain value, which controls the scale of the y-axis values. The default value of the gain is 1.0f and should always be greater than 0.0f.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setGain:) float gain;
|
||||
@property (nonatomic, assign) IBInspectable float gain;
|
||||
|
||||
/**
|
||||
The type of plot as specified by the `EZPlotType` enumeration (i.e. a buffer or rolling plot type).
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setPlotType:) EZPlotType plotType;
|
||||
@property (nonatomic, assign) IBInspectable EZPlotType plotType;
|
||||
|
||||
/**
|
||||
A boolean indicating whether or not to fill in the graph. A value of YES will make a filled graph (filling in the space between the x-axis and the y-value), while a value of NO will create a stroked graph (connecting the points along the y-axis).
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setShouldFill:) BOOL shouldFill;
|
||||
@property (nonatomic, assign) IBInspectable BOOL shouldFill;
|
||||
|
||||
/**
|
||||
A boolean indicating whether the graph should be rotated along the x-axis to give a mirrored reflection. This is typical for audio plots to produce the classic waveform look. A value of YES will produce a mirrored reflection of the y-values about the x-axis, while a value of NO will only plot the y-values.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setShouldMirror:) BOOL shouldMirror;
|
||||
@property (nonatomic, assign) IBInspectable BOOL shouldMirror;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Clearing
|
||||
@@ -128,7 +137,6 @@ typedef NS_ENUM(NSInteger, EZPlotType)
|
||||
@param bufferSize The size of the float array that will be mapped to the y-axis.
|
||||
@warning The bufferSize is expected to be the same, constant value once initial triggered. For plots using OpenGL a vertex buffer object will be allocated with a maximum buffersize of (2 * the initial given buffer size) to account for any interpolation necessary for filling in the graph. Updates use the glBufferSubData(...) function, which will crash if the buffersize exceeds the initial maximum allocated size.
|
||||
*/
|
||||
-(void)updateBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
-(void)updateBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
@end
|
||||
|
||||
+257
-16
@@ -26,6 +26,12 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
@class EZRecorder;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Data Structures
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
To ensure valid recording formats are used when recording to a file the EZRecorderFileType describes the most common file types that a file can be encoded in. Each of these types can be used to output recordings as such:
|
||||
|
||||
@@ -50,57 +56,290 @@ typedef NS_ENUM(NSInteger, EZRecorderFileType)
|
||||
EZRecorderFileTypeWAV
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZRecorderDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZRecorderDelegate for the EZRecorder provides a receiver for write events, `recorderUpdatedCurrentTime:`, and the close event, `recorderDidClose:`.
|
||||
*/
|
||||
@protocol EZRecorderDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
Triggers when the EZRecorder is explicitly closed with the `closeAudioFile` method.
|
||||
@param recorder The EZRecorder instance that triggered the action
|
||||
*/
|
||||
- (void)recorderDidClose:(EZRecorder *)recorder;
|
||||
|
||||
/**
|
||||
Triggers after the EZRecorder has successfully written audio data from the `appendDataFromBufferList:withBufferSize:` method.
|
||||
@param recorder The EZRecorder instance that triggered the action
|
||||
*/
|
||||
- (void)recorderUpdatedCurrentTime:(EZRecorder *)recorder;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZRecorder
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZRecorder provides a flexible way to create an audio file and append raw audio data to it. The EZRecorder will convert the incoming audio on the fly to the destination format so no conversion is needed between this and any other component. Right now the only supported output format is 'caf'. Each output file should have its own EZRecorder instance (think 1 EZRecorder = 1 audio file).
|
||||
*/
|
||||
@interface EZRecorder : NSObject
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
An EZRecorderDelegate to listen for the write and close events.
|
||||
*/
|
||||
@property (nonatomic, weak) id<EZRecorderDelegate> delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), and a file type (see `EZRecorderFileType`) that will automatically create an internal `fileFormat` and audio file type hint.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), and a file type (see `EZRecorderFileType`) that will automatically create an internal `fileFormat` and audio file type hint, as well as a delegate to respond to the recorder's write and close events.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@param delegate An EZRecorderDelegate to listen for the recorder's write and close events.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
delegate:(id<EZRecorderDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), a file format describing the destination format on disk (see `fileFormat` for more info), and an audio file type (an AudioFileTypeID for Core Audio, not a EZRecorderFileType).
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileFormat An AudioStreamBasicDescription describing the format of the audio being written to disk (MP3, AAC, WAV, etc)
|
||||
@param audioFileTypeID An AudioFileTypeID that matches your fileFormat (i.e. kAudioFileM4AType for an M4A format)
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), a file format describing the destination format on disk (see `fileFormat` for more info), an audio file type (an AudioFileTypeID for Core Audio, not a EZRecorderFileType), and delegate to respond to the recorder's write and close events.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileFormat An AudioStreamBasicDescription describing the format of the audio being written to disk (MP3, AAC, WAV, etc)
|
||||
@param audioFileTypeID An AudioFileTypeID that matches your fileFormat (i.e. kAudioFileM4AType for an M4A format)
|
||||
@param delegate An EZRecorderDelegate to listen for the recorder's write and close events.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
delegate:(id<EZRecorderDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates a new instance of an EZRecorder using a destination file path URL and the source format of the incoming audio.
|
||||
@param url An NSURL specifying the file path location of where the audio file should be written to.
|
||||
@param sourceFormat The AudioStreamBasicDescription for the incoming audio that will be written to the file.
|
||||
@param destinationFileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@deprecated This property is deprecated starting in version 0.8.0.
|
||||
@note Please use `initWithURL:clientFormat:fileType:` initializer instead.
|
||||
@return The newly created EZRecorder instance.
|
||||
*/
|
||||
-(EZRecorder*)initWithDestinationURL:(NSURL*)url
|
||||
- (instancetype)initWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType;
|
||||
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType __attribute__((deprecated));
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), and a file type (see `EZRecorderFileType`) that will automatically create an internal `fileFormat` and audio file type hint.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), and a file type (see `EZRecorderFileType`) that will automatically create an internal `fileFormat` and audio file type hint, as well as a delegate to respond to the recorder's write and close events.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@param delegate An EZRecorderDelegate to listen for the recorder's write and close events.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
delegate:(id<EZRecorderDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), a file format describing the destination format on disk (see `fileFormat` for more info), and an audio file type (an AudioFileTypeID for Core Audio, not a EZRecorderFileType).
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileFormat An AudioStreamBasicDescription describing the format of the audio being written to disk (MP3, AAC, WAV, etc)
|
||||
@param audioFileTypeID An AudioFileTypeID that matches your fileFormat (i.e. kAudioFileM4AType for an M4A format)
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), a file format describing the destination format on disk (see `fileFormat` for more info), an audio file type (an AudioFileTypeID for Core Audio, not a EZRecorderFileType), and delegate to respond to the recorder's write and close events.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileFormat An AudioStreamBasicDescription describing the format of the audio being written to disk (MP3, AAC, WAV, etc)
|
||||
@param audioFileTypeID An AudioFileTypeID that matches your fileFormat (i.e. kAudioFileM4AType for an M4A format)
|
||||
@param delegate An EZRecorderDelegate to listen for the recorder's write and close events.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
delegate:(id<EZRecorderDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create a new instance of an EZRecorder using a destination file path URL and the source format of the incoming audio.
|
||||
@param url An NSURL specifying the file path location of where the audio file should be written to.
|
||||
@param sourceFormat The AudioStreamBasicDescription for the incoming audio that will be written to the file.
|
||||
@param sourceFormat The AudioStreamBasicDescription for the incoming audio that will be written to the file (also called the `clientFormat`).
|
||||
@param destinationFileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@return The newly created EZRecorder instance.
|
||||
*/
|
||||
+(EZRecorder*)recorderWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType;
|
||||
+ (instancetype)recorderWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType __attribute__((deprecated));
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - Getters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Getting The Recorder's Properties
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the common AudioStreamBasicDescription that will be used for in-app interaction. The recorder's format will be converted from this format to the `fileFormat`. For instance, the file on disk could be a 22.5 kHz, float format, but we might have an audio processing graph that has a 44.1 kHz, signed integer format that we'd like to interact with. The client format lets us set that 44.1 kHz format on the recorder to properly write samples from the graph out to the file in the desired destination format.
|
||||
@warning This must be a linear PCM format!
|
||||
@return An AudioStreamBasicDescription structure describing the format of the audio file.
|
||||
*/
|
||||
@property (readwrite) AudioStreamBasicDescription clientFormat;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current write offset in the audio file as an NSTimeInterval (i.e. in seconds). When setting this it will determine the correct frame offset and perform a `seekToFrame` to the new time offset.
|
||||
@warning Make sure the new current time offset is less than the `duration` or you will receive an invalid seek assertion.
|
||||
*/
|
||||
@property (readonly) NSTimeInterval currentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration of the audio file in seconds.
|
||||
*/
|
||||
@property (readonly) NSTimeInterval duration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the AudioStreamBasicDescription structure containing the format of the recorder's audio file.
|
||||
@return An AudioStreamBasicDescription structure describing the format of the audio file.
|
||||
*/
|
||||
@property (readonly) AudioStreamBasicDescription fileFormat;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current time as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedCurrentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedDuration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the frame index (a.k.a the write positon) within the audio file as SInt64. This can be helpful when seeking through the audio file.
|
||||
@return The current frame index within the audio file as a SInt64.
|
||||
*/
|
||||
@property (readonly) SInt64 frameIndex;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the total frame count of the recorder's audio file in the file format.
|
||||
@return The total number of frames in the recorder in the AudioStreamBasicDescription representing the file format as a SInt64.
|
||||
*/
|
||||
@property (readonly) SInt64 totalFrames;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the file path that's currently being used by the recorder.
|
||||
@return The NSURL representing the file path of the audio file path being used for recording.
|
||||
@return The NSURL representing the file path of the recorder path being used for recording.
|
||||
*/
|
||||
-(NSURL*)url;
|
||||
- (NSURL *)url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Events
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Appending Data To The Audio File
|
||||
/// @name Appending Data To The Recorder
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -108,16 +347,18 @@ typedef NS_ENUM(NSInteger, EZRecorderFileType)
|
||||
@param bufferList The AudioBufferList holding the audio data to append
|
||||
@param bufferSize The size of each of the buffers in the buffer list.
|
||||
*/
|
||||
-(void)appendDataFromBufferList:(AudioBufferList*)bufferList
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
- (void)appendDataFromBufferList:(AudioBufferList *)bufferList
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Closing The Audio File
|
||||
/// @name Closing The Recorder
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Finishes writes to the audio file and closes it.
|
||||
Finishes writes to the recorder's audio file and closes it.
|
||||
*/
|
||||
-(void)closeAudioFile;
|
||||
- (void)closeAudioFile;
|
||||
|
||||
@end
|
||||
+327
-63
@@ -26,57 +26,202 @@
|
||||
#import "EZRecorder.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
@interface EZRecorder (){
|
||||
ExtAudioFileRef _destinationFile;
|
||||
AudioFileTypeID _destinationFileTypeID;
|
||||
CFURLRef _destinationFileURL;
|
||||
AudioStreamBasicDescription _destinationFormat;
|
||||
AudioStreamBasicDescription _sourceFormat;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Data Structures
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AudioFileTypeID audioFileTypeID;
|
||||
ExtAudioFileRef extAudioFileRef;
|
||||
AudioStreamBasicDescription clientFormat;
|
||||
BOOL closed;
|
||||
CFURLRef fileURL;
|
||||
AudioStreamBasicDescription fileFormat;
|
||||
} EZRecorderInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZRecorder (Interface Extension)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@interface EZRecorder ()
|
||||
@property (nonatomic, assign) EZRecorderInfo *info;
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZRecorder (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation EZRecorder
|
||||
|
||||
#pragma mark - Initializers
|
||||
-(EZRecorder*)initWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (!self.info->closed)
|
||||
{
|
||||
[self closeAudioFile];
|
||||
}
|
||||
free(self.info);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
{
|
||||
return [self initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileType:fileType
|
||||
delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
delegate:(id<EZRecorderDelegate>)delegate
|
||||
{
|
||||
AudioStreamBasicDescription fileFormat = [EZRecorder formatForFileType:fileType
|
||||
withSourceFormat:clientFormat];
|
||||
AudioFileTypeID audioFileTypeID = [EZRecorder fileTypeIdForFileType:fileType
|
||||
withSourceFormat:clientFormat];
|
||||
return [self initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileFormat:fileFormat
|
||||
audioFileTypeID:audioFileTypeID
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
{
|
||||
return [self initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileFormat:fileFormat
|
||||
audioFileTypeID:audioFileTypeID
|
||||
delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
delegate:(id<EZRecorderDelegate>)delegate
|
||||
{
|
||||
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
// Set defaults
|
||||
_destinationFile = NULL;
|
||||
_destinationFileURL = (__bridge CFURLRef)url;
|
||||
_sourceFormat = sourceFormat;
|
||||
_destinationFormat = [EZRecorder recorderFormatForFileType:destinationFileType
|
||||
withSourceFormat:_sourceFormat];
|
||||
_destinationFileTypeID = [EZRecorder recorderFileTypeIdForFileType:destinationFileType
|
||||
withSourceFormat:_sourceFormat];
|
||||
|
||||
// Initializer the recorder instance
|
||||
[self _initializeRecorder];
|
||||
self.info = (EZRecorderInfo *)calloc(1, sizeof(EZRecorderInfo));
|
||||
self.info->audioFileTypeID = audioFileTypeID;
|
||||
self.info->fileURL = (__bridge CFURLRef)url;
|
||||
self.info->clientFormat = clientFormat;
|
||||
self.info->fileFormat = fileFormat;
|
||||
self.delegate = delegate;
|
||||
[self setup];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType
|
||||
{
|
||||
return [self initWithURL:url
|
||||
clientFormat:sourceFormat
|
||||
fileType:destinationFileType];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
+(EZRecorder*)recorderWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
{
|
||||
return [[self alloc] initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileType:fileType];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
delegate:(id<EZRecorderDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileType:fileType
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
{
|
||||
return [[self alloc] initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileFormat:fileFormat
|
||||
audioFileTypeID:audioFileTypeID];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
delegate:(id<EZRecorderDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileFormat:fileFormat
|
||||
audioFileTypeID:audioFileTypeID
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType
|
||||
{
|
||||
return [[EZRecorder alloc] initWithDestinationURL:url
|
||||
sourceFormat:sourceFormat
|
||||
destinationFileType:destinationFileType];
|
||||
}
|
||||
|
||||
#pragma mark - Private Configuration
|
||||
+(AudioStreamBasicDescription)recorderFormatForFileType:(EZRecorderFileType)fileType
|
||||
withSourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Methods
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (AudioStreamBasicDescription)formatForFileType:(EZRecorderFileType)fileType
|
||||
withSourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
{
|
||||
AudioStreamBasicDescription asbd;
|
||||
switch ( fileType)
|
||||
switch (fileType)
|
||||
{
|
||||
case EZRecorderFileTypeAIFF:
|
||||
asbd = [EZAudioUtilities AIFFFormatWithNumberOfChannels:sourceFormat.mChannelsPerFrame
|
||||
@@ -98,11 +243,13 @@
|
||||
return asbd;
|
||||
}
|
||||
|
||||
+(AudioFileTypeID)recorderFileTypeIdForFileType:(EZRecorderFileType)fileType
|
||||
withSourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (AudioFileTypeID)fileTypeIdForFileType:(EZRecorderFileType)fileType
|
||||
withSourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
{
|
||||
AudioFileTypeID audioFileTypeID;
|
||||
switch ( fileType)
|
||||
switch (fileType)
|
||||
{
|
||||
case EZRecorderFileTypeAIFF:
|
||||
audioFileTypeID = kAudioFileAIFFType;
|
||||
@@ -123,70 +270,187 @@
|
||||
return audioFileTypeID;
|
||||
}
|
||||
|
||||
-(void)_initializeRecorder
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setup
|
||||
{
|
||||
// Finish filling out the destination format description
|
||||
UInt32 propSize = sizeof(_destinationFormat);
|
||||
UInt32 propSize = sizeof(self.info->fileFormat);
|
||||
[EZAudioUtilities checkResult:AudioFormatGetProperty(kAudioFormatProperty_FormatInfo,
|
||||
0,
|
||||
NULL,
|
||||
&propSize,
|
||||
&_destinationFormat)
|
||||
&self.info->fileFormat)
|
||||
operation:"Failed to fill out rest of destination format"];
|
||||
|
||||
//
|
||||
// Create the audio file
|
||||
[EZAudioUtilities checkResult:ExtAudioFileCreateWithURL(_destinationFileURL,
|
||||
_destinationFileTypeID,
|
||||
&_destinationFormat,
|
||||
//
|
||||
[EZAudioUtilities checkResult:ExtAudioFileCreateWithURL(self.info->fileURL,
|
||||
self.info->audioFileTypeID,
|
||||
&self.info->fileFormat,
|
||||
NULL,
|
||||
kAudioFileFlags_EraseFile,
|
||||
&_destinationFile)
|
||||
&self.info->extAudioFileRef)
|
||||
operation:"Failed to create audio file"];
|
||||
|
||||
// Set the client format (which should be equal to the source format)
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSetProperty(_destinationFile,
|
||||
kExtAudioFileProperty_ClientDataFormat,
|
||||
sizeof(_sourceFormat),
|
||||
&_sourceFormat)
|
||||
operation:"Failed to set client format on recorded audio file"];
|
||||
|
||||
//
|
||||
// Set the client format
|
||||
//
|
||||
[self setClientFormat:self.info->clientFormat];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Events
|
||||
-(void)appendDataFromBufferList:(AudioBufferList *)bufferList
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)appendDataFromBufferList:(AudioBufferList *)bufferList
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
{
|
||||
if (_destinationFile)
|
||||
//
|
||||
// Make sure the audio file is not closed
|
||||
//
|
||||
NSAssert(!self.info->closed, @"Cannot append data when EZRecorder has been closed. You must create a new instance.;");
|
||||
|
||||
//
|
||||
// Perform the write
|
||||
//
|
||||
[EZAudioUtilities checkResult:ExtAudioFileWrite(self.info->extAudioFileRef,
|
||||
bufferSize,
|
||||
bufferList)
|
||||
operation:"Failed to write audio data to recorded audio file"];
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(recorderUpdatedCurrentTime:)])
|
||||
{
|
||||
[EZAudioUtilities checkResult:ExtAudioFileWriteAsync(_destinationFile,
|
||||
bufferSize,
|
||||
bufferList)
|
||||
operation:"Failed to write audio data to recorded audio file"];
|
||||
[self.delegate recorderUpdatedCurrentTime:self];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)closeAudioFile
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)closeAudioFile
|
||||
{
|
||||
if (_destinationFile)
|
||||
if (!self.info->closed)
|
||||
{
|
||||
// Dispose of the audio file reference
|
||||
[EZAudioUtilities checkResult:ExtAudioFileDispose(_destinationFile)
|
||||
//
|
||||
// Close, audio file can no longer be written to
|
||||
//
|
||||
[EZAudioUtilities checkResult:ExtAudioFileDispose(self.info->extAudioFileRef)
|
||||
operation:"Failed to close audio file"];
|
||||
self.info->closed = YES;
|
||||
|
||||
// Null out the file reference
|
||||
_destinationFile = NULL;
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(recorderDidClose:)])
|
||||
{
|
||||
[self.delegate recorderDidClose:self];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(NSURL *)url
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Getters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (AudioStreamBasicDescription)clientFormat
|
||||
{
|
||||
return (__bridge NSURL*)_destinationFileURL;
|
||||
return self.info->clientFormat;
|
||||
}
|
||||
|
||||
#pragma mark - Dealloc
|
||||
-(void)dealloc
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)currentTime
|
||||
{
|
||||
[self closeAudioFile];
|
||||
NSTimeInterval currentTime = 0.0;
|
||||
NSTimeInterval duration = [self duration];
|
||||
if (duration != 0.0)
|
||||
{
|
||||
currentTime = (NSTimeInterval)[EZAudioUtilities MAP:(float)[self frameIndex]
|
||||
leftMin:0.0f
|
||||
leftMax:(float)[self totalFrames]
|
||||
rightMin:0.0f
|
||||
rightMax:duration];
|
||||
}
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)duration
|
||||
{
|
||||
NSTimeInterval frames = (NSTimeInterval)[self totalFrames];
|
||||
return (NSTimeInterval) frames / self.info->fileFormat.mSampleRate;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (AudioStreamBasicDescription)fileFormat
|
||||
{
|
||||
return self.info->fileFormat;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedCurrentTime
|
||||
{
|
||||
return [EZAudioUtilities displayTimeStringFromSeconds:[self currentTime]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedDuration
|
||||
{
|
||||
return [EZAudioUtilities displayTimeStringFromSeconds:[self duration]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)frameIndex
|
||||
{
|
||||
SInt64 frameIndex;
|
||||
[EZAudioUtilities checkResult:ExtAudioFileTell(self.info->extAudioFileRef,
|
||||
&frameIndex)
|
||||
operation:"Failed to get frame index"];
|
||||
return frameIndex;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)totalFrames
|
||||
{
|
||||
SInt64 totalFrames;
|
||||
UInt32 propSize = sizeof(SInt64);
|
||||
[EZAudioUtilities checkResult:ExtAudioFileGetProperty(self.info->extAudioFileRef,
|
||||
kExtAudioFileProperty_FileLengthFrames,
|
||||
&propSize,
|
||||
&totalFrames)
|
||||
operation:"Recorder failed to get total frames."];
|
||||
return totalFrames;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSURL *)url
|
||||
{
|
||||
return (__bridge NSURL*)self.info->fileURL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setClientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
{
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSetProperty(self.info->extAudioFileRef,
|
||||
kExtAudioFileProperty_ClientDataFormat,
|
||||
sizeof(clientFormat),
|
||||
&clientFormat)
|
||||
operation:"Failed to set client format on recorded audio file"];
|
||||
self.info->clientFormat = clientFormat;
|
||||
}
|
||||
|
||||
@end
|
||||
-6
@@ -30,7 +30,6 @@
|
||||
66755A371B3B790D0013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A1A1B3B790D0013E67E /* EZAudioPlayer.m */; };
|
||||
66755A381B3B790D0013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A1C1B3B790D0013E67E /* EZAudioPlot.m */; };
|
||||
66755A391B3B790D0013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A1E1B3B790D0013E67E /* EZAudioPlotGL.m */; };
|
||||
66755A3A1B3B790D0013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A201B3B790D0013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
66755A3B1B3B790D0013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A221B3B790D0013E67E /* EZAudioUtilities.m */; };
|
||||
66755A3C1B3B790D0013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A241B3B790D0013E67E /* EZMicrophone.m */; };
|
||||
66755A3D1B3B790D0013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A261B3B790D0013E67E /* EZOutput.m */; };
|
||||
@@ -89,8 +88,6 @@
|
||||
66755A1C1B3B790D0013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
66755A1D1B3B790D0013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
66755A1E1B3B790D0013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
66755A1F1B3B790D0013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
66755A201B3B790D0013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
66755A211B3B790D0013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
66755A221B3B790D0013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
66755A231B3B790D0013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -183,8 +180,6 @@
|
||||
66755A1C1B3B790D0013E67E /* EZAudioPlot.m */,
|
||||
66755A1D1B3B790D0013E67E /* EZAudioPlotGL.h */,
|
||||
66755A1E1B3B790D0013E67E /* EZAudioPlotGL.m */,
|
||||
66755A1F1B3B790D0013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
66755A201B3B790D0013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
66755A211B3B790D0013E67E /* EZAudioUtilities.h */,
|
||||
66755A221B3B790D0013E67E /* EZAudioUtilities.m */,
|
||||
66755A231B3B790D0013E67E /* EZMicrophone.h */,
|
||||
@@ -425,7 +420,6 @@
|
||||
66755A371B3B790D0013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056D88185B97E300EB94BA /* CoreGraphicsWaveformViewController.m in Sources */,
|
||||
66755A391B3B790D0013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
66755A3A1B3B790D0013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
66755A341B3B790D0013E67E /* EZAudioFile.m in Sources */,
|
||||
66755A3D1B3B790D0013E67E /* EZOutput.m in Sources */,
|
||||
66755A3B1B3B790D0013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
+4
-3
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
@@ -648,7 +648,8 @@
|
||||
</items>
|
||||
</menu>
|
||||
<window title="EZAudioCoreGraphicsWaveformExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" fullSizeContentView="YES"/>
|
||||
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
|
||||
+5
@@ -57,6 +57,11 @@
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSPopUpButton *microphoneInputChannelPopUpButton;
|
||||
|
||||
/**
|
||||
The checkbox button used to turn the microphone off/on
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSButton *microphoneSwitch;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+21
@@ -240,4 +240,25 @@ withNumberOfChannels:(UInt32)numberOfChannels
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)microphone:(EZMicrophone *)microphone changedPlayingState:(BOOL)isPlaying
|
||||
{
|
||||
NSString *title = isPlaying ? @"Microphone On" : @"Microphone Off";
|
||||
[self setTitle:title forButton:self.microphoneSwitch];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setTitle:(NSString *)title forButton:(NSButton *)button
|
||||
{
|
||||
NSDictionary *attributes = @{ NSForegroundColorAttributeName : [NSColor whiteColor] };
|
||||
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:title
|
||||
attributes:attributes];
|
||||
button.attributedTitle = attributedTitle;
|
||||
button.attributedAlternateTitle = attributedTitle;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
+6
-5
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="CoreGraphicsWaveformViewController">
|
||||
@@ -10,6 +10,7 @@
|
||||
<outlet property="audioPlot" destination="wpL-Ou-GSb" id="OME-Hf-I27"/>
|
||||
<outlet property="microphoneInputChannelPopUpButton" destination="Yi6-fS-Cob" id="pLg-4c-klV"/>
|
||||
<outlet property="microphoneInputPopUpButton" destination="SjR-qx-mWV" id="NuN-SS-ESg"/>
|
||||
<outlet property="microphoneSwitch" destination="kAI-gs-c31" id="ADZ-Fg-aCN"/>
|
||||
<outlet property="view" destination="wpL-Ou-GSb" id="oxJ-iT-SKO"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
@@ -83,7 +84,7 @@
|
||||
<rect key="frame" x="18" y="43" width="36" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Input" id="Png-Pk-fMc">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
@@ -91,7 +92,7 @@
|
||||
<rect key="frame" x="204" y="43" width="55" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Channel" id="lkh-zp-WCY">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
@@ -111,7 +112,7 @@
|
||||
<constraint firstItem="SjR-qx-mWV" firstAttribute="top" secondItem="fi6-Uh-bvr" secondAttribute="bottom" constant="5" id="qkS-wp-O0d"/>
|
||||
<constraint firstAttribute="trailing" secondItem="HTa-6n-EPo" secondAttribute="trailing" constant="20" id="rGZ-5W-ZDN"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="178" y="314"/>
|
||||
<point key="canvasLocation" x="226" y="324"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
66755B8D1B3B79380013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B701B3B79380013E67E /* EZAudioPlayer.m */; };
|
||||
66755B8E1B3B79380013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B721B3B79380013E67E /* EZAudioPlot.m */; };
|
||||
66755B8F1B3B79380013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B741B3B79380013E67E /* EZAudioPlotGL.m */; };
|
||||
66755B901B3B79380013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B761B3B79380013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
66755B911B3B79380013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B781B3B79380013E67E /* EZAudioUtilities.m */; };
|
||||
66755B921B3B79380013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B7A1B3B79380013E67E /* EZMicrophone.m */; };
|
||||
66755B931B3B79380013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B7C1B3B79380013E67E /* EZOutput.m */; };
|
||||
@@ -76,8 +75,6 @@
|
||||
66755B721B3B79380013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
66755B731B3B79380013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
66755B741B3B79380013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
66755B751B3B79380013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
66755B761B3B79380013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
66755B771B3B79380013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
66755B781B3B79380013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
66755B791B3B79380013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -172,8 +169,6 @@
|
||||
66755B721B3B79380013E67E /* EZAudioPlot.m */,
|
||||
66755B731B3B79380013E67E /* EZAudioPlotGL.h */,
|
||||
66755B741B3B79380013E67E /* EZAudioPlotGL.m */,
|
||||
66755B751B3B79380013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
66755B761B3B79380013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
66755B771B3B79380013E67E /* EZAudioUtilities.h */,
|
||||
66755B781B3B79380013E67E /* EZAudioUtilities.m */,
|
||||
66755B791B3B79380013E67E /* EZMicrophone.h */,
|
||||
@@ -398,7 +393,6 @@
|
||||
66755B8D1B3B79380013E67E /* EZAudioPlayer.m in Sources */,
|
||||
9417A9D61872130200D9D37B /* FFTViewController.m in Sources */,
|
||||
66755B8F1B3B79380013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
66755B901B3B79380013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
66755B8A1B3B79380013E67E /* EZAudioFile.m in Sources */,
|
||||
66755B931B3B79380013E67E /* EZOutput.m in Sources */,
|
||||
66755B911B3B79380013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5053" systemVersion="13C64" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5053"/>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
@@ -10,7 +11,7 @@
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="EZAudioFFTExample" id="56">
|
||||
@@ -647,10 +648,10 @@
|
||||
</items>
|
||||
</menu>
|
||||
<window title="EZAudioFFTExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" fullSizeContentView="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="878"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
|
||||
-6
@@ -16,7 +16,6 @@
|
||||
66755A701B3B79130013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A531B3B79130013E67E /* EZAudioPlayer.m */; };
|
||||
66755A711B3B79130013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A551B3B79130013E67E /* EZAudioPlot.m */; };
|
||||
66755A721B3B79130013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A571B3B79130013E67E /* EZAudioPlotGL.m */; };
|
||||
66755A731B3B79130013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A591B3B79130013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
66755A741B3B79130013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A5B1B3B79130013E67E /* EZAudioUtilities.m */; };
|
||||
66755A751B3B79130013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A5D1B3B79130013E67E /* EZMicrophone.m */; };
|
||||
66755A761B3B79130013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A5F1B3B79130013E67E /* EZOutput.m */; };
|
||||
@@ -75,8 +74,6 @@
|
||||
66755A551B3B79130013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
66755A561B3B79130013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
66755A571B3B79130013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
66755A581B3B79130013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
66755A591B3B79130013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
66755A5A1B3B79130013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
66755A5B1B3B79130013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
66755A5C1B3B79130013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -169,8 +166,6 @@
|
||||
66755A551B3B79130013E67E /* EZAudioPlot.m */,
|
||||
66755A561B3B79130013E67E /* EZAudioPlotGL.h */,
|
||||
66755A571B3B79130013E67E /* EZAudioPlotGL.m */,
|
||||
66755A581B3B79130013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
66755A591B3B79130013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
66755A5A1B3B79130013E67E /* EZAudioUtilities.h */,
|
||||
66755A5B1B3B79130013E67E /* EZAudioUtilities.m */,
|
||||
66755A5C1B3B79130013E67E /* EZMicrophone.h */,
|
||||
@@ -394,7 +389,6 @@
|
||||
66755A701B3B79130013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056DAA185BB0BC00EB94BA /* AppDelegate.m in Sources */,
|
||||
66755A721B3B79130013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
66755A731B3B79130013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
66755A6D1B3B79130013E67E /* EZAudioFile.m in Sources */,
|
||||
66755A761B3B79130013E67E /* EZOutput.m in Sources */,
|
||||
66755A741B3B79130013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
+342
-141
@@ -1,100 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4439" systemVersion="13A451" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4439"/>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" destination="58" id="142"/>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder">
|
||||
<connections>
|
||||
<action selector="alignCenter:" destination="499" id="518"/>
|
||||
<action selector="alignJustified:" destination="500" id="523"/>
|
||||
<action selector="alignLeft:" destination="498" id="524"/>
|
||||
<action selector="alignRight:" destination="501" id="521"/>
|
||||
<action selector="arrangeInFront:" destination="5" id="39"/>
|
||||
<action selector="capitalizeWord:" destination="466" id="467"/>
|
||||
<action selector="centerSelectionInVisibleArea:" destination="210" id="245"/>
|
||||
<action selector="checkSpelling:" destination="201" id="225"/>
|
||||
<action selector="clearRecentDocuments:" destination="126" id="127"/>
|
||||
<action selector="copy:" destination="197" id="224"/>
|
||||
<action selector="copyFont:" destination="403" id="428"/>
|
||||
<action selector="copyRuler:" destination="506" id="522"/>
|
||||
<action selector="cut:" destination="199" id="228"/>
|
||||
<action selector="delete:" destination="202" id="235"/>
|
||||
<action selector="hide:" destination="134" id="367"/>
|
||||
<action selector="hideOtherApplications:" destination="145" id="368"/>
|
||||
<action selector="loosenKerning:" destination="419" id="435"/>
|
||||
<action selector="lowerBaseline:" destination="410" id="427"/>
|
||||
<action selector="lowercaseWord:" destination="465" id="468"/>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" destination="511" id="526"/>
|
||||
<action selector="makeBaseWritingDirectionNatural:" destination="510" id="525"/>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" destination="512" id="527"/>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" destination="516" id="529"/>
|
||||
<action selector="makeTextWritingDirectionNatural:" destination="515" id="528"/>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" destination="517" id="530"/>
|
||||
<action selector="newDocument:" destination="82" id="373"/>
|
||||
<action selector="openDocument:" destination="72" id="374"/>
|
||||
<action selector="orderFrontColorPanel:" destination="401" id="433"/>
|
||||
<action selector="orderFrontSubstitutionsPanel:" destination="457" id="458"/>
|
||||
<action selector="paste:" destination="203" id="226"/>
|
||||
<action selector="pasteAsPlainText:" destination="485" id="486"/>
|
||||
<action selector="pasteFont:" destination="404" id="436"/>
|
||||
<action selector="pasteRuler:" destination="507" id="519"/>
|
||||
<action selector="performClose:" destination="73" id="193"/>
|
||||
<action selector="performFindPanelAction:" destination="209" id="241"/>
|
||||
<action selector="performFindPanelAction:" destination="208" id="487"/>
|
||||
<action selector="performFindPanelAction:" destination="213" id="488"/>
|
||||
<action selector="performFindPanelAction:" destination="221" id="489"/>
|
||||
<action selector="performFindPanelAction:" destination="534" id="535"/>
|
||||
<action selector="performMiniaturize:" destination="23" id="37"/>
|
||||
<action selector="performZoom:" destination="239" id="240"/>
|
||||
<action selector="print:" destination="78" id="86"/>
|
||||
<action selector="raiseBaseline:" destination="409" id="426"/>
|
||||
<action selector="redo:" destination="215" id="231"/>
|
||||
<action selector="revertDocumentToSaved:" destination="112" id="364"/>
|
||||
<action selector="runPageLayout:" destination="77" id="87"/>
|
||||
<action selector="runToolbarCustomizationPalette:" destination="298" id="365"/>
|
||||
<action selector="saveDocument:" destination="75" id="362"/>
|
||||
<action selector="selectAll:" destination="198" id="232"/>
|
||||
<action selector="showGuessPanel:" destination="204" id="230"/>
|
||||
<action selector="showHelp:" destination="492" id="493"/>
|
||||
<action selector="startSpeaking:" destination="196" id="233"/>
|
||||
<action selector="stopSpeaking:" destination="195" id="227"/>
|
||||
<action selector="subscript:" destination="408" id="429"/>
|
||||
<action selector="superscript:" destination="407" id="430"/>
|
||||
<action selector="tightenKerning:" destination="418" id="431"/>
|
||||
<action selector="toggleAutomaticDashSubstitution:" destination="460" id="461"/>
|
||||
<action selector="toggleAutomaticLinkDetection:" destination="354" id="357"/>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" destination="351" id="356"/>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" destination="454" id="456"/>
|
||||
<action selector="toggleAutomaticTextReplacement:" destination="462" id="463"/>
|
||||
<action selector="toggleContinuousSpellChecking:" destination="219" id="222"/>
|
||||
<action selector="toggleGrammarChecking:" destination="346" id="347"/>
|
||||
<action selector="toggleRuler:" destination="505" id="520"/>
|
||||
<action selector="toggleSmartInsertDelete:" destination="350" id="355"/>
|
||||
<action selector="toggleToolbarShown:" destination="297" id="366"/>
|
||||
<action selector="turnOffKerning:" destination="417" id="441"/>
|
||||
<action selector="turnOffLigatures:" destination="413" id="440"/>
|
||||
<action selector="underline:" destination="392" id="432"/>
|
||||
<action selector="undo:" destination="207" id="223"/>
|
||||
<action selector="unhideAllApplications:" destination="150" id="370"/>
|
||||
<action selector="unscript:" destination="406" id="437"/>
|
||||
<action selector="uppercaseWord:" destination="452" id="464"/>
|
||||
<action selector="useAllLigatures:" destination="414" id="434"/>
|
||||
<action selector="useStandardKerning:" destination="416" id="438"/>
|
||||
<action selector="useStandardLigatures:" destination="412" id="439"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-3" userLabel="Application">
|
||||
<connections>
|
||||
<action selector="terminate:" destination="136" id="449"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="EZAudioOpenGLWaveformExample" id="56">
|
||||
@@ -102,6 +19,9 @@
|
||||
<items>
|
||||
<menuItem title="About EZAudioOpenGLWaveformExample" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
@@ -116,95 +36,211 @@
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide EZAudioOpenGLWaveformExample" keyEquivalent="h" id="134"/>
|
||||
<menuItem title="Hide EZAudioOpenGLWaveformExample" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150">
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150"/>
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit EZAudioOpenGLWaveformExample" keyEquivalent="q" id="136"/>
|
||||
<menuItem title="Quit EZAudioOpenGLWaveformExample" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-3" id="449"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="83">
|
||||
<menu key="submenu" title="File" id="81">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="82"/>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72"/>
|
||||
<menuItem title="New" keyEquivalent="n" id="82">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="373"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="374"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="124">
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="126"/>
|
||||
<menuItem title="Clear Menu" id="126">
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="127"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73"/>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="193"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="362"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="-1" id="87"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78">
|
||||
<connections>
|
||||
<action selector="print:" target="-1" id="86"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207"/>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="223"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="231"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199"/>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197"/>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="228"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="224"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="226"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="486"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202">
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="235"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="232"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202"/>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198"/>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209"/>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="241"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="535"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="487"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208"/>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="488"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="489"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221"/>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="216">
|
||||
<menu key="submenu" title="Spelling and Grammar" id="200">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204"/>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201"/>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="230"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="225"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="453"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219"/>
|
||||
<menuItem title="Check Grammar With Spelling" id="346"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219">
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="346">
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="454">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="456"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -214,18 +250,38 @@
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="457">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="458"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350"/>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="460">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="461"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="462">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="463"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -236,12 +292,21 @@
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="452">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="464"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="465">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="468"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="466">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="467"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -249,8 +314,16 @@
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="196"/>
|
||||
<menuItem title="Stop Speaking" id="195"/>
|
||||
<menuItem title="Start Speaking" id="196">
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="233"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="195">
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="227"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -265,13 +338,37 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389"/>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390"/>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391"/>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392"/>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="420" id="424"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="421"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="422"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="432"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="393"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394"/>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="425"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="423"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="396"/>
|
||||
<menuItem title="Kern" id="397">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -279,15 +376,27 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="416">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="438"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="417">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="441"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="418">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="431"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="419">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="435"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -298,12 +407,21 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="412">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="439"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="413">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="440"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="414">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="434"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -314,30 +432,55 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="406">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="437"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="407">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="430"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="408">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="429"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="409">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="426"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="410">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="427"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="400"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="402"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="428"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="436"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -346,12 +489,27 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498"/>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499"/>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="524"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="518"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="500">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="523"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="521"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501"/>
|
||||
<menuItem isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -363,14 +521,23 @@
|
||||
<menuItem id="510">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="511">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="512">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="527"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="513"/>
|
||||
<menuItem title="Selection" enabled="NO" id="514">
|
||||
@@ -379,14 +546,23 @@
|
||||
<menuItem id="515">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="516">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="517">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="530"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -394,12 +570,21 @@
|
||||
<menuItem isSeparatorItem="YES" id="504"/>
|
||||
<menuItem title="Show Ruler" id="505">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="520"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="522"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="519"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -412,20 +597,39 @@
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298">
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23"/>
|
||||
<menuItem title="Zoom" id="239"/>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="37"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="239">
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="240"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5"/>
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -433,17 +637,22 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="EZAudioOpenGLWaveformExample Help" keyEquivalent="?" id="492"/>
|
||||
<menuItem title="EZAudioOpenGLWaveformExample Help" keyEquivalent="?" id="492">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="EZAudioOpenGLWaveformExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" fullSizeContentView="YES"/>
|
||||
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
@@ -454,14 +663,6 @@
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" destination="390" id="421"/>
|
||||
<action selector="addFontTrait:" destination="391" id="422"/>
|
||||
<action selector="modifyFont:" destination="395" id="423"/>
|
||||
<action selector="modifyFont:" destination="394" id="425"/>
|
||||
<action selector="orderFrontFontPanel:" destination="389" id="424"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager"/>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
+5
@@ -61,6 +61,11 @@
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSPopUpButton *microphoneInputChannelPopUpButton;
|
||||
|
||||
/**
|
||||
The checkbox button used to turn the microphone off/on
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSButton *microphoneSwitch;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+22
-2
@@ -226,8 +226,7 @@ withNumberOfChannels:(UInt32)numberOfChannels
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)microphone:(EZMicrophone *)microphone
|
||||
changedDevice:(EZAudioDevice *)device
|
||||
- (void)microphone:(EZMicrophone *)microphone changedDevice:(EZAudioDevice *)device
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
//
|
||||
@@ -246,4 +245,25 @@ withNumberOfChannels:(UInt32)numberOfChannels
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)microphone:(EZMicrophone *)microphone changedPlayingState:(BOOL)isPlaying
|
||||
{
|
||||
NSString *title = isPlaying ? @"Microphone On" : @"Microphone Off";
|
||||
[self setTitle:title forButton:self.microphoneSwitch];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setTitle:(NSString *)title forButton:(NSButton *)button
|
||||
{
|
||||
NSDictionary *attributes = @{ NSForegroundColorAttributeName : [NSColor whiteColor] };
|
||||
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:title
|
||||
attributes:attributes];
|
||||
button.attributedTitle = attributedTitle;
|
||||
button.attributedAlternateTitle = attributedTitle;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
+97
-93
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="OpenGLWaveformViewController">
|
||||
@@ -10,6 +10,7 @@
|
||||
<outlet property="audioPlot" destination="foT-nv-032" id="Baw-Le-z98"/>
|
||||
<outlet property="microphoneInputChannelPopUpButton" destination="Usd-lp-n8s" id="FbQ-hj-24k"/>
|
||||
<outlet property="microphoneInputPopUpButton" destination="wBG-jf-wVy" id="thS-Ur-IMj"/>
|
||||
<outlet property="microphoneSwitch" destination="TbW-ha-PgJ" id="wEZ-dt-f7t"/>
|
||||
<outlet property="view" destination="hFn-jA-9Se" id="cfu-I4-qhQ"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
@@ -19,104 +20,107 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="TbW-ha-PgJ">
|
||||
<rect key="frame" x="339" y="44" width="123" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="119" id="xPL-Un-c5O"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="check" title="Microphone On" bezelStyle="regularSquare" imagePosition="right" state="on" inset="2" id="DaM-FV-gba">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" target="-2" id="Zb5-tE-lf2"/>
|
||||
</connections>
|
||||
</button>
|
||||
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="UPI-59-15v">
|
||||
<rect key="frame" x="335" y="15" width="127" height="24"/>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="VRd-fb-9nH">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Buffer" selected="YES"/>
|
||||
<segment label="Rolling" tag="1"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="changePlotType:" target="-2" id="BMJ-vA-3ce"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wBG-jf-wVy" userLabel="microphoneInputPopUpButton">
|
||||
<rect key="frame" x="18" y="14" width="180" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="175" id="aMw-9p-rHt"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="cAL-rs-h1w" id="H5k-ea-wV5">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="15c-sS-jR2">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="cAL-rs-h1w"/>
|
||||
<menuItem title="Item 2" id="LTz-i3-N0M"/>
|
||||
<menuItem title="Item 3" id="twD-3N-rcl"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Usd-lp-n8s" userLabel="microphoneInputChannelPopUpButton">
|
||||
<rect key="frame" x="204" y="14" width="79" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="74" id="oDB-ke-aGz"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Oit-zz-O9w" id="Eyb-QQ-0bg">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="IPB-NH-My1">
|
||||
<items>
|
||||
<menuItem title="1" state="on" id="Oit-zz-O9w"/>
|
||||
<menuItem title="Item 2" id="v3y-Nn-80j"/>
|
||||
<menuItem title="Item 3" id="IHk-VR-fPC"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AuX-d2-dD9">
|
||||
<rect key="frame" x="18" y="43" width="36" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Input" id="Fq3-tX-8aU">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="PMV-Zt-Wg6">
|
||||
<rect key="frame" x="204" y="43" width="55" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Channel" id="PTE-g2-mTV">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="foT-nv-032" customClass="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="77" width="480" height="195"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<subviews>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="TbW-ha-PgJ">
|
||||
<rect key="frame" x="339" y="47" width="123" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="119" id="xPL-Un-c5O"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="check" title="Microphone On" bezelStyle="regularSquare" imagePosition="right" state="on" inset="2" id="DaM-FV-gba">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" target="-2" id="Zb5-tE-lf2"/>
|
||||
</connections>
|
||||
</button>
|
||||
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="UPI-59-15v">
|
||||
<rect key="frame" x="335" y="18" width="127" height="24"/>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="VRd-fb-9nH">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Buffer" selected="YES"/>
|
||||
<segment label="Rolling" tag="1"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="changePlotType:" target="-2" id="BMJ-vA-3ce"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wBG-jf-wVy" userLabel="microphoneInputPopUpButton">
|
||||
<rect key="frame" x="18" y="17" width="180" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="175" id="aMw-9p-rHt"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="cAL-rs-h1w" id="H5k-ea-wV5">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="15c-sS-jR2">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="cAL-rs-h1w"/>
|
||||
<menuItem title="Item 2" id="LTz-i3-N0M"/>
|
||||
<menuItem title="Item 3" id="twD-3N-rcl"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Usd-lp-n8s" userLabel="microphoneInputChannelPopUpButton">
|
||||
<rect key="frame" x="204" y="17" width="79" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="74" id="oDB-ke-aGz"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Oit-zz-O9w" id="Eyb-QQ-0bg">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="IPB-NH-My1">
|
||||
<items>
|
||||
<menuItem title="1" state="on" id="Oit-zz-O9w"/>
|
||||
<menuItem title="Item 2" id="v3y-Nn-80j"/>
|
||||
<menuItem title="Item 3" id="IHk-VR-fPC"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AuX-d2-dD9">
|
||||
<rect key="frame" x="18" y="46" width="36" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Input" id="Fq3-tX-8aU">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="PMV-Zt-Wg6">
|
||||
<rect key="frame" x="204" y="46" width="55" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Channel" id="PTE-g2-mTV">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="AuX-d2-dD9" firstAttribute="leading" secondItem="foT-nv-032" secondAttribute="leading" constant="20" id="251-JP-6Sa"/>
|
||||
<constraint firstItem="PMV-Zt-Wg6" firstAttribute="leading" secondItem="AuX-d2-dD9" secondAttribute="trailing" constant="154" id="2EP-1U-pH4"/>
|
||||
<constraint firstAttribute="bottom" secondItem="wBG-jf-wVy" secondAttribute="bottom" constant="20" id="3kE-rV-Xyk"/>
|
||||
<constraint firstItem="wBG-jf-wVy" firstAttribute="leading" secondItem="foT-nv-032" secondAttribute="leading" constant="20" id="5BJ-zk-KIK"/>
|
||||
<constraint firstItem="wBG-jf-wVy" firstAttribute="top" secondItem="AuX-d2-dD9" secondAttribute="bottom" constant="5" id="GPm-pn-f3f"/>
|
||||
<constraint firstAttribute="bottom" secondItem="UPI-59-15v" secondAttribute="bottom" constant="20" id="NIO-kU-qxG"/>
|
||||
<constraint firstItem="UPI-59-15v" firstAttribute="top" secondItem="TbW-ha-PgJ" secondAttribute="bottom" constant="8" id="TZN-2g-Vnf"/>
|
||||
<constraint firstAttribute="trailing" secondItem="TbW-ha-PgJ" secondAttribute="trailing" constant="20" id="mg0-av-TaM"/>
|
||||
<constraint firstItem="Usd-lp-n8s" firstAttribute="top" secondItem="PMV-Zt-Wg6" secondAttribute="bottom" constant="5" id="nD0-WN-DIk"/>
|
||||
<constraint firstAttribute="trailing" secondItem="UPI-59-15v" secondAttribute="trailing" constant="20" id="rW1-1W-2K8"/>
|
||||
<constraint firstItem="Usd-lp-n8s" firstAttribute="leading" secondItem="wBG-jf-wVy" secondAttribute="trailing" constant="11" id="uWS-Ht-6JY"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Usd-lp-n8s" secondAttribute="bottom" constant="20" id="yZL-HJ-0px"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="wBG-jf-wVy" secondAttribute="bottom" constant="17" id="39Q-dq-Ifx"/>
|
||||
<constraint firstAttribute="trailing" secondItem="foT-nv-032" secondAttribute="trailing" id="4QC-HO-oMa"/>
|
||||
<constraint firstItem="foT-nv-032" firstAttribute="top" secondItem="hFn-jA-9Se" secondAttribute="top" id="5zo-Yc-OKX"/>
|
||||
<constraint firstItem="UPI-59-15v" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Usd-lp-n8s" secondAttribute="trailing" constant="11" id="AXw-KY-VEi"/>
|
||||
<constraint firstItem="Usd-lp-n8s" firstAttribute="top" secondItem="PMV-Zt-Wg6" secondAttribute="bottom" constant="5" id="GZn-x5-gDa"/>
|
||||
<constraint firstAttribute="trailing" secondItem="UPI-59-15v" secondAttribute="trailing" constant="20" id="Ihi-YB-8cN"/>
|
||||
<constraint firstItem="AuX-d2-dD9" firstAttribute="leading" secondItem="hFn-jA-9Se" secondAttribute="leading" constant="20" id="RFU-gK-hRd"/>
|
||||
<constraint firstItem="TbW-ha-PgJ" firstAttribute="top" secondItem="foT-nv-032" secondAttribute="bottom" constant="17" id="aWO-qE-S52"/>
|
||||
<constraint firstAttribute="bottom" secondItem="UPI-59-15v" secondAttribute="bottom" constant="17" id="biy-0r-WsW"/>
|
||||
<constraint firstItem="wBG-jf-wVy" firstAttribute="top" secondItem="AuX-d2-dD9" secondAttribute="bottom" constant="5" id="fEE-bx-NVl"/>
|
||||
<constraint firstItem="UPI-59-15v" firstAttribute="top" secondItem="TbW-ha-PgJ" secondAttribute="bottom" constant="8" id="gMX-Q1-9Ly"/>
|
||||
<constraint firstAttribute="trailing" secondItem="TbW-ha-PgJ" secondAttribute="trailing" constant="20" id="gek-Wl-IPz"/>
|
||||
<constraint firstItem="Usd-lp-n8s" firstAttribute="leading" secondItem="wBG-jf-wVy" secondAttribute="trailing" constant="11" id="gqi-4E-1Wf"/>
|
||||
<constraint firstItem="Usd-lp-n8s" firstAttribute="leading" secondItem="PMV-Zt-Wg6" secondAttribute="leading" id="lT3-RX-en8"/>
|
||||
<constraint firstAttribute="bottom" secondItem="foT-nv-032" secondAttribute="bottom" id="VKs-UL-eU4"/>
|
||||
<constraint firstItem="foT-nv-032" firstAttribute="leading" secondItem="hFn-jA-9Se" secondAttribute="leading" id="o4A-j4-xiR"/>
|
||||
<constraint firstItem="wBG-jf-wVy" firstAttribute="leading" secondItem="hFn-jA-9Se" secondAttribute="leading" constant="20" id="uyC-v9-bP1"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Usd-lp-n8s" secondAttribute="bottom" constant="17" id="yk6-Fm-gXu"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</objects>
|
||||
|
||||
-6
@@ -16,7 +16,6 @@
|
||||
66755B541B3B79310013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B371B3B79310013E67E /* EZAudioPlayer.m */; };
|
||||
66755B551B3B79310013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B391B3B79310013E67E /* EZAudioPlot.m */; };
|
||||
66755B561B3B79310013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B3B1B3B79310013E67E /* EZAudioPlotGL.m */; };
|
||||
66755B571B3B79310013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B3D1B3B79310013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
66755B581B3B79310013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B3F1B3B79310013E67E /* EZAudioUtilities.m */; };
|
||||
66755B591B3B79310013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B411B3B79310013E67E /* EZMicrophone.m */; };
|
||||
66755B5A1B3B79310013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B431B3B79310013E67E /* EZOutput.m */; };
|
||||
@@ -75,8 +74,6 @@
|
||||
66755B391B3B79310013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
66755B3A1B3B79310013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
66755B3B1B3B79310013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
66755B3C1B3B79310013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
66755B3D1B3B79310013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
66755B3E1B3B79310013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
66755B3F1B3B79310013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
66755B401B3B79310013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -169,8 +166,6 @@
|
||||
66755B391B3B79310013E67E /* EZAudioPlot.m */,
|
||||
66755B3A1B3B79310013E67E /* EZAudioPlotGL.h */,
|
||||
66755B3B1B3B79310013E67E /* EZAudioPlotGL.m */,
|
||||
66755B3C1B3B79310013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
66755B3D1B3B79310013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
66755B3E1B3B79310013E67E /* EZAudioUtilities.h */,
|
||||
66755B3F1B3B79310013E67E /* EZAudioUtilities.m */,
|
||||
66755B401B3B79310013E67E /* EZMicrophone.h */,
|
||||
@@ -394,7 +389,6 @@
|
||||
66755B541B3B79310013E67E /* EZAudioPlayer.m in Sources */,
|
||||
941D72211864C4D7007D52D8 /* PassThroughViewController.m in Sources */,
|
||||
66755B561B3B79310013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
66755B571B3B79310013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
66755B511B3B79310013E67E /* EZAudioFile.m in Sources */,
|
||||
66755B5A1B3B79310013E67E /* EZOutput.m in Sources */,
|
||||
66755B581B3B79310013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
+341
-141
@@ -1,100 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4439" systemVersion="13A451" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4439"/>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" destination="58" id="142"/>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder">
|
||||
<connections>
|
||||
<action selector="alignCenter:" destination="499" id="518"/>
|
||||
<action selector="alignJustified:" destination="500" id="523"/>
|
||||
<action selector="alignLeft:" destination="498" id="524"/>
|
||||
<action selector="alignRight:" destination="501" id="521"/>
|
||||
<action selector="arrangeInFront:" destination="5" id="39"/>
|
||||
<action selector="capitalizeWord:" destination="466" id="467"/>
|
||||
<action selector="centerSelectionInVisibleArea:" destination="210" id="245"/>
|
||||
<action selector="checkSpelling:" destination="201" id="225"/>
|
||||
<action selector="clearRecentDocuments:" destination="126" id="127"/>
|
||||
<action selector="copy:" destination="197" id="224"/>
|
||||
<action selector="copyFont:" destination="403" id="428"/>
|
||||
<action selector="copyRuler:" destination="506" id="522"/>
|
||||
<action selector="cut:" destination="199" id="228"/>
|
||||
<action selector="delete:" destination="202" id="235"/>
|
||||
<action selector="hide:" destination="134" id="367"/>
|
||||
<action selector="hideOtherApplications:" destination="145" id="368"/>
|
||||
<action selector="loosenKerning:" destination="419" id="435"/>
|
||||
<action selector="lowerBaseline:" destination="410" id="427"/>
|
||||
<action selector="lowercaseWord:" destination="465" id="468"/>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" destination="511" id="526"/>
|
||||
<action selector="makeBaseWritingDirectionNatural:" destination="510" id="525"/>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" destination="512" id="527"/>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" destination="516" id="529"/>
|
||||
<action selector="makeTextWritingDirectionNatural:" destination="515" id="528"/>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" destination="517" id="530"/>
|
||||
<action selector="newDocument:" destination="82" id="373"/>
|
||||
<action selector="openDocument:" destination="72" id="374"/>
|
||||
<action selector="orderFrontColorPanel:" destination="401" id="433"/>
|
||||
<action selector="orderFrontSubstitutionsPanel:" destination="457" id="458"/>
|
||||
<action selector="paste:" destination="203" id="226"/>
|
||||
<action selector="pasteAsPlainText:" destination="485" id="486"/>
|
||||
<action selector="pasteFont:" destination="404" id="436"/>
|
||||
<action selector="pasteRuler:" destination="507" id="519"/>
|
||||
<action selector="performClose:" destination="73" id="193"/>
|
||||
<action selector="performFindPanelAction:" destination="209" id="241"/>
|
||||
<action selector="performFindPanelAction:" destination="208" id="487"/>
|
||||
<action selector="performFindPanelAction:" destination="213" id="488"/>
|
||||
<action selector="performFindPanelAction:" destination="221" id="489"/>
|
||||
<action selector="performFindPanelAction:" destination="534" id="535"/>
|
||||
<action selector="performMiniaturize:" destination="23" id="37"/>
|
||||
<action selector="performZoom:" destination="239" id="240"/>
|
||||
<action selector="print:" destination="78" id="86"/>
|
||||
<action selector="raiseBaseline:" destination="409" id="426"/>
|
||||
<action selector="redo:" destination="215" id="231"/>
|
||||
<action selector="revertDocumentToSaved:" destination="112" id="364"/>
|
||||
<action selector="runPageLayout:" destination="77" id="87"/>
|
||||
<action selector="runToolbarCustomizationPalette:" destination="298" id="365"/>
|
||||
<action selector="saveDocument:" destination="75" id="362"/>
|
||||
<action selector="selectAll:" destination="198" id="232"/>
|
||||
<action selector="showGuessPanel:" destination="204" id="230"/>
|
||||
<action selector="showHelp:" destination="492" id="493"/>
|
||||
<action selector="startSpeaking:" destination="196" id="233"/>
|
||||
<action selector="stopSpeaking:" destination="195" id="227"/>
|
||||
<action selector="subscript:" destination="408" id="429"/>
|
||||
<action selector="superscript:" destination="407" id="430"/>
|
||||
<action selector="tightenKerning:" destination="418" id="431"/>
|
||||
<action selector="toggleAutomaticDashSubstitution:" destination="460" id="461"/>
|
||||
<action selector="toggleAutomaticLinkDetection:" destination="354" id="357"/>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" destination="351" id="356"/>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" destination="454" id="456"/>
|
||||
<action selector="toggleAutomaticTextReplacement:" destination="462" id="463"/>
|
||||
<action selector="toggleContinuousSpellChecking:" destination="219" id="222"/>
|
||||
<action selector="toggleGrammarChecking:" destination="346" id="347"/>
|
||||
<action selector="toggleRuler:" destination="505" id="520"/>
|
||||
<action selector="toggleSmartInsertDelete:" destination="350" id="355"/>
|
||||
<action selector="toggleToolbarShown:" destination="297" id="366"/>
|
||||
<action selector="turnOffKerning:" destination="417" id="441"/>
|
||||
<action selector="turnOffLigatures:" destination="413" id="440"/>
|
||||
<action selector="underline:" destination="392" id="432"/>
|
||||
<action selector="undo:" destination="207" id="223"/>
|
||||
<action selector="unhideAllApplications:" destination="150" id="370"/>
|
||||
<action selector="unscript:" destination="406" id="437"/>
|
||||
<action selector="uppercaseWord:" destination="452" id="464"/>
|
||||
<action selector="useAllLigatures:" destination="414" id="434"/>
|
||||
<action selector="useStandardKerning:" destination="416" id="438"/>
|
||||
<action selector="useStandardLigatures:" destination="412" id="439"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-3" userLabel="Application">
|
||||
<connections>
|
||||
<action selector="terminate:" destination="136" id="449"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="EZAudioPassThroughExample" id="56">
|
||||
@@ -102,6 +19,9 @@
|
||||
<items>
|
||||
<menuItem title="About EZAudioPassThroughExample" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
@@ -116,95 +36,211 @@
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide EZAudioPassThroughExample" keyEquivalent="h" id="134"/>
|
||||
<menuItem title="Hide EZAudioPassThroughExample" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150">
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150"/>
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit EZAudioPassThroughExample" keyEquivalent="q" id="136"/>
|
||||
<menuItem title="Quit EZAudioPassThroughExample" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-3" id="449"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="83">
|
||||
<menu key="submenu" title="File" id="81">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="82"/>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72"/>
|
||||
<menuItem title="New" keyEquivalent="n" id="82">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="373"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="374"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="124">
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="126"/>
|
||||
<menuItem title="Clear Menu" id="126">
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="127"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73"/>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="193"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="362"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="-1" id="87"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78">
|
||||
<connections>
|
||||
<action selector="print:" target="-1" id="86"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207"/>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="223"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="231"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199"/>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197"/>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="228"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="224"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="226"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="486"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202">
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="235"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="232"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202"/>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198"/>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209"/>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="241"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="535"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="487"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208"/>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="488"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="489"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221"/>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="216">
|
||||
<menu key="submenu" title="Spelling and Grammar" id="200">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204"/>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201"/>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="230"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="225"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="453"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219"/>
|
||||
<menuItem title="Check Grammar With Spelling" id="346"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219">
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="346">
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="454">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="456"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -214,18 +250,38 @@
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="457">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="458"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350"/>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="460">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="461"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="462">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="463"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -236,12 +292,21 @@
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="452">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="464"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="465">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="468"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="466">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="467"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -249,8 +314,16 @@
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="196"/>
|
||||
<menuItem title="Stop Speaking" id="195"/>
|
||||
<menuItem title="Start Speaking" id="196">
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="233"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="195">
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="227"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -265,13 +338,37 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389"/>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390"/>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391"/>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392"/>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="420" id="424"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="421"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="422"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="432"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="393"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394"/>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="425"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="423"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="396"/>
|
||||
<menuItem title="Kern" id="397">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -279,15 +376,27 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="416">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="438"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="417">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="441"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="418">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="431"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="419">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="435"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -298,12 +407,21 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="412">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="439"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="413">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="440"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="414">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="434"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -314,30 +432,55 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="406">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="437"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="407">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="430"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="408">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="429"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="409">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="426"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="410">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="427"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="400"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="402"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="428"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="436"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -346,12 +489,27 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498"/>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499"/>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="524"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="518"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="500">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="523"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="521"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501"/>
|
||||
<menuItem isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -363,14 +521,23 @@
|
||||
<menuItem id="510">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="511">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="512">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="527"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="513"/>
|
||||
<menuItem title="Selection" enabled="NO" id="514">
|
||||
@@ -379,14 +546,23 @@
|
||||
<menuItem id="515">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="516">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="517">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="530"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -394,12 +570,21 @@
|
||||
<menuItem isSeparatorItem="YES" id="504"/>
|
||||
<menuItem title="Show Ruler" id="505">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="520"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="522"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="519"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -412,20 +597,39 @@
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298">
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23"/>
|
||||
<menuItem title="Zoom" id="239"/>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="37"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="239">
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="240"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5"/>
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -433,17 +637,21 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="EZAudioPassThroughExample Help" keyEquivalent="?" id="492"/>
|
||||
<menuItem title="EZAudioPassThroughExample Help" keyEquivalent="?" id="492">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="EZAudioPassThroughExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" fullSizeContentView="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
@@ -454,14 +662,6 @@
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" destination="390" id="421"/>
|
||||
<action selector="addFontTrait:" destination="391" id="422"/>
|
||||
<action selector="modifyFont:" destination="395" id="423"/>
|
||||
<action selector="modifyFont:" destination="394" id="425"/>
|
||||
<action selector="orderFrontFontPanel:" destination="389" id="424"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager"/>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
+8
-1
@@ -39,7 +39,14 @@
|
||||
/**
|
||||
The OpenGL based audio plot
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlotGL *audioPlot;
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlotGL *audioPlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The label used to display the microphone state
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSButton *microphoneSwitch;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
|
||||
+21
@@ -132,6 +132,14 @@
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)microphone:(EZMicrophone *)microphone changedPlayingState:(BOOL)isPlaying
|
||||
{
|
||||
NSString *title = isPlaying ? @"Microphone On" : @"Microphone Off";
|
||||
[self setTitle:title forButton:self.microphoneSwitch];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void) microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
@@ -144,6 +152,19 @@
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setTitle:(NSString *)title forButton:(NSButton *)button
|
||||
{
|
||||
NSDictionary *attributes = @{ NSForegroundColorAttributeName : [NSColor whiteColor] };
|
||||
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:title
|
||||
attributes:attributes];
|
||||
button.attributedTitle = attributedTitle;
|
||||
button.attributedAlternateTitle = attributedTitle;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
+63
-43
@@ -1,69 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="PassThroughViewController">
|
||||
<connections>
|
||||
<outlet property="audioPlot" destination="szV-uu-KbA" id="KwB-bl-yeS"/>
|
||||
<outlet property="microphoneSwitch" destination="hej-uQ-uG1" id="fhN-xl-LNP"/>
|
||||
<outlet property="view" destination="1d9-8y-ung" id="BT4-Db-KNk"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="1d9-8y-ung">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="szV-uu-KbA" customClass="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="42" width="480" height="230"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<subviews>
|
||||
<box autoresizesSubviews="NO" title="Box" boxType="custom" borderType="none" translatesAutoresizingMaskIntoConstraints="NO" id="eSf-nW-gda">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="57"/>
|
||||
<view key="contentView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="57"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="hej-uQ-uG1">
|
||||
<rect key="frame" x="16" y="16" width="119" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="fd8-mW-5iG"/>
|
||||
<constraint firstAttribute="width" constant="115" id="znu-AU-bWg"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="check" title="Microphone On" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="k97-dB-fHu">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" target="-2" id="ofz-vX-IjK"/>
|
||||
</connections>
|
||||
</button>
|
||||
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sPx-Eg-cI6">
|
||||
<rect key="frame" x="335" y="16" width="129" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="125" id="JlH-Js-Z1d"/>
|
||||
<constraint firstAttribute="height" constant="21" id="hEY-sc-Ib0"/>
|
||||
</constraints>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="q61-MR-tCv">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Buffer" selected="YES"/>
|
||||
<segment label="Rolling" tag="1"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="changePlotType:" target="-2" id="UVX-Mg-yXi"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="sPx-Eg-cI6" secondAttribute="trailing" constant="18" id="3dz-EL-GYk"/>
|
||||
<constraint firstItem="hej-uQ-uG1" firstAttribute="leading" secondItem="eSf-nW-gda" secondAttribute="leading" constant="18" id="QRY-A3-l3d"/>
|
||||
<constraint firstItem="sPx-Eg-cI6" firstAttribute="centerY" secondItem="eSf-nW-gda" secondAttribute="centerY" id="ZiD-Mc-F6Z"/>
|
||||
<constraint firstItem="sPx-Eg-cI6" firstAttribute="bottom" secondItem="hej-uQ-uG1" secondAttribute="bottom" id="kMA-Gc-Asn"/>
|
||||
<constraint firstAttribute="height" constant="57" id="q54-Ma-rT2"/>
|
||||
</constraints>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" red="0.0" green="0.0" blue="0.0" alpha="0.70000000000000007" colorSpace="calibratedRGB"/>
|
||||
</box>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="eSf-nW-gda" firstAttribute="leading" secondItem="szV-uu-KbA" secondAttribute="leading" id="n5W-wG-XMz"/>
|
||||
<constraint firstAttribute="bottom" secondItem="eSf-nW-gda" secondAttribute="bottom" id="ob1-us-1L5"/>
|
||||
<constraint firstAttribute="trailing" secondItem="eSf-nW-gda" secondAttribute="trailing" id="pGc-Rn-8IL"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="hej-uQ-uG1">
|
||||
<rect key="frame" x="18" y="14" width="119" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="fd8-mW-5iG"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="check" title="Microphone On" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="k97-dB-fHu">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" target="-2" id="ofz-vX-IjK"/>
|
||||
</connections>
|
||||
</button>
|
||||
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sPx-Eg-cI6">
|
||||
<rect key="frame" x="333" y="11" width="129" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="21" id="hEY-sc-Ib0"/>
|
||||
</constraints>
|
||||
<segmentedCell key="cell" alignment="left" style="rounded" trackingMode="selectOne" id="q61-MR-tCv">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Buffer" selected="YES"/>
|
||||
<segment label="Rolling" tag="1"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="changePlotType:" target="-2" id="UVX-Mg-yXi"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="szV-uu-KbA" secondAttribute="bottom" id="8NU-Oj-lK1"/>
|
||||
<constraint firstAttribute="trailing" secondItem="szV-uu-KbA" secondAttribute="trailing" id="AVW-CO-N2Q"/>
|
||||
<constraint firstItem="szV-uu-KbA" firstAttribute="top" secondItem="1d9-8y-ung" secondAttribute="top" id="DM4-bU-zuP"/>
|
||||
<constraint firstItem="sPx-Eg-cI6" firstAttribute="top" secondItem="szV-uu-KbA" secondAttribute="bottom" constant="8" id="EFb-mI-KZS"/>
|
||||
<constraint firstAttribute="trailing" secondItem="sPx-Eg-cI6" secondAttribute="trailing" constant="20" id="MiO-PO-tmm"/>
|
||||
<constraint firstItem="hej-uQ-uG1" firstAttribute="leading" secondItem="1d9-8y-ung" secondAttribute="leading" constant="20" id="NJE-fd-586"/>
|
||||
<constraint firstItem="szV-uu-KbA" firstAttribute="leading" secondItem="1d9-8y-ung" secondAttribute="leading" id="Qkq-oi-gx2"/>
|
||||
<constraint firstAttribute="bottom" secondItem="hej-uQ-uG1" secondAttribute="bottom" constant="16" id="UXq-4r-K0N"/>
|
||||
<constraint firstAttribute="bottom" secondItem="sPx-Eg-cI6" secondAttribute="bottom" constant="13" id="V0F-aH-MAE"/>
|
||||
<constraint firstItem="hej-uQ-uG1" firstAttribute="top" secondItem="szV-uu-KbA" secondAttribute="bottom" constant="12" id="cPy-qk-vL2"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
</document>
|
||||
|
||||
-6
@@ -17,7 +17,6 @@
|
||||
66755AA91B3B791C0013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A8C1B3B791C0013E67E /* EZAudioPlayer.m */; };
|
||||
66755AAA1B3B791C0013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A8E1B3B791C0013E67E /* EZAudioPlot.m */; };
|
||||
66755AAB1B3B791C0013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A901B3B791C0013E67E /* EZAudioPlotGL.m */; };
|
||||
66755AAC1B3B791C0013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A921B3B791C0013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
66755AAD1B3B791C0013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A941B3B791C0013E67E /* EZAudioUtilities.m */; };
|
||||
66755AAE1B3B791C0013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A961B3B791C0013E67E /* EZMicrophone.m */; };
|
||||
66755AAF1B3B791C0013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755A981B3B791C0013E67E /* EZOutput.m */; };
|
||||
@@ -77,8 +76,6 @@
|
||||
66755A8E1B3B791C0013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
66755A8F1B3B791C0013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
66755A901B3B791C0013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
66755A911B3B791C0013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
66755A921B3B791C0013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
66755A931B3B791C0013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
66755A941B3B791C0013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
66755A951B3B791C0013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -171,8 +168,6 @@
|
||||
66755A8E1B3B791C0013E67E /* EZAudioPlot.m */,
|
||||
66755A8F1B3B791C0013E67E /* EZAudioPlotGL.h */,
|
||||
66755A901B3B791C0013E67E /* EZAudioPlotGL.m */,
|
||||
66755A911B3B791C0013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
66755A921B3B791C0013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
66755A931B3B791C0013E67E /* EZAudioUtilities.h */,
|
||||
66755A941B3B791C0013E67E /* EZAudioUtilities.m */,
|
||||
66755A951B3B791C0013E67E /* EZMicrophone.h */,
|
||||
@@ -398,7 +393,6 @@
|
||||
66755AA91B3B791C0013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056F31185BD86D00EB94BA /* PlayFileViewController.m in Sources */,
|
||||
66755AAB1B3B791C0013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
66755AAC1B3B791C0013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
66755AA61B3B791C0013E67E /* EZAudioFile.m in Sources */,
|
||||
66755AAF1B3B791C0013E67E /* EZOutput.m in Sources */,
|
||||
66755AAD1B3B791C0013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
+341
-141
@@ -1,100 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4439" systemVersion="13A451" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4439"/>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" destination="58" id="142"/>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder">
|
||||
<connections>
|
||||
<action selector="alignCenter:" destination="499" id="518"/>
|
||||
<action selector="alignJustified:" destination="500" id="523"/>
|
||||
<action selector="alignLeft:" destination="498" id="524"/>
|
||||
<action selector="alignRight:" destination="501" id="521"/>
|
||||
<action selector="arrangeInFront:" destination="5" id="39"/>
|
||||
<action selector="capitalizeWord:" destination="466" id="467"/>
|
||||
<action selector="centerSelectionInVisibleArea:" destination="210" id="245"/>
|
||||
<action selector="checkSpelling:" destination="201" id="225"/>
|
||||
<action selector="clearRecentDocuments:" destination="126" id="127"/>
|
||||
<action selector="copy:" destination="197" id="224"/>
|
||||
<action selector="copyFont:" destination="403" id="428"/>
|
||||
<action selector="copyRuler:" destination="506" id="522"/>
|
||||
<action selector="cut:" destination="199" id="228"/>
|
||||
<action selector="delete:" destination="202" id="235"/>
|
||||
<action selector="hide:" destination="134" id="367"/>
|
||||
<action selector="hideOtherApplications:" destination="145" id="368"/>
|
||||
<action selector="loosenKerning:" destination="419" id="435"/>
|
||||
<action selector="lowerBaseline:" destination="410" id="427"/>
|
||||
<action selector="lowercaseWord:" destination="465" id="468"/>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" destination="511" id="526"/>
|
||||
<action selector="makeBaseWritingDirectionNatural:" destination="510" id="525"/>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" destination="512" id="527"/>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" destination="516" id="529"/>
|
||||
<action selector="makeTextWritingDirectionNatural:" destination="515" id="528"/>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" destination="517" id="530"/>
|
||||
<action selector="newDocument:" destination="82" id="373"/>
|
||||
<action selector="openDocument:" destination="72" id="374"/>
|
||||
<action selector="orderFrontColorPanel:" destination="401" id="433"/>
|
||||
<action selector="orderFrontSubstitutionsPanel:" destination="457" id="458"/>
|
||||
<action selector="paste:" destination="203" id="226"/>
|
||||
<action selector="pasteAsPlainText:" destination="485" id="486"/>
|
||||
<action selector="pasteFont:" destination="404" id="436"/>
|
||||
<action selector="pasteRuler:" destination="507" id="519"/>
|
||||
<action selector="performClose:" destination="73" id="193"/>
|
||||
<action selector="performFindPanelAction:" destination="209" id="241"/>
|
||||
<action selector="performFindPanelAction:" destination="208" id="487"/>
|
||||
<action selector="performFindPanelAction:" destination="213" id="488"/>
|
||||
<action selector="performFindPanelAction:" destination="221" id="489"/>
|
||||
<action selector="performFindPanelAction:" destination="534" id="535"/>
|
||||
<action selector="performMiniaturize:" destination="23" id="37"/>
|
||||
<action selector="performZoom:" destination="239" id="240"/>
|
||||
<action selector="print:" destination="78" id="86"/>
|
||||
<action selector="raiseBaseline:" destination="409" id="426"/>
|
||||
<action selector="redo:" destination="215" id="231"/>
|
||||
<action selector="revertDocumentToSaved:" destination="112" id="364"/>
|
||||
<action selector="runPageLayout:" destination="77" id="87"/>
|
||||
<action selector="runToolbarCustomizationPalette:" destination="298" id="365"/>
|
||||
<action selector="saveDocument:" destination="75" id="362"/>
|
||||
<action selector="selectAll:" destination="198" id="232"/>
|
||||
<action selector="showGuessPanel:" destination="204" id="230"/>
|
||||
<action selector="showHelp:" destination="492" id="493"/>
|
||||
<action selector="startSpeaking:" destination="196" id="233"/>
|
||||
<action selector="stopSpeaking:" destination="195" id="227"/>
|
||||
<action selector="subscript:" destination="408" id="429"/>
|
||||
<action selector="superscript:" destination="407" id="430"/>
|
||||
<action selector="tightenKerning:" destination="418" id="431"/>
|
||||
<action selector="toggleAutomaticDashSubstitution:" destination="460" id="461"/>
|
||||
<action selector="toggleAutomaticLinkDetection:" destination="354" id="357"/>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" destination="351" id="356"/>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" destination="454" id="456"/>
|
||||
<action selector="toggleAutomaticTextReplacement:" destination="462" id="463"/>
|
||||
<action selector="toggleContinuousSpellChecking:" destination="219" id="222"/>
|
||||
<action selector="toggleGrammarChecking:" destination="346" id="347"/>
|
||||
<action selector="toggleRuler:" destination="505" id="520"/>
|
||||
<action selector="toggleSmartInsertDelete:" destination="350" id="355"/>
|
||||
<action selector="toggleToolbarShown:" destination="297" id="366"/>
|
||||
<action selector="turnOffKerning:" destination="417" id="441"/>
|
||||
<action selector="turnOffLigatures:" destination="413" id="440"/>
|
||||
<action selector="underline:" destination="392" id="432"/>
|
||||
<action selector="undo:" destination="207" id="223"/>
|
||||
<action selector="unhideAllApplications:" destination="150" id="370"/>
|
||||
<action selector="unscript:" destination="406" id="437"/>
|
||||
<action selector="uppercaseWord:" destination="452" id="464"/>
|
||||
<action selector="useAllLigatures:" destination="414" id="434"/>
|
||||
<action selector="useStandardKerning:" destination="416" id="438"/>
|
||||
<action selector="useStandardLigatures:" destination="412" id="439"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-3" userLabel="Application">
|
||||
<connections>
|
||||
<action selector="terminate:" destination="136" id="449"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="EZAudioPlayFileExample" id="56">
|
||||
@@ -102,6 +19,9 @@
|
||||
<items>
|
||||
<menuItem title="About EZAudioPlayFileExample" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
@@ -116,95 +36,211 @@
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide EZAudioPlayFileExample" keyEquivalent="h" id="134"/>
|
||||
<menuItem title="Hide EZAudioPlayFileExample" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150">
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150"/>
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit EZAudioPlayFileExample" keyEquivalent="q" id="136"/>
|
||||
<menuItem title="Quit EZAudioPlayFileExample" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-3" id="449"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="83">
|
||||
<menu key="submenu" title="File" id="81">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="82"/>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72"/>
|
||||
<menuItem title="New" keyEquivalent="n" id="82">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="373"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="374"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="124">
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="126"/>
|
||||
<menuItem title="Clear Menu" id="126">
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="127"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73"/>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="193"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="362"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="-1" id="87"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78">
|
||||
<connections>
|
||||
<action selector="print:" target="-1" id="86"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207"/>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="223"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="231"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199"/>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197"/>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="228"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="224"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="226"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="486"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202">
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="235"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="232"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202"/>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198"/>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209"/>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="241"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="535"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="487"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208"/>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="488"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="489"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221"/>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="216">
|
||||
<menu key="submenu" title="Spelling and Grammar" id="200">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204"/>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201"/>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="230"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="225"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="453"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219"/>
|
||||
<menuItem title="Check Grammar With Spelling" id="346"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219">
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="346">
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="454">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="456"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -214,18 +250,38 @@
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="457">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="458"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350"/>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="460">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="461"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="462">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="463"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -236,12 +292,21 @@
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="452">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="464"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="465">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="468"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="466">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="467"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -249,8 +314,16 @@
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="196"/>
|
||||
<menuItem title="Stop Speaking" id="195"/>
|
||||
<menuItem title="Start Speaking" id="196">
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="233"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="195">
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="227"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -265,13 +338,37 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389"/>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390"/>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391"/>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392"/>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="420" id="424"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="421"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="422"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="432"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="393"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394"/>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="425"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="423"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="396"/>
|
||||
<menuItem title="Kern" id="397">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -279,15 +376,27 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="416">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="438"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="417">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="441"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="418">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="431"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="419">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="435"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -298,12 +407,21 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="412">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="439"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="413">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="440"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="414">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="434"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -314,30 +432,55 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="406">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="437"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="407">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="430"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="408">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="429"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="409">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="426"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="410">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="427"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="400"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="402"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="428"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="436"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -346,12 +489,27 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498"/>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499"/>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="524"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="518"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="500">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="523"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="521"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501"/>
|
||||
<menuItem isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -363,14 +521,23 @@
|
||||
<menuItem id="510">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="511">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="512">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="527"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="513"/>
|
||||
<menuItem title="Selection" enabled="NO" id="514">
|
||||
@@ -379,14 +546,23 @@
|
||||
<menuItem id="515">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="516">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="517">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="530"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -394,12 +570,21 @@
|
||||
<menuItem isSeparatorItem="YES" id="504"/>
|
||||
<menuItem title="Show Ruler" id="505">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="520"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="522"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="519"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -412,20 +597,39 @@
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298">
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23"/>
|
||||
<menuItem title="Zoom" id="239"/>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="37"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="239">
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="240"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5"/>
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -433,17 +637,21 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="EZAudioPlayFileExample Help" keyEquivalent="?" id="492"/>
|
||||
<menuItem title="EZAudioPlayFileExample Help" keyEquivalent="?" id="492">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="EZAudioPlayFileExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" fullSizeContentView="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
@@ -454,14 +662,6 @@
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" destination="390" id="421"/>
|
||||
<action selector="addFontTrait:" destination="391" id="422"/>
|
||||
<action selector="modifyFont:" destination="395" id="423"/>
|
||||
<action selector="modifyFont:" destination="394" id="425"/>
|
||||
<action selector="orderFrontFontPanel:" destination="389" id="424"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager"/>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
+13
-5
@@ -37,9 +37,7 @@
|
||||
Using the EZOutputDataSource to provide output data to the EZOutput component.
|
||||
*/
|
||||
@interface PlayFileViewController : NSViewController <NSOpenSavePanelDelegate,
|
||||
EZAudioFileDelegate,
|
||||
EZOutputDataSource,
|
||||
EZOutputDelegate>
|
||||
EZAudioPlayerDelegate>
|
||||
|
||||
#pragma mark - Components
|
||||
/**
|
||||
@@ -50,12 +48,12 @@
|
||||
/**
|
||||
The EZOutput component used to output the audio file's audio data.
|
||||
*/
|
||||
@property (nonatomic, strong) EZOutput *output;
|
||||
@property (nonatomic, strong) EZAudioPlayer *player;
|
||||
|
||||
/**
|
||||
The CoreGraphics based audio plot
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlot *audioPlot;
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlotGL *audioPlot;
|
||||
|
||||
#pragma mark - UI Extras
|
||||
/**
|
||||
@@ -63,6 +61,11 @@
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSTextField *filePathLabel;
|
||||
|
||||
/**
|
||||
A checkbox button to that allows you to specify if the audio player should loop.
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSButton *loopCheckboxButton;
|
||||
|
||||
/**
|
||||
A label to display the audio file's current position.
|
||||
*/
|
||||
@@ -114,6 +117,11 @@
|
||||
*/
|
||||
- (IBAction)changeRollingHistoryLength:(id)sender;
|
||||
|
||||
/**
|
||||
Switches the loop state on the audio player regarding whether the current playing audio file should loop back to the beginning when it finishes.
|
||||
*/
|
||||
- (IBAction)changeShouldLoop:(id)sender;
|
||||
|
||||
/**
|
||||
Changes the volume of the audio coming out of the EZOutput.
|
||||
*/
|
||||
|
||||
+119
-62
@@ -32,6 +32,15 @@
|
||||
|
||||
@implementation PlayFileViewController
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Customize the Audio Plot
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -55,8 +64,8 @@
|
||||
//
|
||||
// Create EZOutput to play audio data
|
||||
//
|
||||
self.output = [EZOutput outputWithDataSource:self];
|
||||
self.output.delegate = self;
|
||||
self.player = [EZAudioPlayer audioPlayerWithDelegate:self];
|
||||
self.player.shouldLoop = YES;
|
||||
|
||||
//
|
||||
// Reload the menu for the output device selector popup button
|
||||
@@ -66,17 +75,81 @@
|
||||
//
|
||||
// Configure UI components
|
||||
//
|
||||
self.volumeSlider.floatValue = [self.output volume];
|
||||
self.volumeLabel.floatValue = [self.output volume];
|
||||
self.volumeSlider.floatValue = [self.player volume];
|
||||
self.volumeLabel.floatValue = [self.player volume];
|
||||
self.rollingHistoryLengthSlider.intValue = [self.audioPlot rollingHistoryLength];
|
||||
self.rollingHistoryLengthLabel.intValue = [self.audioPlot rollingHistoryLength];
|
||||
self.loopCheckboxButton.state = [self.player shouldLoop];
|
||||
|
||||
//
|
||||
// Listen for state changes to the EZAudioPlayer
|
||||
//
|
||||
[self setupNotifications];
|
||||
|
||||
//
|
||||
// Try opening the sample file
|
||||
//
|
||||
[self openFileWithFilePathURL:[NSURL fileURLWithPath:kAudioFileDefault]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Notifications
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setupNotifications
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(audioPlayerDidChangeAudioFile:)
|
||||
name:EZAudioPlayerDidChangeAudioFileNotification
|
||||
object:self.player];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(audioPlayerDidChangeOutputDevice:)
|
||||
name:EZAudioPlayerDidChangeOutputDeviceNotification
|
||||
object:self.player];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(audioPlayerDidChangePlayState:)
|
||||
name:EZAudioPlayerDidChangePlayStateNotification
|
||||
object:self.player];
|
||||
|
||||
// This notification will only trigger if the player's shouldLoop property is set to NO
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(audioPlayerDidReachEndOfFile:)
|
||||
name:EZAudioPlayerDidReachEndOfFileNotification
|
||||
object:self.player];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayerDidChangeAudioFile:(NSNotification *)notification
|
||||
{
|
||||
EZAudioPlayer *player = [notification object];
|
||||
NSLog(@"Player changed audio file: %@", [player audioFile]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayerDidChangeOutputDevice:(NSNotification *)notification
|
||||
{
|
||||
EZAudioPlayer *player = [notification object];
|
||||
NSLog(@"Player changed output device: %@", [player device]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayerDidChangePlayState:(NSNotification *)notification
|
||||
{
|
||||
EZAudioPlayer *player = [notification object];
|
||||
NSLog(@"Player change play state, isPlaying: %i", [player isPlaying]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayerDidReachEndOfFile:(NSNotification *)notification
|
||||
{
|
||||
NSLog(@"Player did reach end of file!");
|
||||
[self.playButton setState:NSOffState];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -84,7 +157,7 @@
|
||||
- (void)changedOutput:(NSMenuItem *)item
|
||||
{
|
||||
EZAudioDevice *device = [item representedObject];
|
||||
[self.output setDevice:device];
|
||||
[self.player setDevice:device];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -107,10 +180,18 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)changeShouldLoop:(id)sender
|
||||
{
|
||||
NSInteger state = [(NSButton *)sender state];
|
||||
[self.player setShouldLoop:state];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)changeVolume:(id)sender
|
||||
{
|
||||
float value = [(NSSlider *)sender floatValue];
|
||||
[self.output setVolume:value];
|
||||
[self.player setVolume:value];
|
||||
self.volumeLabel.floatValue = value;
|
||||
}
|
||||
|
||||
@@ -142,7 +223,7 @@
|
||||
|
||||
-(void)play:(id)sender
|
||||
{
|
||||
if (![self.output isPlaying])
|
||||
if (![self.player isPlaying])
|
||||
{
|
||||
if (self.eof)
|
||||
{
|
||||
@@ -152,11 +233,11 @@
|
||||
{
|
||||
self.audioPlot.plotType = EZPlotTypeRolling;
|
||||
}
|
||||
[self.output startPlayback];
|
||||
[self.player play];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.output stopPlayback];
|
||||
[self.player pause];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +246,7 @@
|
||||
-(void)seekToFrame:(id)sender
|
||||
{
|
||||
double value = [(NSSlider*)sender doubleValue];
|
||||
[self.audioFile seekToFrame:(SInt64)value];
|
||||
[self.player seekToFrame:(SInt64)value];
|
||||
self.positionLabel.doubleValue = value;
|
||||
}
|
||||
|
||||
@@ -208,7 +289,7 @@
|
||||
//
|
||||
// Stop playback
|
||||
//
|
||||
[self.output stopPlayback];
|
||||
[self.player pause];
|
||||
|
||||
//
|
||||
// Clear the audio plot
|
||||
@@ -218,7 +299,7 @@
|
||||
//
|
||||
// Load the audio file and customize the UI
|
||||
//
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL delegate:self];
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL];
|
||||
self.eof = NO;
|
||||
self.filePathLabel.stringValue = filePathURL.lastPathComponent;
|
||||
self.positionSlider.minValue = 0.0f;
|
||||
@@ -226,30 +307,29 @@
|
||||
self.playButton.state = NSOffState;
|
||||
self.plotSegmentControl.selectedSegment = 1;
|
||||
|
||||
//
|
||||
// Set the client format from the EZAudioFile on the output
|
||||
//
|
||||
[self.output setInputFormat:self.audioFile.clientFormat];
|
||||
|
||||
//
|
||||
// Change back to a buffer plot, but mirror and fill the waveform
|
||||
//
|
||||
self.audioPlot.plotType = EZPlotTypeBuffer;
|
||||
self.audioPlot.shouldFill = YES;
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
[self.audioPlot clear];
|
||||
|
||||
//
|
||||
// Plot the whole waveform
|
||||
//
|
||||
__weak typeof (self) weakSelf = self;
|
||||
[self.audioFile getWaveformDataWithNumberOfPoints:256
|
||||
[self.audioFile getWaveformDataWithNumberOfPoints:1024
|
||||
completion:^(float **waveformData,
|
||||
int length)
|
||||
{
|
||||
[weakSelf.audioPlot updateBuffer:waveformData[0]
|
||||
withBufferSize:length];
|
||||
}];
|
||||
|
||||
//
|
||||
// Play the audio file
|
||||
//
|
||||
[self.player setAudioFile:self.audioFile];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -274,7 +354,7 @@
|
||||
// if you are connected to an external display by default the external
|
||||
// display's microphone might be used instead of the mac's built in
|
||||
// mic.
|
||||
if ([device isEqual:[self.output device]])
|
||||
if ([device isEqual:[self.player device]])
|
||||
{
|
||||
defaultOutputDeviceItem = item;
|
||||
}
|
||||
@@ -289,53 +369,14 @@
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFileDelegate
|
||||
#pragma mark - EZAudioPlayerDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void)audioFile:(EZAudioFile *)audioFile updatedPosition:(SInt64)framePosition
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (![weakSelf.positionSlider.cell isHighlighted])
|
||||
{
|
||||
weakSelf.positionSlider.floatValue = (float)framePosition;
|
||||
weakSelf.positionLabel.floatValue = (float)framePosition;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDataSource
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(OSStatus) output:(EZOutput *)output
|
||||
shouldFillAudioBufferList:(AudioBufferList *)audioBufferList
|
||||
withNumberOfFrames:(UInt32)frames
|
||||
timestamp:(const AudioTimeStamp *)timestamp
|
||||
{
|
||||
if (self.audioFile)
|
||||
{
|
||||
UInt32 bufferSize;
|
||||
[self.audioFile readFrames:frames
|
||||
audioBufferList:audioBufferList
|
||||
bufferSize:&bufferSize
|
||||
eof:&_eof];
|
||||
if (_eof)
|
||||
{
|
||||
[self seekToFrame:0];
|
||||
}
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) output:(EZOutput *)output
|
||||
- (void) audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
playedAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
inAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@@ -344,6 +385,22 @@
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
updatedPosition:(SInt64)framePosition
|
||||
inAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!weakSelf.positionSlider.highlighted)
|
||||
{
|
||||
weakSelf.positionSlider.floatValue = (float)framePosition;
|
||||
weakSelf.positionLabel.integerValue = framePosition;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - NSOpenSavePanelDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+245
-204
@@ -1,14 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="PlayFileViewController">
|
||||
<connections>
|
||||
<outlet property="audioPlot" destination="Lz1-Gs-1lD" id="V5w-yH-ZVR"/>
|
||||
<outlet property="checkboxButton" destination="5xb-MK-C8b" id="fx2-y9-qXH"/>
|
||||
<outlet property="filePathLabel" destination="0eT-7c-7fJ" id="IGv-mA-5Hw"/>
|
||||
<outlet property="loopCheckboxButton" destination="5xb-MK-C8b" id="Rlt-Z9-Zy8"/>
|
||||
<outlet property="outputDevicePopUpButton" destination="0LV-Bi-dGz" id="QTQ-qq-Ro8"/>
|
||||
<outlet property="playButton" destination="OQp-Lr-dlS" id="K5R-Qg-7DY"/>
|
||||
<outlet property="plotSegmentControl" destination="bZW-tA-C61" id="4ic-Ou-qh2"/>
|
||||
@@ -27,211 +29,250 @@
|
||||
<rect key="frame" x="0.0" y="-1" width="480" height="366"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Lz1-Gs-1lD" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="146"/>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Lz1-Gs-1lD" customClass="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="366"/>
|
||||
<subviews>
|
||||
<box autoresizesSubviews="NO" title="Box" boxType="custom" borderType="none" translatesAutoresizingMaskIntoConstraints="NO" id="woe-PM-Kco">
|
||||
<rect key="frame" x="0.0" y="124" width="480" height="242"/>
|
||||
<view key="contentView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="242"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2Ma-jj-U3z">
|
||||
<rect key="frame" x="12" y="172" width="125" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Choose File..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="KLq-bf-Xkh">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="openFile:" target="-2" id="3QB-hU-LDl"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0eT-7c-7fJ">
|
||||
<rect key="frame" x="140" y="184" width="36" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" sendsActionOnEndEditing="YES" alignment="left" title="Label" id="vXQ-HF-vLX">
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OQp-Lr-dlS">
|
||||
<rect key="frame" x="12" y="139" width="125" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Play" alternateTitle="Pause" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Z2A-7U-sb6">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="play:" target="-2" id="y83-JF-y4e"/>
|
||||
</connections>
|
||||
</button>
|
||||
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bZW-tA-C61">
|
||||
<rect key="frame" x="335" y="144" width="129" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="125" id="MeF-BC-3tU"/>
|
||||
</constraints>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="8U1-ER-vPJ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Buffer" selected="YES"/>
|
||||
<segment label="Rolling" tag="1"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="changePlotType:" target="-2" id="alU-Rf-22L"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<slider verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CFP-v0-TzQ">
|
||||
<rect key="frame" x="117" y="94" width="269" height="20"/>
|
||||
<sliderCell key="cell" continuous="YES" alignment="left" maxValue="100" doubleValue="9.3380614657210401" tickMarkPosition="above" sliderType="linear" id="gPc-pN-dmP"/>
|
||||
<connections>
|
||||
<action selector="seekToFrame:" target="-2" id="iVY-so-6X2"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<slider verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vj5-qT-JkR">
|
||||
<rect key="frame" x="117" y="69" width="269" height="20"/>
|
||||
<sliderCell key="cell" continuous="YES" alignment="left" minValue="128" maxValue="1024" doubleValue="128" tickMarkPosition="above" sliderType="linear" id="uRZ-Kf-cgJ"/>
|
||||
<connections>
|
||||
<action selector="changeRollingHistoryLength:" target="-2" id="eYD-H1-n52"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7AB-VA-xL3">
|
||||
<rect key="frame" x="16" y="121" width="53" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Volume:" id="GAa-Hp-OlV">
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Fw5-pm-4w0">
|
||||
<rect key="frame" x="16" y="96" width="58" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Position:" id="9hW-4Z-OEW">
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Aa9-nc-WHJ">
|
||||
<rect key="frame" x="16" y="71" width="96" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Rolling Length:" id="Mfs-zu-sCx">
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3ul-3w-l3S">
|
||||
<rect key="frame" x="390" y="121" width="72" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="68" id="H4m-6Q-Jin"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="0.00" id="vlK-Hb-Yca">
|
||||
<numberFormatter key="formatter" formatterBehavior="custom10_4" minimumIntegerDigits="1" maximumIntegerDigits="1" minimumFractionDigits="2" maximumFractionDigits="2" id="bBU-vS-tEB">
|
||||
<metadata>
|
||||
<real key="inspectorSampleValue" value="44"/>
|
||||
</metadata>
|
||||
</numberFormatter>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<slider verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rRH-oS-VV3">
|
||||
<rect key="frame" x="117" y="119" width="269" height="20"/>
|
||||
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="0.5" tickMarkPosition="above" sliderType="linear" id="xbX-Ce-da5"/>
|
||||
<connections>
|
||||
<action selector="changeVolume:" target="-2" id="iKx-7d-34D"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vKe-ey-hXI">
|
||||
<rect key="frame" x="390" y="71" width="72" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="0" id="JiA-3H-vb2">
|
||||
<numberFormatter key="formatter" formatterBehavior="custom10_4" minimumIntegerDigits="0" maximumIntegerDigits="42" id="AYM-Tu-k5w">
|
||||
<metadata>
|
||||
<real key="inspectorSampleValue" value="44"/>
|
||||
</metadata>
|
||||
</numberFormatter>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0LV-Bi-dGz" userLabel="microphoneInputPopUpButton">
|
||||
<rect key="frame" x="16" y="13" width="180" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="175" id="2C5-hq-caw"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="a7m-V2-Mw8" id="VLU-oW-zia">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="uLv-18-vra">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="a7m-V2-Mw8"/>
|
||||
<menuItem title="Item 2" id="qJe-zH-SrZ"/>
|
||||
<menuItem title="Item 3" id="zlE-dQ-R4x"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="RRH-G6-xkQ">
|
||||
<rect key="frame" x="16" y="46" width="50" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Output:" id="2OQ-1o-1vp">
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KYm-Io-VNv">
|
||||
<rect key="frame" x="390" y="96" width="72" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="0" id="gfS-wb-pFu">
|
||||
<numberFormatter key="formatter" formatterBehavior="custom10_4" minimumIntegerDigits="0" maximumIntegerDigits="42" id="py5-BY-fQN">
|
||||
<metadata>
|
||||
<real key="inspectorSampleValue" value="44"/>
|
||||
</metadata>
|
||||
</numberFormatter>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="5xb-MK-C8b">
|
||||
<rect key="frame" x="442" y="14" width="22" height="18"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="right" alignment="right" state="on" inset="2" id="O83-sN-k0z">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="changeShouldLoop:" target="-2" id="lJN-Pe-JWA"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TPR-Ta-wlb">
|
||||
<rect key="frame" x="407" y="16" width="35" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Loop" id="Tok-s1-Gjv">
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstItem="2Ma-jj-U3z" firstAttribute="leading" secondItem="OQp-Lr-dlS" secondAttribute="leading" id="65r-3l-UpC"/>
|
||||
<constraint firstItem="bZW-tA-C61" firstAttribute="top" secondItem="OQp-Lr-dlS" secondAttribute="top" id="68U-wj-F2c"/>
|
||||
<constraint firstItem="vKe-ey-hXI" firstAttribute="trailing" secondItem="KYm-Io-VNv" secondAttribute="trailing" id="6r9-KH-IXj"/>
|
||||
<constraint firstItem="RRH-G6-xkQ" firstAttribute="top" secondItem="Aa9-nc-WHJ" secondAttribute="bottom" constant="9" id="ARD-0e-VM7"/>
|
||||
<constraint firstItem="rRH-oS-VV3" firstAttribute="baseline" secondItem="7AB-VA-xL3" secondAttribute="baseline" id="ASG-bU-1Vn"/>
|
||||
<constraint firstItem="KYm-Io-VNv" firstAttribute="leading" secondItem="CFP-v0-TzQ" secondAttribute="trailing" constant="8" symbolic="YES" id="CvB-yq-Kw5"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bZW-tA-C61" secondAttribute="trailing" constant="18" id="DqD-RM-NfD"/>
|
||||
<constraint firstItem="0LV-Bi-dGz" firstAttribute="bottom" secondItem="5xb-MK-C8b" secondAttribute="bottom" id="Eo3-Ds-Pga"/>
|
||||
<constraint firstItem="7AB-VA-xL3" firstAttribute="leading" secondItem="Fw5-pm-4w0" secondAttribute="leading" id="F4w-hP-VrP"/>
|
||||
<constraint firstItem="vj5-qT-JkR" firstAttribute="baseline" secondItem="Aa9-nc-WHJ" secondAttribute="baseline" id="FyT-aB-ZMd"/>
|
||||
<constraint firstItem="Fw5-pm-4w0" firstAttribute="top" secondItem="7AB-VA-xL3" secondAttribute="bottom" constant="9" id="HHI-Px-CUW"/>
|
||||
<constraint firstItem="RRH-G6-xkQ" firstAttribute="leading" secondItem="0LV-Bi-dGz" secondAttribute="leading" id="Hpy-j7-Sn4"/>
|
||||
<constraint firstItem="0eT-7c-7fJ" firstAttribute="leading" secondItem="2Ma-jj-U3z" secondAttribute="trailing" constant="11" id="I84-HZ-kvK"/>
|
||||
<constraint firstItem="OQp-Lr-dlS" firstAttribute="trailing" secondItem="2Ma-jj-U3z" secondAttribute="trailing" id="JSU-sV-ydn"/>
|
||||
<constraint firstAttribute="bottom" secondItem="TPR-Ta-wlb" secondAttribute="bottom" constant="16" id="NHb-lI-raQ"/>
|
||||
<constraint firstItem="5xb-MK-C8b" firstAttribute="leading" secondItem="TPR-Ta-wlb" secondAttribute="trailing" constant="4" id="OcY-La-p2F"/>
|
||||
<constraint firstAttribute="bottom" secondItem="0LV-Bi-dGz" secondAttribute="bottom" constant="16" id="Su4-hr-dIF"/>
|
||||
<constraint firstItem="7AB-VA-xL3" firstAttribute="top" secondItem="OQp-Lr-dlS" secondAttribute="bottom" constant="9" id="U54-Sp-UR9"/>
|
||||
<constraint firstItem="KYm-Io-VNv" firstAttribute="baseline" secondItem="CFP-v0-TzQ" secondAttribute="baseline" id="WYP-6b-bar"/>
|
||||
<constraint firstItem="KYm-Io-VNv" firstAttribute="leading" secondItem="vKe-ey-hXI" secondAttribute="leading" id="WkB-Br-hx8"/>
|
||||
<constraint firstItem="CFP-v0-TzQ" firstAttribute="leading" secondItem="rRH-oS-VV3" secondAttribute="leading" id="YYb-HP-3oI"/>
|
||||
<constraint firstItem="0LV-Bi-dGz" firstAttribute="top" secondItem="RRH-G6-xkQ" secondAttribute="bottom" constant="9" id="ZW9-Wz-NjB"/>
|
||||
<constraint firstItem="bZW-tA-C61" firstAttribute="trailing" secondItem="5xb-MK-C8b" secondAttribute="trailing" id="a4v-Da-5OI"/>
|
||||
<constraint firstItem="vj5-qT-JkR" firstAttribute="leading" secondItem="Aa9-nc-WHJ" secondAttribute="trailing" constant="9" id="bJy-fK-Mgx"/>
|
||||
<constraint firstItem="rRH-oS-VV3" firstAttribute="baseline" secondItem="3ul-3w-l3S" secondAttribute="baseline" id="bfM-wb-rHx"/>
|
||||
<constraint firstItem="7AB-VA-xL3" firstAttribute="leading" secondItem="OQp-Lr-dlS" secondAttribute="leading" id="dta-hH-v59"/>
|
||||
<constraint firstItem="Fw5-pm-4w0" firstAttribute="leading" secondItem="Aa9-nc-WHJ" secondAttribute="leading" id="e3o-sk-vrf"/>
|
||||
<constraint firstItem="KYm-Io-VNv" firstAttribute="trailing" secondItem="3ul-3w-l3S" secondAttribute="trailing" id="eZB-I6-kCg"/>
|
||||
<constraint firstAttribute="height" constant="242" id="gIM-zm-GWO"/>
|
||||
<constraint firstItem="2Ma-jj-U3z" firstAttribute="top" secondItem="0eT-7c-7fJ" secondAttribute="top" id="hRy-MT-4On"/>
|
||||
<constraint firstItem="OQp-Lr-dlS" firstAttribute="top" secondItem="2Ma-jj-U3z" secondAttribute="bottom" constant="12" symbolic="YES" id="i9A-k5-5Qa"/>
|
||||
<constraint firstItem="3ul-3w-l3S" firstAttribute="leading" secondItem="KYm-Io-VNv" secondAttribute="leading" id="jNp-BV-Sn1"/>
|
||||
<constraint firstItem="CFP-v0-TzQ" firstAttribute="leading" secondItem="vj5-qT-JkR" secondAttribute="leading" id="jlK-cp-ukV"/>
|
||||
<constraint firstAttribute="trailing" secondItem="3ul-3w-l3S" secondAttribute="trailing" constant="20" id="lUf-2h-95p"/>
|
||||
<constraint firstItem="CFP-v0-TzQ" firstAttribute="baseline" secondItem="Fw5-pm-4w0" secondAttribute="baseline" id="lVm-7v-XFC"/>
|
||||
<constraint firstItem="Aa9-nc-WHJ" firstAttribute="top" secondItem="Fw5-pm-4w0" secondAttribute="bottom" constant="9" id="mep-8V-ybk"/>
|
||||
<constraint firstItem="2Ma-jj-U3z" firstAttribute="leading" secondItem="woe-PM-Kco" secondAttribute="leading" constant="18" id="ufW-Fo-f6i"/>
|
||||
<constraint firstItem="RRH-G6-xkQ" firstAttribute="leading" secondItem="Aa9-nc-WHJ" secondAttribute="leading" id="v6o-ED-CBK"/>
|
||||
<constraint firstItem="vKe-ey-hXI" firstAttribute="leading" secondItem="vj5-qT-JkR" secondAttribute="trailing" constant="8" symbolic="YES" id="x5P-WA-MWS"/>
|
||||
<constraint firstItem="3ul-3w-l3S" firstAttribute="leading" secondItem="rRH-oS-VV3" secondAttribute="trailing" constant="8" symbolic="YES" id="yQv-xx-Toh"/>
|
||||
<constraint firstItem="vj5-qT-JkR" firstAttribute="baseline" secondItem="vKe-ey-hXI" secondAttribute="baseline" id="ysL-Tn-bng"/>
|
||||
</constraints>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" red="0.0" green="0.0" blue="0.0" alpha="0.70000000000000007" colorSpace="calibratedRGB"/>
|
||||
</box>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="woe-PM-Kco" secondAttribute="trailing" id="IfY-Ff-46n"/>
|
||||
<constraint firstItem="woe-PM-Kco" firstAttribute="leading" secondItem="Lz1-Gs-1lD" secondAttribute="leading" id="UzR-Mq-ujC"/>
|
||||
<constraint firstItem="woe-PM-Kco" firstAttribute="top" secondItem="Lz1-Gs-1lD" secondAttribute="top" id="yqN-Hf-0Wn"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2Ma-jj-U3z">
|
||||
<rect key="frame" x="12" y="320" width="125" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Choose File..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="KLq-bf-Xkh">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="openFile:" target="-2" id="3QB-hU-LDl"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0eT-7c-7fJ">
|
||||
<rect key="frame" x="140" y="332" width="36" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" sendsActionOnEndEditing="YES" alignment="left" title="Label" id="vXQ-HF-vLX">
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OQp-Lr-dlS">
|
||||
<rect key="frame" x="12" y="287" width="125" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Play" alternateTitle="Pause" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Z2A-7U-sb6">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="play:" target="-2" id="y83-JF-y4e"/>
|
||||
</connections>
|
||||
</button>
|
||||
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bZW-tA-C61">
|
||||
<rect key="frame" x="335" y="292" width="129" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="125" id="A3V-sd-Jab"/>
|
||||
</constraints>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="8U1-ER-vPJ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Buffer" selected="YES"/>
|
||||
<segment label="Rolling" tag="1"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="changePlotType:" target="-2" id="alU-Rf-22L"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<slider verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CFP-v0-TzQ">
|
||||
<rect key="frame" x="117" y="242" width="269" height="20"/>
|
||||
<sliderCell key="cell" continuous="YES" alignment="left" maxValue="100" doubleValue="9.3380614657210401" tickMarkPosition="above" sliderType="linear" id="gPc-pN-dmP"/>
|
||||
<connections>
|
||||
<action selector="seekToFrame:" target="-2" id="iVY-so-6X2"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<slider verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vj5-qT-JkR">
|
||||
<rect key="frame" x="117" y="217" width="269" height="20"/>
|
||||
<sliderCell key="cell" continuous="YES" alignment="left" minValue="128" maxValue="1024" doubleValue="128" tickMarkPosition="above" sliderType="linear" id="uRZ-Kf-cgJ"/>
|
||||
<connections>
|
||||
<action selector="changeRollingHistoryLength:" target="-2" id="eYD-H1-n52"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7AB-VA-xL3">
|
||||
<rect key="frame" x="16" y="269" width="53" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Volume:" id="GAa-Hp-OlV">
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Fw5-pm-4w0">
|
||||
<rect key="frame" x="16" y="244" width="58" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Position:" id="9hW-4Z-OEW">
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Aa9-nc-WHJ">
|
||||
<rect key="frame" x="16" y="219" width="96" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Rolling Length:" id="Mfs-zu-sCx">
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3ul-3w-l3S">
|
||||
<rect key="frame" x="390" y="269" width="72" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="68" id="eyi-2x-AqF"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="0.00" id="vlK-Hb-Yca">
|
||||
<numberFormatter key="formatter" formatterBehavior="custom10_4" minimumIntegerDigits="1" maximumIntegerDigits="1" minimumFractionDigits="2" maximumFractionDigits="2" id="bBU-vS-tEB">
|
||||
<metadata>
|
||||
<real key="inspectorSampleValue" value="44"/>
|
||||
</metadata>
|
||||
</numberFormatter>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<slider verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rRH-oS-VV3">
|
||||
<rect key="frame" x="117" y="267" width="269" height="20"/>
|
||||
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="0.5" tickMarkPosition="above" sliderType="linear" id="xbX-Ce-da5"/>
|
||||
<connections>
|
||||
<action selector="changeVolume:" target="-2" id="iKx-7d-34D"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vKe-ey-hXI">
|
||||
<rect key="frame" x="390" y="219" width="72" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="68" id="7dV-vH-IBh"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="0" id="JiA-3H-vb2">
|
||||
<numberFormatter key="formatter" formatterBehavior="custom10_4" minimumIntegerDigits="0" maximumIntegerDigits="42" id="AYM-Tu-k5w">
|
||||
<metadata>
|
||||
<real key="inspectorSampleValue" value="44"/>
|
||||
</metadata>
|
||||
</numberFormatter>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0LV-Bi-dGz" userLabel="microphoneInputPopUpButton">
|
||||
<rect key="frame" x="16" y="161" width="180" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="175" id="fDF-j7-LMD"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="a7m-V2-Mw8" id="VLU-oW-zia">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="uLv-18-vra">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="a7m-V2-Mw8"/>
|
||||
<menuItem title="Item 2" id="qJe-zH-SrZ"/>
|
||||
<menuItem title="Item 3" id="zlE-dQ-R4x"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="RRH-G6-xkQ">
|
||||
<rect key="frame" x="16" y="194" width="50" height="16"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Output:" id="2OQ-1o-1vp">
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KYm-Io-VNv">
|
||||
<rect key="frame" x="390" y="244" width="72" height="16"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="68" id="fOV-38-VqQ"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="0" id="gfS-wb-pFu">
|
||||
<numberFormatter key="formatter" formatterBehavior="custom10_4" minimumIntegerDigits="0" maximumIntegerDigits="42" id="py5-BY-fQN">
|
||||
<metadata>
|
||||
<real key="inspectorSampleValue" value="44"/>
|
||||
</metadata>
|
||||
</numberFormatter>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="vKe-ey-hXI" firstAttribute="baseline" secondItem="vj5-qT-JkR" secondAttribute="baseline" id="03u-fe-Q2r"/>
|
||||
<constraint firstItem="vj5-qT-JkR" firstAttribute="leading" secondItem="Aa9-nc-WHJ" secondAttribute="trailing" constant="9" id="0QT-jZ-rPL"/>
|
||||
<constraint firstItem="rRH-oS-VV3" firstAttribute="baseline" secondItem="7AB-VA-xL3" secondAttribute="baseline" id="4WU-L2-5TI"/>
|
||||
<constraint firstItem="3ul-3w-l3S" firstAttribute="trailing" secondItem="bZW-tA-C61" secondAttribute="trailing" constant="-2" id="75o-B9-UmY"/>
|
||||
<constraint firstItem="vj5-qT-JkR" firstAttribute="baseline" secondItem="Aa9-nc-WHJ" secondAttribute="baseline" id="8ia-fE-3Ej"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Lz1-Gs-1lD" secondAttribute="bottom" id="Cdp-xg-Udu"/>
|
||||
<constraint firstItem="0eT-7c-7fJ" firstAttribute="leading" secondItem="2Ma-jj-U3z" secondAttribute="trailing" constant="11" id="F4y-lz-2p6"/>
|
||||
<constraint firstItem="7AB-VA-xL3" firstAttribute="top" secondItem="OQp-Lr-dlS" secondAttribute="bottom" constant="9" id="GbY-7Z-81V"/>
|
||||
<constraint firstItem="Lz1-Gs-1lD" firstAttribute="leading" secondItem="Xpo-HP-Ost" secondAttribute="leading" id="HW1-t3-mGg"/>
|
||||
<constraint firstItem="OQp-Lr-dlS" firstAttribute="leading" secondItem="2Ma-jj-U3z" secondAttribute="leading" id="Ira-0b-xzU"/>
|
||||
<constraint firstItem="rRH-oS-VV3" firstAttribute="baseline" secondItem="3ul-3w-l3S" secondAttribute="baseline" id="KOD-cZ-e52"/>
|
||||
<constraint firstItem="CFP-v0-TzQ" firstAttribute="baseline" secondItem="Fw5-pm-4w0" secondAttribute="baseline" id="PbC-KG-EzE"/>
|
||||
<constraint firstItem="2Ma-jj-U3z" firstAttribute="leading" secondItem="Xpo-HP-Ost" secondAttribute="leading" constant="18" id="PiQ-KC-eta"/>
|
||||
<constraint firstItem="Fw5-pm-4w0" firstAttribute="top" secondItem="7AB-VA-xL3" secondAttribute="bottom" constant="9" id="SPP-F6-chs"/>
|
||||
<constraint firstItem="vj5-qT-JkR" firstAttribute="trailing" secondItem="CFP-v0-TzQ" secondAttribute="trailing" id="URd-7z-JBO"/>
|
||||
<constraint firstItem="RRH-G6-xkQ" firstAttribute="leading" secondItem="Xpo-HP-Ost" secondAttribute="leading" constant="18" id="WiW-CU-B7N"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Lz1-Gs-1lD" secondAttribute="trailing" id="ay9-Mt-iFx"/>
|
||||
<constraint firstItem="rRH-oS-VV3" firstAttribute="leading" secondItem="CFP-v0-TzQ" secondAttribute="leading" id="cWn-4f-E04"/>
|
||||
<constraint firstItem="Fw5-pm-4w0" firstAttribute="leading" secondItem="Aa9-nc-WHJ" secondAttribute="leading" id="cnU-xS-2CO"/>
|
||||
<constraint firstItem="KYm-Io-VNv" firstAttribute="leading" secondItem="3ul-3w-l3S" secondAttribute="leading" id="dac-nA-d4U"/>
|
||||
<constraint firstItem="0LV-Bi-dGz" firstAttribute="top" secondItem="RRH-G6-xkQ" secondAttribute="bottom" constant="9" id="dnZ-Rx-iiV"/>
|
||||
<constraint firstItem="Aa9-nc-WHJ" firstAttribute="top" secondItem="Fw5-pm-4w0" secondAttribute="bottom" constant="9" id="fc6-dV-Lxf"/>
|
||||
<constraint firstItem="vKe-ey-hXI" firstAttribute="leading" secondItem="vj5-qT-JkR" secondAttribute="trailing" constant="8" symbolic="YES" id="fuB-es-weU"/>
|
||||
<constraint firstItem="2Ma-jj-U3z" firstAttribute="top" secondItem="Xpo-HP-Ost" secondAttribute="top" constant="18" id="hDY-vI-eWO"/>
|
||||
<constraint firstItem="OQp-Lr-dlS" firstAttribute="trailing" secondItem="2Ma-jj-U3z" secondAttribute="trailing" id="hXB-Gp-9wN"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bZW-tA-C61" secondAttribute="trailing" constant="18" id="iUL-br-ASL"/>
|
||||
<constraint firstItem="OQp-Lr-dlS" firstAttribute="top" secondItem="bZW-tA-C61" secondAttribute="top" id="kny-zR-hiF"/>
|
||||
<constraint firstItem="Lz1-Gs-1lD" firstAttribute="top" secondItem="0LV-Bi-dGz" secondAttribute="bottom" constant="18" id="l6M-H0-bYA"/>
|
||||
<constraint firstItem="7AB-VA-xL3" firstAttribute="leading" secondItem="OQp-Lr-dlS" secondAttribute="leading" id="omq-Zw-Gvk"/>
|
||||
<constraint firstItem="KYm-Io-VNv" firstAttribute="baseline" secondItem="CFP-v0-TzQ" secondAttribute="baseline" id="q8e-0e-Xqt"/>
|
||||
<constraint firstItem="0eT-7c-7fJ" firstAttribute="top" secondItem="2Ma-jj-U3z" secondAttribute="top" id="snu-Ma-cHX"/>
|
||||
<constraint firstItem="OQp-Lr-dlS" firstAttribute="top" secondItem="2Ma-jj-U3z" secondAttribute="bottom" constant="12" symbolic="YES" id="tkR-bR-msf"/>
|
||||
<constraint firstItem="0LV-Bi-dGz" firstAttribute="leading" secondItem="Xpo-HP-Ost" secondAttribute="leading" constant="18" id="tmm-8d-ldM"/>
|
||||
<constraint firstItem="3ul-3w-l3S" firstAttribute="leading" secondItem="rRH-oS-VV3" secondAttribute="trailing" constant="8" id="uF6-oM-5lN"/>
|
||||
<constraint firstItem="Fw5-pm-4w0" firstAttribute="leading" secondItem="7AB-VA-xL3" secondAttribute="leading" id="vNA-c3-Gcy"/>
|
||||
<constraint firstItem="RRH-G6-xkQ" firstAttribute="top" secondItem="Aa9-nc-WHJ" secondAttribute="bottom" constant="9" id="w92-Np-SYg"/>
|
||||
<constraint firstItem="rRH-oS-VV3" firstAttribute="trailing" secondItem="CFP-v0-TzQ" secondAttribute="trailing" id="wdS-Vt-caT"/>
|
||||
<constraint firstItem="vj5-qT-JkR" firstAttribute="leading" secondItem="CFP-v0-TzQ" secondAttribute="leading" id="wek-S9-BzW"/>
|
||||
<constraint firstItem="Lz1-Gs-1lD" firstAttribute="leading" secondItem="Xpo-HP-Ost" secondAttribute="leading" id="Edu-Ye-wV8"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Lz1-Gs-1lD" secondAttribute="bottom" id="UV6-Xh-8m0"/>
|
||||
<constraint firstItem="Lz1-Gs-1lD" firstAttribute="top" secondItem="Xpo-HP-Ost" secondAttribute="top" id="b4I-Py-1Kt"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Lz1-Gs-1lD" secondAttribute="trailing" id="ges-aT-5L1"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="191" y="409"/>
|
||||
</customView>
|
||||
|
||||
-6
@@ -16,7 +16,6 @@
|
||||
66755AE21B3B79230013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755AC51B3B79220013E67E /* EZAudioPlayer.m */; };
|
||||
66755AE31B3B79230013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755AC71B3B79220013E67E /* EZAudioPlot.m */; };
|
||||
66755AE41B3B79230013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755AC91B3B79220013E67E /* EZAudioPlotGL.m */; };
|
||||
66755AE51B3B79230013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755ACB1B3B79220013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
66755AE61B3B79230013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755ACD1B3B79220013E67E /* EZAudioUtilities.m */; };
|
||||
66755AE71B3B79230013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755ACF1B3B79230013E67E /* EZMicrophone.m */; };
|
||||
66755AE81B3B79230013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755AD11B3B79230013E67E /* EZOutput.m */; };
|
||||
@@ -76,8 +75,6 @@
|
||||
66755AC71B3B79220013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
66755AC81B3B79220013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
66755AC91B3B79220013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
66755ACA1B3B79220013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
66755ACB1B3B79220013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
66755ACC1B3B79220013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
66755ACD1B3B79220013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
66755ACE1B3B79230013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -172,8 +169,6 @@
|
||||
66755AC71B3B79220013E67E /* EZAudioPlot.m */,
|
||||
66755AC81B3B79220013E67E /* EZAudioPlotGL.h */,
|
||||
66755AC91B3B79220013E67E /* EZAudioPlotGL.m */,
|
||||
66755ACA1B3B79220013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
66755ACB1B3B79220013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
66755ACC1B3B79220013E67E /* EZAudioUtilities.h */,
|
||||
66755ACD1B3B79220013E67E /* EZAudioUtilities.m */,
|
||||
66755ACE1B3B79230013E67E /* EZMicrophone.h */,
|
||||
@@ -398,7 +393,6 @@
|
||||
66755AE21B3B79230013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056E74185BB44200EB94BA /* RecordViewController.m in Sources */,
|
||||
66755AE41B3B79230013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
66755AE51B3B79230013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
66755ADF1B3B79230013E67E /* EZAudioFile.m in Sources */,
|
||||
66755AE81B3B79230013E67E /* EZOutput.m in Sources */,
|
||||
66755AE61B3B79230013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
@implementation AppDelegate
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
|
||||
{
|
||||
// Swap in our view controller in the window's content view
|
||||
self.recordViewController = [[RecordViewController alloc] init];
|
||||
// Resize view controller to content view's current size
|
||||
|
||||
+341
-141
@@ -1,100 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4439" systemVersion="13A451" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4439"/>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" destination="58" id="142"/>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder">
|
||||
<connections>
|
||||
<action selector="alignCenter:" destination="499" id="518"/>
|
||||
<action selector="alignJustified:" destination="500" id="523"/>
|
||||
<action selector="alignLeft:" destination="498" id="524"/>
|
||||
<action selector="alignRight:" destination="501" id="521"/>
|
||||
<action selector="arrangeInFront:" destination="5" id="39"/>
|
||||
<action selector="capitalizeWord:" destination="466" id="467"/>
|
||||
<action selector="centerSelectionInVisibleArea:" destination="210" id="245"/>
|
||||
<action selector="checkSpelling:" destination="201" id="225"/>
|
||||
<action selector="clearRecentDocuments:" destination="126" id="127"/>
|
||||
<action selector="copy:" destination="197" id="224"/>
|
||||
<action selector="copyFont:" destination="403" id="428"/>
|
||||
<action selector="copyRuler:" destination="506" id="522"/>
|
||||
<action selector="cut:" destination="199" id="228"/>
|
||||
<action selector="delete:" destination="202" id="235"/>
|
||||
<action selector="hide:" destination="134" id="367"/>
|
||||
<action selector="hideOtherApplications:" destination="145" id="368"/>
|
||||
<action selector="loosenKerning:" destination="419" id="435"/>
|
||||
<action selector="lowerBaseline:" destination="410" id="427"/>
|
||||
<action selector="lowercaseWord:" destination="465" id="468"/>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" destination="511" id="526"/>
|
||||
<action selector="makeBaseWritingDirectionNatural:" destination="510" id="525"/>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" destination="512" id="527"/>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" destination="516" id="529"/>
|
||||
<action selector="makeTextWritingDirectionNatural:" destination="515" id="528"/>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" destination="517" id="530"/>
|
||||
<action selector="newDocument:" destination="82" id="373"/>
|
||||
<action selector="openDocument:" destination="72" id="374"/>
|
||||
<action selector="orderFrontColorPanel:" destination="401" id="433"/>
|
||||
<action selector="orderFrontSubstitutionsPanel:" destination="457" id="458"/>
|
||||
<action selector="paste:" destination="203" id="226"/>
|
||||
<action selector="pasteAsPlainText:" destination="485" id="486"/>
|
||||
<action selector="pasteFont:" destination="404" id="436"/>
|
||||
<action selector="pasteRuler:" destination="507" id="519"/>
|
||||
<action selector="performClose:" destination="73" id="193"/>
|
||||
<action selector="performFindPanelAction:" destination="209" id="241"/>
|
||||
<action selector="performFindPanelAction:" destination="208" id="487"/>
|
||||
<action selector="performFindPanelAction:" destination="213" id="488"/>
|
||||
<action selector="performFindPanelAction:" destination="221" id="489"/>
|
||||
<action selector="performFindPanelAction:" destination="534" id="535"/>
|
||||
<action selector="performMiniaturize:" destination="23" id="37"/>
|
||||
<action selector="performZoom:" destination="239" id="240"/>
|
||||
<action selector="print:" destination="78" id="86"/>
|
||||
<action selector="raiseBaseline:" destination="409" id="426"/>
|
||||
<action selector="redo:" destination="215" id="231"/>
|
||||
<action selector="revertDocumentToSaved:" destination="112" id="364"/>
|
||||
<action selector="runPageLayout:" destination="77" id="87"/>
|
||||
<action selector="runToolbarCustomizationPalette:" destination="298" id="365"/>
|
||||
<action selector="saveDocument:" destination="75" id="362"/>
|
||||
<action selector="selectAll:" destination="198" id="232"/>
|
||||
<action selector="showGuessPanel:" destination="204" id="230"/>
|
||||
<action selector="showHelp:" destination="492" id="493"/>
|
||||
<action selector="startSpeaking:" destination="196" id="233"/>
|
||||
<action selector="stopSpeaking:" destination="195" id="227"/>
|
||||
<action selector="subscript:" destination="408" id="429"/>
|
||||
<action selector="superscript:" destination="407" id="430"/>
|
||||
<action selector="tightenKerning:" destination="418" id="431"/>
|
||||
<action selector="toggleAutomaticDashSubstitution:" destination="460" id="461"/>
|
||||
<action selector="toggleAutomaticLinkDetection:" destination="354" id="357"/>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" destination="351" id="356"/>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" destination="454" id="456"/>
|
||||
<action selector="toggleAutomaticTextReplacement:" destination="462" id="463"/>
|
||||
<action selector="toggleContinuousSpellChecking:" destination="219" id="222"/>
|
||||
<action selector="toggleGrammarChecking:" destination="346" id="347"/>
|
||||
<action selector="toggleRuler:" destination="505" id="520"/>
|
||||
<action selector="toggleSmartInsertDelete:" destination="350" id="355"/>
|
||||
<action selector="toggleToolbarShown:" destination="297" id="366"/>
|
||||
<action selector="turnOffKerning:" destination="417" id="441"/>
|
||||
<action selector="turnOffLigatures:" destination="413" id="440"/>
|
||||
<action selector="underline:" destination="392" id="432"/>
|
||||
<action selector="undo:" destination="207" id="223"/>
|
||||
<action selector="unhideAllApplications:" destination="150" id="370"/>
|
||||
<action selector="unscript:" destination="406" id="437"/>
|
||||
<action selector="uppercaseWord:" destination="452" id="464"/>
|
||||
<action selector="useAllLigatures:" destination="414" id="434"/>
|
||||
<action selector="useStandardKerning:" destination="416" id="438"/>
|
||||
<action selector="useStandardLigatures:" destination="412" id="439"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-3" userLabel="Application">
|
||||
<connections>
|
||||
<action selector="terminate:" destination="136" id="449"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="EZAudioRecordExample" id="56">
|
||||
@@ -102,6 +19,9 @@
|
||||
<items>
|
||||
<menuItem title="About EZAudioRecordExample" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
@@ -116,95 +36,211 @@
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide EZAudioRecordExample" keyEquivalent="h" id="134"/>
|
||||
<menuItem title="Hide EZAudioRecordExample" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150">
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150"/>
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit EZAudioRecordExample" keyEquivalent="q" id="136"/>
|
||||
<menuItem title="Quit EZAudioRecordExample" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-3" id="449"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="83">
|
||||
<menu key="submenu" title="File" id="81">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="82"/>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72"/>
|
||||
<menuItem title="New" keyEquivalent="n" id="82">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="373"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="374"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="124">
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="126"/>
|
||||
<menuItem title="Clear Menu" id="126">
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="127"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73"/>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="193"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="362"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="-1" id="87"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78">
|
||||
<connections>
|
||||
<action selector="print:" target="-1" id="86"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207"/>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="223"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="231"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199"/>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197"/>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="228"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="224"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="226"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="486"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202">
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="235"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="232"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202"/>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198"/>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209"/>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="241"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="535"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="487"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208"/>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="488"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="489"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221"/>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="216">
|
||||
<menu key="submenu" title="Spelling and Grammar" id="200">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204"/>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201"/>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="230"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="225"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="453"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219"/>
|
||||
<menuItem title="Check Grammar With Spelling" id="346"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219">
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="346">
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="454">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="456"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -214,18 +250,38 @@
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="457">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="458"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350"/>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="460">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="461"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="462">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="463"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -236,12 +292,21 @@
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="452">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="464"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="465">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="468"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="466">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="467"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -249,8 +314,16 @@
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="196"/>
|
||||
<menuItem title="Stop Speaking" id="195"/>
|
||||
<menuItem title="Start Speaking" id="196">
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="233"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="195">
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="227"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -265,13 +338,37 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389"/>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390"/>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391"/>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392"/>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="420" id="424"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="421"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="422"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="432"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="393"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394"/>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="425"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="423"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="396"/>
|
||||
<menuItem title="Kern" id="397">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -279,15 +376,27 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="416">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="438"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="417">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="441"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="418">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="431"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="419">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="435"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -298,12 +407,21 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="412">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="439"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="413">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="440"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="414">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="434"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -314,30 +432,55 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="406">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="437"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="407">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="430"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="408">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="429"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="409">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="426"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="410">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="427"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="400"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="402"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="428"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="436"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -346,12 +489,27 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498"/>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499"/>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="524"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="518"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="500">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="523"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="521"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501"/>
|
||||
<menuItem isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -363,14 +521,23 @@
|
||||
<menuItem id="510">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="511">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="512">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="527"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="513"/>
|
||||
<menuItem title="Selection" enabled="NO" id="514">
|
||||
@@ -379,14 +546,23 @@
|
||||
<menuItem id="515">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="516">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="517">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="530"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -394,12 +570,21 @@
|
||||
<menuItem isSeparatorItem="YES" id="504"/>
|
||||
<menuItem title="Show Ruler" id="505">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="520"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="522"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="519"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -412,20 +597,39 @@
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298">
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23"/>
|
||||
<menuItem title="Zoom" id="239"/>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="37"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="239">
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="240"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5"/>
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -433,17 +637,21 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="EZAudioRecordExample Help" keyEquivalent="?" id="492"/>
|
||||
<menuItem title="EZAudioRecordExample Help" keyEquivalent="?" id="492">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="EZAudioRecordExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" fullSizeContentView="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
@@ -454,14 +662,6 @@
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" destination="390" id="421"/>
|
||||
<action selector="addFontTrait:" destination="391" id="422"/>
|
||||
<action selector="modifyFont:" destination="395" id="423"/>
|
||||
<action selector="modifyFont:" destination="394" id="425"/>
|
||||
<action selector="orderFrontFontPanel:" destination="389" id="424"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager"/>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
+76
-11
@@ -28,51 +28,116 @@
|
||||
// Import EZAudio header
|
||||
#import "EZAudio.h"
|
||||
|
||||
// Import AVFoundation to play the file (will save EZAudioFile and EZOutput for separate example)
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
// By default this will record a file to /Users/YOUR_USERNAME/Documents/test.caf
|
||||
#define kAudioFilePath [NSString stringWithFormat:@"%@%@",NSHomeDirectory(),@"/Documents/test.m4a"]
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - RecordViewController
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
We will allow this view controller to act as an EZMicrophoneDelegate. This is how we listen for the microphone callback.
|
||||
*/
|
||||
@interface RecordViewController : NSViewController <EZMicrophoneDelegate,AVAudioPlayerDelegate>
|
||||
@interface RecordViewController : NSViewController <EZAudioPlayerDelegate,
|
||||
EZMicrophoneDelegate,
|
||||
EZRecorderDelegate>
|
||||
|
||||
/**
|
||||
The label used to display the current time for recording/playback in the top left
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSTextField *currentTimeLabel;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Use a OpenGL based plot to visualize the data coming in
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlotGL *audioPlot;
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlotGL *recordingAudioPlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A flag indicating whether we are recording or not
|
||||
*/
|
||||
@property (nonatomic,assign) BOOL isRecording;
|
||||
@property (nonatomic, assign) BOOL isRecording;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The microphone component
|
||||
*/
|
||||
@property (nonatomic,strong) EZMicrophone *microphone;
|
||||
@property (nonatomic, strong) EZMicrophone *microphone;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The switch used to toggle the microphone on/off
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSButton *microphoneSwitch;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The audio player that will play the recorded file
|
||||
*/
|
||||
@property (nonatomic, strong) EZAudioPlayer *player;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The recorder component
|
||||
*/
|
||||
@property (nonatomic,strong) EZRecorder *recorder;
|
||||
@property (nonatomic, strong) EZRecorder *recorder;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The second audio plot used on the top right to display the current playing audio
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlot *playingAudioPlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The button the user taps to play the recorded audio file
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSButton *playButton;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The label used to display the audio player play state
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSTextField *playingStateLabel;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The switch used to toggle the recording on/off
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSButton *recordSwitch;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Stops the recorder and starts playing whatever has been recorded.
|
||||
*/
|
||||
-(IBAction)playFile:(id)sender;
|
||||
- (IBAction)playFile:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Toggles the microphone on and off. When the microphone is on it will send its delegate (aka this view controller) the audio data in various ways (check out the EZMicrophoneDelegate documentation for more details);
|
||||
*/
|
||||
-(IBAction)toggleMicrophone:(id)sender;
|
||||
- (IBAction)toggleMicrophone:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Toggles the microphone on and off. When the microphone is on it will send its delegate (aka this view controller) the audio data in various ways (check out the EZMicrophoneDelegate documentation for more details);
|
||||
*/
|
||||
-(IBAction)toggleRecording:(id)sender;
|
||||
- (IBAction)toggleRecording:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
+195
-109
@@ -25,12 +25,9 @@
|
||||
|
||||
#import "RecordViewController.h"
|
||||
|
||||
@interface RecordViewController ()
|
||||
@property (nonatomic,strong) AVAudioPlayer *audioPlayer;
|
||||
@property (nonatomic,weak) IBOutlet NSButton *microphoneToggle;
|
||||
@property (nonatomic,weak) IBOutlet NSButton *playButton;
|
||||
@property (nonatomic,weak) IBOutlet NSButton *recordingToggle;
|
||||
@end
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - RecordViewController (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation RecordViewController
|
||||
|
||||
@@ -38,52 +35,106 @@
|
||||
#pragma mark - Customize the Audio Plot
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void)awakeFromNib
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
/*
|
||||
Customizing the audio plot's look
|
||||
*/
|
||||
// Background color
|
||||
self.audioPlot.backgroundColor = [NSColor colorWithCalibratedRed: 0.984 green: 0.71 blue: 0.365 alpha: 1];
|
||||
// Waveform color
|
||||
self.audioPlot.color = [NSColor colorWithCalibratedRed: 1.000 green: 1.000 blue: 1.000 alpha: 1];
|
||||
// Plot type
|
||||
self.audioPlot.plotType = EZPlotTypeRolling;
|
||||
// Fill
|
||||
self.audioPlot.shouldFill = YES;
|
||||
// Mirror
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
|
||||
//
|
||||
// Customizing the audio plot that'll show the current microphone input/recording
|
||||
//
|
||||
self.recordingAudioPlot.backgroundColor = [NSColor colorWithRed: 0.984 green: 0.71 blue: 0.365 alpha: 1];
|
||||
self.recordingAudioPlot.color = [NSColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
self.recordingAudioPlot.plotType = EZPlotTypeRolling;
|
||||
self.recordingAudioPlot.shouldFill = YES;
|
||||
self.recordingAudioPlot.shouldMirror = YES;
|
||||
|
||||
//
|
||||
// Customizing the audio plot that'll show the playback
|
||||
//
|
||||
self.playingAudioPlot.color = [NSColor whiteColor];
|
||||
self.playingAudioPlot.plotType = EZPlotTypeRolling;
|
||||
self.playingAudioPlot.shouldFill = YES;
|
||||
self.playingAudioPlot.shouldMirror = YES;
|
||||
self.playingAudioPlot.gain = 2.5f;
|
||||
|
||||
// Create an instance of the microphone and tell it to use this view controller instance as the delegate
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self];
|
||||
self.player = [EZAudioPlayer audioPlayerWithDelegate:self];
|
||||
|
||||
//
|
||||
// Initialize UI components
|
||||
//
|
||||
[self setTitle:@"Microphone On" forButton:self.microphoneSwitch];
|
||||
[self setTitle:@"Not Recording" forButton:self.recordSwitch];
|
||||
self.playingStateLabel.stringValue = @"Not Playing";
|
||||
self.playButton.enabled = NO;
|
||||
|
||||
//
|
||||
// Setup notifications
|
||||
//
|
||||
[self setupNotifications];
|
||||
|
||||
//
|
||||
// Start the microphone
|
||||
//
|
||||
[self.microphone startFetchingAudio];
|
||||
}
|
||||
|
||||
// Configure the play button
|
||||
[self.playButton setHidden:YES];
|
||||
|
||||
/*
|
||||
Start the microphone
|
||||
*/
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self startsImmediately:YES];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setupNotifications
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(playerDidChangePlayState:)
|
||||
name:EZAudioPlayerDidChangePlayStateNotification
|
||||
object:self.player];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(playerDidReachEndOfFile:)
|
||||
name:EZAudioPlayerDidReachEndOfFileNotification
|
||||
object:self.player];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Notifications
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)playerDidChangePlayState:(NSNotification *)notification
|
||||
{
|
||||
EZAudioPlayer *player = [notification object];
|
||||
BOOL isPlaying = [player isPlaying];
|
||||
if (isPlaying)
|
||||
{
|
||||
self.recorder.delegate = nil;
|
||||
}
|
||||
self.playingStateLabel.stringValue = isPlaying ? @"Playing" : @"Not Playing";
|
||||
self.playingAudioPlot.hidden = !isPlaying;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)playerDidReachEndOfFile:(NSNotification *)notification
|
||||
{
|
||||
[self.playingAudioPlot clear];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void)playFile:(id)sender
|
||||
- (void)playFile:(id)sender
|
||||
{
|
||||
//
|
||||
// Update microphone state
|
||||
//
|
||||
[self.microphone stopFetchingAudio];
|
||||
self.microphoneToggle.state = NSOffState;
|
||||
[self.microphoneToggle setEnabled:NO];
|
||||
|
||||
|
||||
//
|
||||
// Update recording state
|
||||
//
|
||||
self.isRecording = NO;
|
||||
self.recordingToggle.state = NSOffState;
|
||||
[self.recordingToggle setEnabled:NO];
|
||||
|
||||
[self setTitle:@"Not Recording" forButton:self.recordSwitch];
|
||||
self.recordSwitch.state = NSOffState;
|
||||
|
||||
//
|
||||
// Close the audio file
|
||||
//
|
||||
@@ -92,122 +143,157 @@
|
||||
[self.recorder closeAudioFile];
|
||||
}
|
||||
|
||||
//
|
||||
// Create audio player
|
||||
//
|
||||
if (self.audioPlayer)
|
||||
{
|
||||
if (self.audioPlayer.playing) [self.audioPlayer stop];
|
||||
self.audioPlayer = nil;
|
||||
}
|
||||
NSError *err;
|
||||
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:kAudioFilePath]
|
||||
error:&err];
|
||||
EZAudioFile *audioFile = [EZAudioFile audioFileWithURL:[NSURL fileURLWithPath:kAudioFilePath]];
|
||||
[self.player playAudioFile:audioFile];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)toggleMicrophone:(id)sender
|
||||
{
|
||||
[self.player pause];
|
||||
|
||||
[self.audioPlayer play];
|
||||
self.audioPlayer.delegate = self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void)toggleMicrophone:(id)sender
|
||||
{
|
||||
switch([sender state])
|
||||
NSInteger state = [(NSButton *)sender state];
|
||||
if (state == NSOffState)
|
||||
{
|
||||
case NSOffState:
|
||||
[self.microphone stopFetchingAudio];
|
||||
break;
|
||||
case NSOnState:
|
||||
[self.microphone startFetchingAudio];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
[self.microphone stopFetchingAudio];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.microphone startFetchingAudio];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void)toggleRecording:(id)sender
|
||||
- (void)toggleRecording:(id)sender
|
||||
{
|
||||
[self.playButton setHidden:NO];
|
||||
switch( [sender state])
|
||||
[self.player pause];
|
||||
|
||||
NSInteger state = [(NSButton *)sender state];
|
||||
if (state == NSOnState)
|
||||
{
|
||||
case NSOffState:
|
||||
[self.recorder closeAudioFile];
|
||||
break;
|
||||
case NSOnState:
|
||||
/*
|
||||
Create the recorder
|
||||
*/
|
||||
self.recorder = [EZRecorder recorderWithDestinationURL:[NSURL fileURLWithPath:kAudioFilePath]
|
||||
sourceFormat:[self.microphone audioStreamBasicDescription]
|
||||
destinationFileType:EZRecorderFileTypeM4A];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
//
|
||||
// Create the recorder
|
||||
//
|
||||
[self.microphone startFetchingAudio];
|
||||
self.recorder = [EZRecorder recorderWithURL:[NSURL fileURLWithPath:kAudioFilePath]
|
||||
clientFormat:[self.microphone audioStreamBasicDescription]
|
||||
fileType:EZRecorderFileTypeM4A
|
||||
delegate:self];
|
||||
self.playButton.enabled = YES;
|
||||
}
|
||||
self.isRecording = (BOOL)[sender state];
|
||||
self.isRecording = state;
|
||||
NSString *title = self.isRecording ? @"Recording" : @"Not Recording";
|
||||
[self setTitle:title forButton:self.recordSwitch];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)microphone:(EZMicrophone *)microphone changedPlayingState:(BOOL)isPlaying
|
||||
{
|
||||
self.microphoneSwitch.state = isPlaying;
|
||||
NSString *title = isPlaying ? @"Microphone On" : @"Microphone Off";
|
||||
[self setTitle:title forButton:self.microphoneSwitch];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#warning Thread Safety
|
||||
// Note that any callback that provides streamed audio data (like streaming microphone input) happens on a separate audio thread that should not be blocked. When we feed audio data into any of the UI components we need to explicity create a GCD block on the main thread to properly get the UI to work.
|
||||
-(void)microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
- (void) microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
// Getting audio data as an array of float buffer arrays. What does that mean? Because the audio is coming in as a stereo signal the data is split into a left and right channel. So buffer[0] corresponds to the float* data for the left channel while buffer[1] corresponds to the float* data for the right channel.
|
||||
|
||||
// See the Thread Safety warning above, but in a nutshell these callbacks happen on a separate audio thread. We wrap any UI updating in a GCD block on the main thread to avoid blocking that audio flow.
|
||||
// Getting audio data as an array of float buffer arrays. What does that mean? Because the audio is coming in as a stereo signal the data is split into a left and right channel. So buffer[0] corresponds to the float* data for the left channel while buffer[1] corresponds to the float* data for the right channel.
|
||||
|
||||
// See the Thread Safety warning above, but in a nutshell these callbacks happen on a separate audio thread. We wrap any UI updating in a GCD block on the main thread to avoid blocking that audio flow.
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(),^{
|
||||
// All the audio plot needs is the buffer data (float*) and the size. Internally the audio plot will handle all the drawing related code, history management, and freeing its own resources. Hence, one badass line of code gets you a pretty plot :)
|
||||
[weakSelf.audioPlot updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// All the audio plot needs is the buffer data (float*) and the size. Internally the audio plot will handle all the drawing related code, history management, and freeing its own resources. Hence, one badass line of code gets you a pretty plot :)
|
||||
[weakSelf.recordingAudioPlot updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Append the microphone data coming as a AudioBufferList with the specified buffer size to the recorder
|
||||
-(void) microphone:(EZMicrophone *)microphone
|
||||
- (void) microphone:(EZMicrophone *)microphone
|
||||
hasBufferList:(AudioBufferList *)bufferList
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
// Getting audio data as a buffer list that can be directly fed into the EZRecorder. This is happening on the audio thread - any UI updating needs a GCD main queue block.
|
||||
// Getting audio data as a buffer list that can be directly fed into the EZRecorder. This is happening on the audio thread - any UI updating needs a GCD main queue block. This will keep appending data to the tail of the audio file.
|
||||
if (self.isRecording)
|
||||
{
|
||||
[self.recorder appendDataFromBufferList:bufferList
|
||||
withBufferSize:bufferSize];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - AVAudioPlayerDelegate
|
||||
#pragma mark - EZRecorderDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Occurs when the audio player instance completes playback
|
||||
*/
|
||||
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player
|
||||
successfully:(BOOL)flag
|
||||
- (void)recorderDidClose:(EZRecorder *)recorder
|
||||
{
|
||||
// Update microphone state
|
||||
self.microphoneToggle.state = NSOnState;
|
||||
[self.microphoneToggle setEnabled:YES];
|
||||
[self.microphone startFetchingAudio];
|
||||
|
||||
// Update recording state
|
||||
self.isRecording = NO;
|
||||
self.recordingToggle.state = NSOffState;
|
||||
[self.recordingToggle setEnabled:YES];
|
||||
recorder.delegate = nil;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)recorderUpdatedCurrentTime:(EZRecorder *)recorder
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
NSString *formattedCurrentTime = [recorder formattedCurrentTime];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
weakSelf.currentTimeLabel.stringValue = formattedCurrentTime;
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayerDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
playedAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
inAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSelf.playingAudioPlot updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
updatedPosition:(SInt64)framePosition
|
||||
inAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
weakSelf.currentTimeLabel.stringValue = [audioPlayer formattedCurrentTime];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setTitle:(NSString *)title forButton:(NSButton *)button
|
||||
{
|
||||
NSDictionary *attributes = @{ NSForegroundColorAttributeName : [NSColor whiteColor] };
|
||||
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:title
|
||||
attributes:attributes];
|
||||
button.attributedTitle = attributedTitle;
|
||||
button.attributedAlternateTitle = attributedTitle;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+93
-56
@@ -1,79 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="RecordViewController">
|
||||
<connections>
|
||||
<outlet property="audioPlot" destination="dEs-hA-819" id="iGa-BH-xLn"/>
|
||||
<outlet property="microphoneToggle" destination="642-4u-aBm" id="FYB-Cp-aPB"/>
|
||||
<outlet property="playButton" destination="y4R-NE-icG" id="1FP-aQ-BcB"/>
|
||||
<outlet property="recordingToggle" destination="fdr-L4-Y6i" id="dYX-uf-6YS"/>
|
||||
<outlet property="currentTimeLabel" destination="HxF-TY-fDR" id="zwj-XE-ACe"/>
|
||||
<outlet property="microphoneSwitch" destination="642-4u-aBm" id="AEv-nm-gLS"/>
|
||||
<outlet property="playButton" destination="y4R-NE-icG" id="kHv-iM-mCt"/>
|
||||
<outlet property="playingAudioPlot" destination="1yQ-Hd-JGR" id="Hdj-Ve-A6A"/>
|
||||
<outlet property="playingStateLabel" destination="y9d-HG-0Rl" id="YXg-yy-Q9t"/>
|
||||
<outlet property="recordSwitch" destination="fdr-L4-Y6i" id="Rqe-gC-lfh"/>
|
||||
<outlet property="recordingAudioPlot" destination="dEs-hA-819" id="ACe-8h-ags"/>
|
||||
<outlet property="view" destination="178-e9-GIn" id="bPz-Je-f18"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="178-e9-GIn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="dEs-hA-819" customClass="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="42" width="480" height="230"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</customView>
|
||||
<button misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="642-4u-aBm">
|
||||
<rect key="frame" x="18" y="14" width="119" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HxF-TY-fDR">
|
||||
<rect key="frame" x="16" y="193" width="85" height="39"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="00:00" id="Lsu-38-RnW">
|
||||
<font key="font" size="32" name="HelveticaNeue-Light"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1yQ-Hd-JGR" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="108" y="193" width="354" height="39"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="39" id="Cmv-Of-yxB"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="642-4u-aBm">
|
||||
<rect key="frame" x="16" y="39" width="119" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="115" id="jzA-c9-gss"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="check" title="Microphone Off" alternateTitle="Microphone On" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="WpM-g2-QmU">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" target="-2" id="xOT-qg-D3j"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="fdr-L4-Y6i">
|
||||
<rect key="frame" x="16" y="16" width="113" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="109" id="XVw-ku-8Kp"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="check" title="Not Recording" alternateTitle="Recording" bezelStyle="regularSquare" imagePosition="left" inset="2" id="j1l-ue-yI3">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleRecording:" target="-2" id="WKw-uD-CBI"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="y4R-NE-icG">
|
||||
<rect key="frame" x="12" y="57" width="65" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="53" id="eH3-f2-ls9"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="Play" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="XoV-qX-N9x">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="playFile:" target="-2" id="jrd-yg-pvq"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="y9d-HG-0Rl">
|
||||
<rect key="frame" x="76" y="66" width="75" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Not Playing" id="pde-yf-Cac">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="DDP-K1-hjt"/>
|
||||
<constraint firstItem="y9d-HG-0Rl" firstAttribute="leading" secondItem="y4R-NE-icG" secondAttribute="trailing" constant="7" id="5mU-Du-t8h"/>
|
||||
<constraint firstItem="fdr-L4-Y6i" firstAttribute="leading" secondItem="642-4u-aBm" secondAttribute="leading" id="6HB-Yz-Xlv"/>
|
||||
<constraint firstItem="642-4u-aBm" firstAttribute="top" secondItem="y4R-NE-icG" secondAttribute="bottom" constant="9" id="Gvt-cc-iCu"/>
|
||||
<constraint firstItem="1yQ-Hd-JGR" firstAttribute="top" secondItem="dEs-hA-819" secondAttribute="top" constant="40" id="MIg-OC-dHb"/>
|
||||
<constraint firstItem="1yQ-Hd-JGR" firstAttribute="leading" secondItem="HxF-TY-fDR" secondAttribute="trailing" constant="9" id="Njb-Oj-SUR"/>
|
||||
<constraint firstItem="HxF-TY-fDR" firstAttribute="leading" secondItem="dEs-hA-819" secondAttribute="leading" constant="18" id="Y42-ar-917"/>
|
||||
<constraint firstItem="y4R-NE-icG" firstAttribute="leading" secondItem="HxF-TY-fDR" secondAttribute="leading" id="eTn-op-NgF"/>
|
||||
<constraint firstItem="fdr-L4-Y6i" firstAttribute="top" secondItem="642-4u-aBm" secondAttribute="bottom" constant="9" id="hb4-N7-xjI"/>
|
||||
<constraint firstItem="HxF-TY-fDR" firstAttribute="top" secondItem="dEs-hA-819" secondAttribute="top" constant="40" id="kI9-mf-kW9"/>
|
||||
<constraint firstAttribute="trailing" secondItem="1yQ-Hd-JGR" secondAttribute="trailing" constant="18" id="nDj-wc-gcG"/>
|
||||
<constraint firstAttribute="bottom" secondItem="fdr-L4-Y6i" secondAttribute="bottom" constant="18" id="nGo-GX-HZv"/>
|
||||
<constraint firstItem="642-4u-aBm" firstAttribute="leading" secondItem="y4R-NE-icG" secondAttribute="leading" id="o9C-CB-nEE"/>
|
||||
<constraint firstItem="y9d-HG-0Rl" firstAttribute="centerY" secondItem="y4R-NE-icG" secondAttribute="centerY" id="xIG-Gy-XOS"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="check" title="Microphone Off" alternateTitle="Microphone On" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="WpM-g2-QmU">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" target="-2" id="xOT-qg-D3j"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="fdr-L4-Y6i">
|
||||
<rect key="frame" x="349" y="14" width="113" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Not Recording" alternateTitle="Recording" bezelStyle="regularSquare" imagePosition="left" inset="2" id="j1l-ue-yI3">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleRecording:" target="-2" id="WKw-uD-CBI"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="y4R-NE-icG">
|
||||
<rect key="frame" x="137" y="6" width="65" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Play" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="XoV-qX-N9x">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="playFile:" target="-2" id="jrd-yg-pvq"/>
|
||||
</connections>
|
||||
</button>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="642-4u-aBm" secondAttribute="bottom" constant="16" id="LIb-Ej-46s"/>
|
||||
<constraint firstAttribute="bottom" secondItem="fdr-L4-Y6i" secondAttribute="bottom" constant="16" id="Pvr-gh-o7q"/>
|
||||
<constraint firstItem="642-4u-aBm" firstAttribute="top" secondItem="dEs-hA-819" secondAttribute="bottom" constant="12" id="QgB-Ty-AN0"/>
|
||||
<constraint firstAttribute="bottom" secondItem="y4R-NE-icG" secondAttribute="bottom" constant="13" id="UX6-ts-w3M"/>
|
||||
<constraint firstItem="y4R-NE-icG" firstAttribute="leading" secondItem="642-4u-aBm" secondAttribute="trailing" constant="8" id="ZbS-5O-fFJ"/>
|
||||
<constraint firstItem="642-4u-aBm" firstAttribute="leading" secondItem="178-e9-GIn" secondAttribute="leading" constant="20" id="ayr-0v-aOC"/>
|
||||
<constraint firstAttribute="trailing" secondItem="fdr-L4-Y6i" secondAttribute="trailing" constant="20" id="hk9-I9-9g5"/>
|
||||
<constraint firstItem="dEs-hA-819" firstAttribute="top" secondItem="178-e9-GIn" secondAttribute="top" id="mv6-AK-Cz4"/>
|
||||
<constraint firstAttribute="trailing" secondItem="dEs-hA-819" secondAttribute="trailing" id="tqk-1H-SZ4"/>
|
||||
<constraint firstItem="y4R-NE-icG" firstAttribute="top" secondItem="dEs-hA-819" secondAttribute="bottom" constant="8" id="xzp-cM-xAL"/>
|
||||
<constraint firstItem="dEs-hA-819" firstAttribute="leading" secondItem="178-e9-GIn" secondAttribute="leading" id="yvm-d3-Fzl"/>
|
||||
<constraint firstAttribute="trailing" secondItem="dEs-hA-819" secondAttribute="trailing" id="R5V-pX-y9Q"/>
|
||||
<constraint firstItem="dEs-hA-819" firstAttribute="leading" secondItem="178-e9-GIn" secondAttribute="leading" id="UWT-Ay-DKN"/>
|
||||
<constraint firstAttribute="bottom" secondItem="dEs-hA-819" secondAttribute="bottom" id="ajJ-h2-gWy"/>
|
||||
<constraint firstItem="dEs-hA-819" firstAttribute="top" secondItem="178-e9-GIn" secondAttribute="top" id="h1e-yD-I80"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
</document>
|
||||
|
||||
-6
@@ -16,7 +16,6 @@
|
||||
66755B1B1B3B792A0013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755AFE1B3B792A0013E67E /* EZAudioPlayer.m */; };
|
||||
66755B1C1B3B792A0013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B001B3B792A0013E67E /* EZAudioPlot.m */; };
|
||||
66755B1D1B3B792A0013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B021B3B792A0013E67E /* EZAudioPlotGL.m */; };
|
||||
66755B1E1B3B792A0013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B041B3B792A0013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
66755B1F1B3B792A0013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B061B3B792A0013E67E /* EZAudioUtilities.m */; };
|
||||
66755B201B3B792A0013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B081B3B792A0013E67E /* EZMicrophone.m */; };
|
||||
66755B211B3B792A0013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 66755B0A1B3B792A0013E67E /* EZOutput.m */; };
|
||||
@@ -76,8 +75,6 @@
|
||||
66755B001B3B792A0013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
66755B011B3B792A0013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
66755B021B3B792A0013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
66755B031B3B792A0013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
66755B041B3B792A0013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
66755B051B3B792A0013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
66755B061B3B792A0013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
66755B071B3B792A0013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -171,8 +168,6 @@
|
||||
66755B001B3B792A0013E67E /* EZAudioPlot.m */,
|
||||
66755B011B3B792A0013E67E /* EZAudioPlotGL.h */,
|
||||
66755B021B3B792A0013E67E /* EZAudioPlotGL.m */,
|
||||
66755B031B3B792A0013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
66755B041B3B792A0013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
66755B051B3B792A0013E67E /* EZAudioUtilities.h */,
|
||||
66755B061B3B792A0013E67E /* EZAudioUtilities.m */,
|
||||
66755B071B3B792A0013E67E /* EZMicrophone.h */,
|
||||
@@ -398,7 +393,6 @@
|
||||
66755B1B1B3B792A0013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056E96185BCBC000EB94BA /* AppDelegate.m in Sources */,
|
||||
66755B1D1B3B792A0013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
66755B1E1B3B792A0013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
66755B181B3B792A0013E67E /* EZAudioFile.m in Sources */,
|
||||
66755B211B3B792A0013E67E /* EZOutput.m in Sources */,
|
||||
66755B1F1B3B792A0013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
+341
-141
@@ -1,100 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4439" systemVersion="13A451" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4439"/>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" destination="58" id="142"/>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder">
|
||||
<connections>
|
||||
<action selector="alignCenter:" destination="499" id="518"/>
|
||||
<action selector="alignJustified:" destination="500" id="523"/>
|
||||
<action selector="alignLeft:" destination="498" id="524"/>
|
||||
<action selector="alignRight:" destination="501" id="521"/>
|
||||
<action selector="arrangeInFront:" destination="5" id="39"/>
|
||||
<action selector="capitalizeWord:" destination="466" id="467"/>
|
||||
<action selector="centerSelectionInVisibleArea:" destination="210" id="245"/>
|
||||
<action selector="checkSpelling:" destination="201" id="225"/>
|
||||
<action selector="clearRecentDocuments:" destination="126" id="127"/>
|
||||
<action selector="copy:" destination="197" id="224"/>
|
||||
<action selector="copyFont:" destination="403" id="428"/>
|
||||
<action selector="copyRuler:" destination="506" id="522"/>
|
||||
<action selector="cut:" destination="199" id="228"/>
|
||||
<action selector="delete:" destination="202" id="235"/>
|
||||
<action selector="hide:" destination="134" id="367"/>
|
||||
<action selector="hideOtherApplications:" destination="145" id="368"/>
|
||||
<action selector="loosenKerning:" destination="419" id="435"/>
|
||||
<action selector="lowerBaseline:" destination="410" id="427"/>
|
||||
<action selector="lowercaseWord:" destination="465" id="468"/>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" destination="511" id="526"/>
|
||||
<action selector="makeBaseWritingDirectionNatural:" destination="510" id="525"/>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" destination="512" id="527"/>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" destination="516" id="529"/>
|
||||
<action selector="makeTextWritingDirectionNatural:" destination="515" id="528"/>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" destination="517" id="530"/>
|
||||
<action selector="newDocument:" destination="82" id="373"/>
|
||||
<action selector="openDocument:" destination="72" id="374"/>
|
||||
<action selector="orderFrontColorPanel:" destination="401" id="433"/>
|
||||
<action selector="orderFrontSubstitutionsPanel:" destination="457" id="458"/>
|
||||
<action selector="paste:" destination="203" id="226"/>
|
||||
<action selector="pasteAsPlainText:" destination="485" id="486"/>
|
||||
<action selector="pasteFont:" destination="404" id="436"/>
|
||||
<action selector="pasteRuler:" destination="507" id="519"/>
|
||||
<action selector="performClose:" destination="73" id="193"/>
|
||||
<action selector="performFindPanelAction:" destination="209" id="241"/>
|
||||
<action selector="performFindPanelAction:" destination="208" id="487"/>
|
||||
<action selector="performFindPanelAction:" destination="213" id="488"/>
|
||||
<action selector="performFindPanelAction:" destination="221" id="489"/>
|
||||
<action selector="performFindPanelAction:" destination="534" id="535"/>
|
||||
<action selector="performMiniaturize:" destination="23" id="37"/>
|
||||
<action selector="performZoom:" destination="239" id="240"/>
|
||||
<action selector="print:" destination="78" id="86"/>
|
||||
<action selector="raiseBaseline:" destination="409" id="426"/>
|
||||
<action selector="redo:" destination="215" id="231"/>
|
||||
<action selector="revertDocumentToSaved:" destination="112" id="364"/>
|
||||
<action selector="runPageLayout:" destination="77" id="87"/>
|
||||
<action selector="runToolbarCustomizationPalette:" destination="298" id="365"/>
|
||||
<action selector="saveDocument:" destination="75" id="362"/>
|
||||
<action selector="selectAll:" destination="198" id="232"/>
|
||||
<action selector="showGuessPanel:" destination="204" id="230"/>
|
||||
<action selector="showHelp:" destination="492" id="493"/>
|
||||
<action selector="startSpeaking:" destination="196" id="233"/>
|
||||
<action selector="stopSpeaking:" destination="195" id="227"/>
|
||||
<action selector="subscript:" destination="408" id="429"/>
|
||||
<action selector="superscript:" destination="407" id="430"/>
|
||||
<action selector="tightenKerning:" destination="418" id="431"/>
|
||||
<action selector="toggleAutomaticDashSubstitution:" destination="460" id="461"/>
|
||||
<action selector="toggleAutomaticLinkDetection:" destination="354" id="357"/>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" destination="351" id="356"/>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" destination="454" id="456"/>
|
||||
<action selector="toggleAutomaticTextReplacement:" destination="462" id="463"/>
|
||||
<action selector="toggleContinuousSpellChecking:" destination="219" id="222"/>
|
||||
<action selector="toggleGrammarChecking:" destination="346" id="347"/>
|
||||
<action selector="toggleRuler:" destination="505" id="520"/>
|
||||
<action selector="toggleSmartInsertDelete:" destination="350" id="355"/>
|
||||
<action selector="toggleToolbarShown:" destination="297" id="366"/>
|
||||
<action selector="turnOffKerning:" destination="417" id="441"/>
|
||||
<action selector="turnOffLigatures:" destination="413" id="440"/>
|
||||
<action selector="underline:" destination="392" id="432"/>
|
||||
<action selector="undo:" destination="207" id="223"/>
|
||||
<action selector="unhideAllApplications:" destination="150" id="370"/>
|
||||
<action selector="unscript:" destination="406" id="437"/>
|
||||
<action selector="uppercaseWord:" destination="452" id="464"/>
|
||||
<action selector="useAllLigatures:" destination="414" id="434"/>
|
||||
<action selector="useStandardKerning:" destination="416" id="438"/>
|
||||
<action selector="useStandardLigatures:" destination="412" id="439"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-3" userLabel="Application">
|
||||
<connections>
|
||||
<action selector="terminate:" destination="136" id="449"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="EZAudioWaveformFromFileExample" id="56">
|
||||
@@ -102,6 +19,9 @@
|
||||
<items>
|
||||
<menuItem title="About EZAudioWaveformFromFileExample" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
@@ -116,95 +36,211 @@
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide EZAudioWaveformFromFileExample" keyEquivalent="h" id="134"/>
|
||||
<menuItem title="Hide EZAudioWaveformFromFileExample" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150">
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150"/>
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit EZAudioWaveformFromFileExample" keyEquivalent="q" id="136"/>
|
||||
<menuItem title="Quit EZAudioWaveformFromFileExample" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-3" id="449"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="83">
|
||||
<menu key="submenu" title="File" id="81">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="82"/>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72"/>
|
||||
<menuItem title="New" keyEquivalent="n" id="82">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="373"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="374"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="124">
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="126"/>
|
||||
<menuItem title="Clear Menu" id="126">
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="127"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73"/>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="193"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="362"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="-1" id="87"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78">
|
||||
<connections>
|
||||
<action selector="print:" target="-1" id="86"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207"/>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="223"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="231"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199"/>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197"/>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="228"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="224"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="226"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="486"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202">
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="235"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="232"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202"/>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198"/>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209"/>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="241"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="535"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="487"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208"/>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="488"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="489"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221"/>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="216">
|
||||
<menu key="submenu" title="Spelling and Grammar" id="200">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204"/>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201"/>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="230"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="225"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="453"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219"/>
|
||||
<menuItem title="Check Grammar With Spelling" id="346"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219">
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="346">
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="454">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="456"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -214,18 +250,38 @@
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="457">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="458"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350"/>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="460">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="461"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="462">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="463"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -236,12 +292,21 @@
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="452">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="464"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="465">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="468"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="466">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="467"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -249,8 +314,16 @@
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="196"/>
|
||||
<menuItem title="Stop Speaking" id="195"/>
|
||||
<menuItem title="Start Speaking" id="196">
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="233"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="195">
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="227"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -265,13 +338,37 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389"/>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390"/>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391"/>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392"/>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="420" id="424"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="421"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="422"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="432"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="393"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394"/>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="425"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="423"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="396"/>
|
||||
<menuItem title="Kern" id="397">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -279,15 +376,27 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="416">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="438"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="417">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="441"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="418">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="431"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="419">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="435"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -298,12 +407,21 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="412">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="439"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="413">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="440"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="414">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="434"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -314,30 +432,55 @@
|
||||
<items>
|
||||
<menuItem title="Use Default" id="406">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="437"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="407">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="430"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="408">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="429"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="409">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="426"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="410">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="427"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="400"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="402"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="428"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="436"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -346,12 +489,27 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498"/>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499"/>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="524"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="518"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="500">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="523"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="521"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501"/>
|
||||
<menuItem isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
@@ -363,14 +521,23 @@
|
||||
<menuItem id="510">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="511">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="512">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="527"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="513"/>
|
||||
<menuItem title="Selection" enabled="NO" id="514">
|
||||
@@ -379,14 +546,23 @@
|
||||
<menuItem id="515">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="516">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="517">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="530"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -394,12 +570,21 @@
|
||||
<menuItem isSeparatorItem="YES" id="504"/>
|
||||
<menuItem title="Show Ruler" id="505">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="520"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="522"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="519"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
@@ -412,20 +597,39 @@
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298">
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23"/>
|
||||
<menuItem title="Zoom" id="239"/>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="37"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="239">
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="240"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5"/>
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
@@ -433,17 +637,21 @@
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="EZAudioWaveformFromFileExample Help" keyEquivalent="?" id="492"/>
|
||||
<menuItem title="EZAudioWaveformFromFileExample Help" keyEquivalent="?" id="492">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="EZAudioWaveformFromFileExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" fullSizeContentView="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
@@ -454,14 +662,6 @@
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" destination="390" id="421"/>
|
||||
<action selector="addFontTrait:" destination="391" id="422"/>
|
||||
<action selector="modifyFont:" destination="395" id="423"/>
|
||||
<action selector="modifyFont:" destination="394" id="425"/>
|
||||
<action selector="orderFrontFontPanel:" destination="389" id="424"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager"/>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
+68
-45
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="WaveformFromFileViewController">
|
||||
@@ -19,53 +19,76 @@
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="gA7-R7-vbt" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="211"/>
|
||||
</customView>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xHD-WQ-u4W">
|
||||
<rect key="frame" x="14" y="224" width="125" height="32"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<subviews>
|
||||
<box autoresizesSubviews="NO" title="Box" boxType="custom" borderType="none" translatesAutoresizingMaskIntoConstraints="NO" id="dH6-TL-MVT">
|
||||
<rect key="frame" x="0.0" y="193" width="480" height="79"/>
|
||||
<view key="contentView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="79"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xHD-WQ-u4W">
|
||||
<rect key="frame" x="10" y="11" width="125" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="113" id="b31-eU-mqu"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="Choose File..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="7er-Dd-Gmx">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="openFile:" target="-2" id="oIG-3z-prU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zS7-9z-YB1">
|
||||
<rect key="frame" x="137" y="22" width="213" height="17"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" sendsActionOnEndEditing="YES" title="Label" id="jWL-Kx-s9B">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2Q5-5T-qQ4">
|
||||
<rect key="frame" x="371" y="11" width="97" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="85" id="Xin-4w-yLk"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="Snapshot" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8ht-Cu-65q">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="snapshot:" target="-2" id="RLS-Qr-Gbu"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstItem="zS7-9z-YB1" firstAttribute="leading" secondItem="xHD-WQ-u4W" secondAttribute="trailing" constant="10" id="7yh-7q-axR"/>
|
||||
<constraint firstItem="2Q5-5T-qQ4" firstAttribute="leading" secondItem="zS7-9z-YB1" secondAttribute="trailing" constant="29" id="D3d-Ou-qaP"/>
|
||||
<constraint firstAttribute="trailing" secondItem="2Q5-5T-qQ4" secondAttribute="trailing" constant="18" id="D9F-H4-mlu"/>
|
||||
<constraint firstItem="zS7-9z-YB1" firstAttribute="top" secondItem="2Q5-5T-qQ4" secondAttribute="top" id="E0b-6r-tgF"/>
|
||||
<constraint firstItem="xHD-WQ-u4W" firstAttribute="leading" secondItem="dH6-TL-MVT" secondAttribute="leading" constant="16" id="Ieb-er-Yqf"/>
|
||||
<constraint firstItem="2Q5-5T-qQ4" firstAttribute="centerY" secondItem="dH6-TL-MVT" secondAttribute="centerY" constant="11" id="TG9-81-0jp"/>
|
||||
<constraint firstItem="xHD-WQ-u4W" firstAttribute="top" secondItem="dH6-TL-MVT" secondAttribute="top" constant="40" id="aDV-Ry-Inv"/>
|
||||
<constraint firstItem="2Q5-5T-qQ4" firstAttribute="baseline" secondItem="xHD-WQ-u4W" secondAttribute="baseline" id="yAV-WB-sKN"/>
|
||||
</constraints>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" red="0.0" green="0.0" blue="0.0" alpha="0.69999999999999996" colorSpace="calibratedRGB"/>
|
||||
</box>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="113" id="0jv-eA-dSV"/>
|
||||
<constraint firstAttribute="height" constant="21" id="1Yn-bF-mfb"/>
|
||||
<constraint firstItem="dH6-TL-MVT" firstAttribute="leading" secondItem="gA7-R7-vbt" secondAttribute="leading" id="JWF-3n-y1m"/>
|
||||
<constraint firstAttribute="trailing" secondItem="dH6-TL-MVT" secondAttribute="trailing" id="c6J-c1-evB"/>
|
||||
<constraint firstItem="dH6-TL-MVT" firstAttribute="top" secondItem="gA7-R7-vbt" secondAttribute="top" id="yIc-KE-eyZ"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="Choose File..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="7er-Dd-Gmx">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="openFile:" target="-2" id="oIG-3z-prU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zS7-9z-YB1">
|
||||
<rect key="frame" x="141" y="235" width="213" height="17"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" sendsActionOnEndEditing="YES" title="Label" id="jWL-Kx-s9B">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Q5-5T-qQ4">
|
||||
<rect key="frame" x="375" y="224" width="97" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Snapshot" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8ht-Cu-65q">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="snapshot:" target="-2" id="RLS-Qr-Gbu"/>
|
||||
</connections>
|
||||
</button>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="zS7-9z-YB1" firstAttribute="leading" secondItem="xHD-WQ-u4W" secondAttribute="trailing" constant="10" id="4RW-fI-JJs"/>
|
||||
<constraint firstItem="2Q5-5T-qQ4" firstAttribute="top" secondItem="0tP-1Y-eJu" secondAttribute="top" constant="20" id="E3b-p3-BoQ"/>
|
||||
<constraint firstAttribute="trailing" relation="lessThanOrEqual" secondItem="zS7-9z-YB1" secondAttribute="trailing" constant="20" id="NTC-UB-Fma"/>
|
||||
<constraint firstAttribute="trailing" secondItem="gA7-R7-vbt" secondAttribute="trailing" id="Tsg-V9-2HL"/>
|
||||
<constraint firstItem="gA7-R7-vbt" firstAttribute="leading" secondItem="0tP-1Y-eJu" secondAttribute="leading" id="WAi-gw-Gx4"/>
|
||||
<constraint firstItem="gA7-R7-vbt" firstAttribute="top" secondItem="xHD-WQ-u4W" secondAttribute="bottom" constant="20" id="fLd-J2-pdv"/>
|
||||
<constraint firstItem="zS7-9z-YB1" firstAttribute="top" secondItem="0tP-1Y-eJu" secondAttribute="top" constant="20" id="gjc-Xh-3J0"/>
|
||||
<constraint firstItem="xHD-WQ-u4W" firstAttribute="leading" secondItem="0tP-1Y-eJu" secondAttribute="leading" constant="20" id="ide-qF-Q25"/>
|
||||
<constraint firstItem="xHD-WQ-u4W" firstAttribute="top" secondItem="0tP-1Y-eJu" secondAttribute="top" constant="20" id="iiM-ji-9ME"/>
|
||||
<constraint firstAttribute="trailing" secondItem="2Q5-5T-qQ4" secondAttribute="trailing" constant="14" id="j3N-CF-2Rt"/>
|
||||
<constraint firstAttribute="bottom" secondItem="gA7-R7-vbt" secondAttribute="bottom" id="nf1-Zn-U5V"/>
|
||||
<constraint firstItem="gA7-R7-vbt" firstAttribute="leading" secondItem="0tP-1Y-eJu" secondAttribute="leading" id="1uQ-PM-GXF"/>
|
||||
<constraint firstAttribute="trailing" secondItem="gA7-R7-vbt" secondAttribute="trailing" id="w4s-bY-9Vz"/>
|
||||
<constraint firstItem="gA7-R7-vbt" firstAttribute="top" secondItem="0tP-1Y-eJu" secondAttribute="top" id="wko-ZW-xTr"/>
|
||||
<constraint firstAttribute="bottom" secondItem="gA7-R7-vbt" secondAttribute="bottom" id="ynB-p6-1In"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</objects>
|
||||
|
||||
-6
@@ -16,7 +16,6 @@
|
||||
667558A81B3B604B0013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675588B1B3B604B0013E67E /* EZAudioPlayer.m */; };
|
||||
667558A91B3B604B0013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675588D1B3B604B0013E67E /* EZAudioPlot.m */; };
|
||||
667558AA1B3B604B0013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675588F1B3B604B0013E67E /* EZAudioPlotGL.m */; };
|
||||
667558AB1B3B604B0013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558911B3B604B0013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
667558AC1B3B604B0013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558931B3B604B0013E67E /* EZAudioUtilities.m */; };
|
||||
667558AD1B3B604B0013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558951B3B604B0013E67E /* EZMicrophone.m */; };
|
||||
667558AE1B3B604B0013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558971B3B604B0013E67E /* EZOutput.m */; };
|
||||
@@ -73,8 +72,6 @@
|
||||
6675588D1B3B604B0013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
6675588E1B3B604B0013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
6675588F1B3B604B0013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
667558901B3B604B0013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
667558911B3B604B0013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
667558921B3B604B0013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
667558931B3B604B0013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
667558941B3B604B0013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -161,8 +158,6 @@
|
||||
6675588D1B3B604B0013E67E /* EZAudioPlot.m */,
|
||||
6675588E1B3B604B0013E67E /* EZAudioPlotGL.h */,
|
||||
6675588F1B3B604B0013E67E /* EZAudioPlotGL.m */,
|
||||
667558901B3B604B0013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
667558911B3B604B0013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
667558921B3B604B0013E67E /* EZAudioUtilities.h */,
|
||||
667558931B3B604B0013E67E /* EZAudioUtilities.m */,
|
||||
667558941B3B604B0013E67E /* EZMicrophone.h */,
|
||||
@@ -370,7 +365,6 @@
|
||||
667558A81B3B604B0013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056FDE185E59D900EB94BA /* CoreGraphicsWaveformViewController.m in Sources */,
|
||||
667558AA1B3B604B0013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667558AB1B3B604B0013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
667558A51B3B604B0013E67E /* EZAudioFile.m in Sources */,
|
||||
667558AE1B3B604B0013E67E /* EZOutput.m in Sources */,
|
||||
667558AC1B3B604B0013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Customize the Audio Plot
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)viewDidLoad
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="uAJ-Uz-eFq">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="uAJ-Uz-eFq">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
6675591A1B3B78720013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558FD1B3B78720013E67E /* EZAudioPlayer.m */; };
|
||||
6675591B1B3B78720013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558FF1B3B78720013E67E /* EZAudioPlot.m */; };
|
||||
6675591C1B3B78720013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559011B3B78720013E67E /* EZAudioPlotGL.m */; };
|
||||
6675591D1B3B78720013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559031B3B78720013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
6675591E1B3B78720013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559051B3B78720013E67E /* EZAudioUtilities.m */; };
|
||||
6675591F1B3B78720013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559071B3B78720013E67E /* EZMicrophone.m */; };
|
||||
667559201B3B78720013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559091B3B78720013E67E /* EZOutput.m */; };
|
||||
@@ -75,8 +74,6 @@
|
||||
667558FF1B3B78720013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
667559001B3B78720013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
667559011B3B78720013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
667559021B3B78720013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
667559031B3B78720013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
667559041B3B78720013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
667559051B3B78720013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
667559061B3B78720013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -164,8 +161,6 @@
|
||||
667558FF1B3B78720013E67E /* EZAudioPlot.m */,
|
||||
667559001B3B78720013E67E /* EZAudioPlotGL.h */,
|
||||
667559011B3B78720013E67E /* EZAudioPlotGL.m */,
|
||||
667559021B3B78720013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
667559031B3B78720013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
667559041B3B78720013E67E /* EZAudioUtilities.h */,
|
||||
667559051B3B78720013E67E /* EZAudioUtilities.m */,
|
||||
667559061B3B78720013E67E /* EZMicrophone.h */,
|
||||
@@ -374,7 +369,6 @@
|
||||
6675591A1B3B78720013E67E /* EZAudioPlayer.m in Sources */,
|
||||
9417A97C1871E88300D9D37B /* AppDelegate.m in Sources */,
|
||||
6675591C1B3B78720013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
6675591D1B3B78720013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
667559171B3B78720013E67E /* EZAudioFile.m in Sources */,
|
||||
667559201B3B78720013E67E /* EZOutput.m in Sources */,
|
||||
6675591E1B3B78720013E67E /* EZAudioUtilities.m in Sources */,
|
||||
@@ -512,6 +506,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExample/EZAudioFFTExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
@@ -525,6 +520,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExample/EZAudioFFTExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
*/
|
||||
@interface FFTViewController : UIViewController <EZMicrophoneDelegate>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
EZAudioPlot for frequency plot
|
||||
*/
|
||||
|
||||
@@ -49,6 +49,23 @@
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
//
|
||||
// Setup the AVAudioSession. EZMicrophone will not work properly on iOS
|
||||
// if you don't do this!
|
||||
//
|
||||
AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
NSError *error;
|
||||
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"Error setting up audio session category: %@", error.localizedDescription);
|
||||
}
|
||||
[session setActive:YES error:&error];
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"Error setting up audio session active: %@", error.localizedDescription);
|
||||
}
|
||||
|
||||
/*
|
||||
Customizing the audio plot's look
|
||||
*/
|
||||
@@ -70,7 +87,7 @@
|
||||
Start the microphone
|
||||
*/
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self
|
||||
startsImmediately:YES];
|
||||
startsImmediately:YES];
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="Weo-wK-GIV">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="Weo-wK-GIV">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
|
||||
+2
-6
@@ -16,7 +16,6 @@
|
||||
667559FE1B3B78940013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559E11B3B78940013E67E /* EZAudioPlayer.m */; };
|
||||
667559FF1B3B78940013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559E31B3B78940013E67E /* EZAudioPlot.m */; };
|
||||
66755A001B3B78940013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559E51B3B78940013E67E /* EZAudioPlotGL.m */; };
|
||||
66755A011B3B78940013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559E71B3B78940013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
66755A021B3B78940013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559E91B3B78940013E67E /* EZAudioUtilities.m */; };
|
||||
66755A031B3B78940013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559EB1B3B78940013E67E /* EZMicrophone.m */; };
|
||||
66755A041B3B78940013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559ED1B3B78940013E67E /* EZOutput.m */; };
|
||||
@@ -73,8 +72,6 @@
|
||||
667559E31B3B78940013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
667559E41B3B78940013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
667559E51B3B78940013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
667559E61B3B78940013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
667559E71B3B78940013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
667559E81B3B78940013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
667559E91B3B78940013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
667559EA1B3B78940013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -161,8 +158,6 @@
|
||||
667559E31B3B78940013E67E /* EZAudioPlot.m */,
|
||||
667559E41B3B78940013E67E /* EZAudioPlotGL.h */,
|
||||
667559E51B3B78940013E67E /* EZAudioPlotGL.m */,
|
||||
667559E61B3B78940013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
667559E71B3B78940013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
667559E81B3B78940013E67E /* EZAudioUtilities.h */,
|
||||
667559E91B3B78940013E67E /* EZAudioUtilities.m */,
|
||||
667559EA1B3B78940013E67E /* EZMicrophone.h */,
|
||||
@@ -370,7 +365,6 @@
|
||||
667559FE1B3B78940013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94057050185E636100EB94BA /* OpenGLWaveformViewController.m in Sources */,
|
||||
66755A001B3B78940013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
66755A011B3B78940013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
667559FB1B3B78940013E67E /* EZAudioFile.m in Sources */,
|
||||
66755A041B3B78940013E67E /* EZOutput.m in Sources */,
|
||||
66755A021B3B78940013E67E /* EZAudioUtilities.m in Sources */,
|
||||
@@ -508,6 +502,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
@@ -521,6 +516,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="1v1-63-VYU">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="1v1-63-VYU">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Customize the Audio Plot
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)viewDidLoad
|
||||
|
||||
+2
-6
@@ -17,7 +17,6 @@
|
||||
667559531B3B78790013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559361B3B78790013E67E /* EZAudioPlayer.m */; };
|
||||
667559541B3B78790013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559381B3B78790013E67E /* EZAudioPlot.m */; };
|
||||
667559551B3B78790013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675593A1B3B78790013E67E /* EZAudioPlotGL.m */; };
|
||||
667559561B3B78790013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675593C1B3B78790013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
667559571B3B78790013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675593E1B3B78790013E67E /* EZAudioUtilities.m */; };
|
||||
667559581B3B78790013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559401B3B78790013E67E /* EZMicrophone.m */; };
|
||||
667559591B3B78790013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559421B3B78790013E67E /* EZOutput.m */; };
|
||||
@@ -74,8 +73,6 @@
|
||||
667559381B3B78790013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
667559391B3B78790013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
6675593A1B3B78790013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
6675593B1B3B78790013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
6675593C1B3B78790013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
6675593D1B3B78790013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
6675593E1B3B78790013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
6675593F1B3B78790013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -161,8 +158,6 @@
|
||||
667559381B3B78790013E67E /* EZAudioPlot.m */,
|
||||
667559391B3B78790013E67E /* EZAudioPlotGL.h */,
|
||||
6675593A1B3B78790013E67E /* EZAudioPlotGL.m */,
|
||||
6675593B1B3B78790013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
6675593C1B3B78790013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
6675593D1B3B78790013E67E /* EZAudioUtilities.h */,
|
||||
6675593E1B3B78790013E67E /* EZAudioUtilities.m */,
|
||||
6675593F1B3B78790013E67E /* EZMicrophone.h */,
|
||||
@@ -370,7 +365,6 @@
|
||||
667559531B3B78790013E67E /* EZAudioPlayer.m in Sources */,
|
||||
9417A61E1864D4DC00D9D37B /* AppDelegate.m in Sources */,
|
||||
667559551B3B78790013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667559561B3B78790013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
667559501B3B78790013E67E /* EZAudioFile.m in Sources */,
|
||||
667559591B3B78790013E67E /* EZOutput.m in Sources */,
|
||||
667559571B3B78790013E67E /* EZAudioUtilities.m in Sources */,
|
||||
@@ -508,6 +502,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioPassThroughExample/EZAudioPassThroughExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioPassThroughExample/EZAudioPassThroughExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
@@ -521,6 +516,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioPassThroughExample/EZAudioPassThroughExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioPassThroughExample/EZAudioPassThroughExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="zGs-8g-w7u">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="zGs-8g-w7u">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Pass Through View Controller-->
|
||||
|
||||
+21
-4
@@ -28,23 +28,40 @@
|
||||
// Import EZAudio header
|
||||
#import "EZAudio.h"
|
||||
|
||||
@interface PassThroughViewController : UIViewController <EZMicrophoneDelegate,EZOutputDataSource>
|
||||
@interface PassThroughViewController : UIViewController <EZMicrophoneDelegate>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The OpenGL based audio plot
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlotGL *audioPlot;
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlotGL *audioPlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The UILabel used to display whether the microphone is on or off
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UILabel *microphoneTextLabel;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Switches the plot drawing type between a buffer plot (visualizes the current stream of audio data from the update function) or a rolling plot (visualizes the audio data over time, this is the classic waveform look)
|
||||
*/
|
||||
-(IBAction)changePlotType:(id)sender;
|
||||
- (IBAction)changePlotType:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Toggles the microphone on and off. When the microphone is on it will send its delegate (aka this view controller) the audio data in various ways (check out the EZMicrophoneDelegate documentation for more details);
|
||||
*/
|
||||
-(IBAction)toggleMicrophone:(id)sender;
|
||||
- (IBAction)toggleMicrophone:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
+72
-45
@@ -25,22 +25,25 @@
|
||||
|
||||
#import "PassThroughViewController.h"
|
||||
|
||||
@interface PassThroughViewController (){
|
||||
TPCircularBuffer _circularBuffer;
|
||||
}
|
||||
#pragma mark - UI Extras
|
||||
@property (nonatomic,weak) IBOutlet UILabel *microphoneTextLabel;
|
||||
@end
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - PassThroughViewController (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation PassThroughViewController
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Status Bar Style
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
return UIStatusBarStyleLightContent;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Customize the Audio Plot
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
@@ -97,62 +100,86 @@
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
-(void)changePlotType:(id)sender {
|
||||
NSInteger selectedSegment = [sender selectedSegmentIndex];
|
||||
switch(selectedSegment){
|
||||
case 0:
|
||||
[self drawBufferPlot];
|
||||
break;
|
||||
case 1:
|
||||
[self drawRollingPlot];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)changePlotType:(id)sender
|
||||
{
|
||||
NSInteger selectedSegment = [sender selectedSegmentIndex];
|
||||
switch(selectedSegment)
|
||||
{
|
||||
case 0:
|
||||
[self drawBufferPlot];
|
||||
break;
|
||||
case 1:
|
||||
[self drawRollingPlot];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)toggleMicrophone:(id)sender {
|
||||
if( ![(UISwitch*)sender isOn] ){
|
||||
[[EZMicrophone sharedMicrophone] stopFetchingAudio];
|
||||
self.microphoneTextLabel.text = @"Microphone Off";
|
||||
}
|
||||
else {
|
||||
[[EZMicrophone sharedMicrophone] startFetchingAudio];
|
||||
self.microphoneTextLabel.text = @"Microphone On";
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)toggleMicrophone:(id)sender
|
||||
{
|
||||
if( ![(UISwitch*)sender isOn] )
|
||||
{
|
||||
[[EZMicrophone sharedMicrophone] stopFetchingAudio];
|
||||
self.microphoneTextLabel.text = @"Microphone Off";
|
||||
}
|
||||
else
|
||||
{
|
||||
[[EZMicrophone sharedMicrophone] startFetchingAudio];
|
||||
self.microphoneTextLabel.text = @"Microphone On";
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Action Extensions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Give the visualization of the current buffer (this is almost exactly the openFrameworks audio input eample)
|
||||
*/
|
||||
-(void)drawBufferPlot {
|
||||
// Change the plot type to the buffer plot
|
||||
self.audioPlot.plotType = EZPlotTypeBuffer;
|
||||
// Don't mirror over the x-axis
|
||||
self.audioPlot.shouldMirror = NO;
|
||||
// Don't fill
|
||||
self.audioPlot.shouldFill = NO;
|
||||
- (void)drawBufferPlot
|
||||
{
|
||||
// Change the plot type to the buffer plot
|
||||
self.audioPlot.plotType = EZPlotTypeBuffer;
|
||||
// Don't mirror over the x-axis
|
||||
self.audioPlot.shouldMirror = NO;
|
||||
// Don't fill
|
||||
self.audioPlot.shouldFill = NO;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Give the classic mirrored, rolling waveform look
|
||||
*/
|
||||
-(void)drawRollingPlot {
|
||||
self.audioPlot.plotType = EZPlotTypeRolling;
|
||||
self.audioPlot.shouldFill = YES;
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
- (void)drawRollingPlot
|
||||
{
|
||||
self.audioPlot.plotType = EZPlotTypeRolling;
|
||||
self.audioPlot.shouldFill = YES;
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
-(void)microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.audioPlot updateBuffer:buffer[0] withBufferSize:bufferSize];
|
||||
});
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSelf.audioPlot updateBuffer:buffer[0] withBufferSize:bufferSize];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
+2
-6
@@ -17,7 +17,6 @@
|
||||
667558E11B3B60B80013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558C41B3B60B80013E67E /* EZAudioPlayer.m */; };
|
||||
667558E21B3B60B80013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558C61B3B60B80013E67E /* EZAudioPlot.m */; };
|
||||
667558E31B3B60B80013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558C81B3B60B80013E67E /* EZAudioPlotGL.m */; };
|
||||
667558E41B3B60B80013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558CA1B3B60B80013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
667558E51B3B60B80013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558CC1B3B60B80013E67E /* EZAudioUtilities.m */; };
|
||||
667558E61B3B60B80013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558CE1B3B60B80013E67E /* EZMicrophone.m */; };
|
||||
667558E71B3B60B80013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 667558D01B3B60B80013E67E /* EZOutput.m */; };
|
||||
@@ -75,8 +74,6 @@
|
||||
667558C61B3B60B80013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
667558C71B3B60B80013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
667558C81B3B60B80013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
667558C91B3B60B80013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
667558CA1B3B60B80013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
667558CB1B3B60B80013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
667558CC1B3B60B80013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
667558CD1B3B60B80013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -163,8 +160,6 @@
|
||||
667558C61B3B60B80013E67E /* EZAudioPlot.m */,
|
||||
667558C71B3B60B80013E67E /* EZAudioPlotGL.h */,
|
||||
667558C81B3B60B80013E67E /* EZAudioPlotGL.m */,
|
||||
667558C91B3B60B80013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
667558CA1B3B60B80013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
667558CB1B3B60B80013E67E /* EZAudioUtilities.h */,
|
||||
667558CC1B3B60B80013E67E /* EZAudioUtilities.m */,
|
||||
667558CD1B3B60B80013E67E /* EZMicrophone.h */,
|
||||
@@ -374,7 +369,6 @@
|
||||
667558E11B3B60B80013E67E /* EZAudioPlayer.m in Sources */,
|
||||
944D03ED186038A60076EF7A /* AppDelegate.m in Sources */,
|
||||
667558E31B3B60B80013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667558E41B3B60B80013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
667558DE1B3B60B80013E67E /* EZAudioFile.m in Sources */,
|
||||
667558E71B3B60B80013E67E /* EZOutput.m in Sources */,
|
||||
667558E51B3B60B80013E67E /* EZAudioUtilities.m in Sources */,
|
||||
@@ -512,6 +506,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioPlayFileExample/EZAudioPlayFileExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioPlayFileExample/EZAudioPlayFileExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
@@ -525,6 +520,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioPlayFileExample/EZAudioPlayFileExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioPlayFileExample/EZAudioPlayFileExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
|
||||
+5
-6
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="scx-fQ-Cxi">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="scx-fQ-Cxi">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Play File View Controller-->
|
||||
@@ -17,7 +16,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kt3-hw-eFY" customClass="EZAudioPlot">
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kt3-hw-eFY" customClass="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Pcc-nf-p5k">
|
||||
@@ -149,8 +148,8 @@
|
||||
<connections>
|
||||
<outlet property="audioPlot" destination="kt3-hw-eFY" id="9mm-d1-vJk"/>
|
||||
<outlet property="filePathLabel" destination="i5r-ex-ukW" id="GRl-ld-nWi"/>
|
||||
<outlet property="framePositionSlider" destination="Oc2-kU-kAJ" id="z0M-Q9-JAb"/>
|
||||
<outlet property="rollingHistorySlider" destination="2qJ-Va-Qht" id="yf8-JW-5yM"/>
|
||||
<outlet property="positionSlider" destination="Oc2-kU-kAJ" id="ZBM-XQ-gzp"/>
|
||||
<outlet property="rollingHistorySlider" destination="2qJ-Va-Qht" id="8rE-j3-utb"/>
|
||||
<outlet property="view" destination="PED-9r-Xub" id="Xxb-En-D2X"/>
|
||||
<outlet property="volumeSlider" destination="d3R-ct-df2" id="pAW-BF-AFa"/>
|
||||
</connections>
|
||||
|
||||
+44
-19
@@ -16,79 +16,104 @@
|
||||
*/
|
||||
#define kAudioFileDefault [[NSBundle mainBundle] pathForResource:@"simple-drum-beat" ofType:@"wav"]
|
||||
|
||||
/**
|
||||
Using the EZOutputDataSource to provide output data to the EZOutput component.
|
||||
*/
|
||||
@interface PlayFileViewController : UIViewController <EZAudioFileDelegate,
|
||||
EZOutputDataSource,
|
||||
EZOutputDelegate>
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - PlayFileViewController
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - Components
|
||||
/**
|
||||
The EZAudioFile representing of the currently selected audio file
|
||||
The PlayFileViewController will demonstrate how to play an audio file and plot
|
||||
the audio data in real-time.
|
||||
*/
|
||||
@interface PlayFileViewController : UIViewController <EZAudioPlayerDelegate>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
An EZAudioFile that will be used to load the audio file at the file path specified
|
||||
*/
|
||||
@property (nonatomic, strong) EZAudioFile *audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZOutput representing the output currently being used to play the audio file.
|
||||
An EZAudioPlayer that will be used for playback
|
||||
*/
|
||||
@property (nonatomic, strong) EZOutput *output;
|
||||
@property (nonatomic, strong) EZAudioPlayer *player;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The CoreGraphics based audio plot
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlot *audioPlot;
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlotGL *audioPlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - UI Extras
|
||||
/**
|
||||
A label to display the current file path with the waveform shown
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UILabel *filePathLabel;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A slider to indicate the current frame position in the audio file
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UISlider *framePositionSlider;
|
||||
@property (nonatomic, weak) IBOutlet UISlider *positionSlider;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A slider to indicate the current rolling history length of the audio plot.
|
||||
A slider to indicate the rolling history length of the audio plot.
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UISlider *rollingHistorySlider;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A slider to indicate the volume on the audio player
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UISlider *volumeSlider;
|
||||
|
||||
/**
|
||||
A BOOL indicating whether or not we've reached the end of the file
|
||||
*/
|
||||
@property (nonatomic,assign) BOOL eof;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Switches the plot drawing type between a buffer plot (visualizes the current stream of audio data from the update function) or a rolling plot (visualizes the audio data over time, this is the classic waveform look)
|
||||
*/
|
||||
- (IBAction)changePlotType:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Changes the length of the rolling history of the audio plot.
|
||||
*/
|
||||
- (IBAction)changeRollingHistoryLength:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Changes the volume of the audio player.
|
||||
*/
|
||||
- (IBAction)changeVolume:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Begins playback if a file is loaded. Pauses if the file is already playing.
|
||||
*/
|
||||
- (IBAction)play:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Seeks to a specific frame in the audio file.
|
||||
*/
|
||||
- (IBAction)seekToFrame:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
+143
-103
@@ -10,17 +10,32 @@
|
||||
|
||||
@implementation PlayFileViewController
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Status Bar Style
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
return UIStatusBarStyleLightContent;
|
||||
}
|
||||
|
||||
#pragma mark - Customize the Audio Plot
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
|
||||
//
|
||||
// Setup the AVAudioSession. EZMicrophone will not work properly on iOS
|
||||
// if you don't do this!
|
||||
@@ -39,37 +54,89 @@
|
||||
}
|
||||
|
||||
//
|
||||
// Customize the plot's look
|
||||
// Customizing the audio plot's look
|
||||
//
|
||||
// Background color
|
||||
self.audioPlot.backgroundColor = [UIColor colorWithRed: 0.816 green: 0.349 blue: 0.255 alpha: 1];
|
||||
// Waveform color
|
||||
self.audioPlot.color = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
// Plot type
|
||||
self.audioPlot.plotType = EZPlotTypeBuffer;
|
||||
// Fill
|
||||
self.audioPlot.shouldFill = YES;
|
||||
// Mirror
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
|
||||
//
|
||||
// Create an EZOutput instance
|
||||
//
|
||||
self.output = [EZOutput outputWithDataSource:self];
|
||||
self.output.delegate = self;
|
||||
|
||||
NSLog(@"outputs: %@", [EZAudioDevice outputDevices]);
|
||||
|
||||
//
|
||||
// Customize UI controls
|
||||
// Create the audio player
|
||||
//
|
||||
self.volumeSlider.value = [self.output volume];
|
||||
self.rollingHistorySlider.value = [self.audioPlot rollingHistoryLength];
|
||||
self.player = [EZAudioPlayer audioPlayerWithDelegate:self];
|
||||
self.player.shouldLoop = YES;
|
||||
|
||||
// Override the output to the speaker
|
||||
[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"Error overriding output to the speaker: %@", error.localizedDescription);
|
||||
}
|
||||
|
||||
//
|
||||
// Try opening the sample file
|
||||
// Customize UI components
|
||||
//
|
||||
self.rollingHistorySlider.value = (float)[self.audioPlot rollingHistoryLength];
|
||||
|
||||
//
|
||||
// Listen for EZAudioPlayer notifications
|
||||
//
|
||||
[self setupNotifications];
|
||||
|
||||
/*
|
||||
Try opening the sample file
|
||||
*/
|
||||
[self openFileWithFilePathURL:[NSURL fileURLWithPath:kAudioFileDefault]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Notifications
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setupNotifications
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(audioPlayerDidChangeAudioFile:)
|
||||
name:EZAudioPlayerDidChangeAudioFileNotification
|
||||
object:self.player];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(audioPlayerDidChangeOutputDevice:)
|
||||
name:EZAudioPlayerDidChangeOutputDeviceNotification
|
||||
object:self.player];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(audioPlayerDidChangePlayState:)
|
||||
name:EZAudioPlayerDidChangePlayStateNotification
|
||||
object:self.player];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayerDidChangeAudioFile:(NSNotification *)notification
|
||||
{
|
||||
EZAudioPlayer *player = [notification object];
|
||||
NSLog(@"Player changed audio file: %@", [player audioFile]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayerDidChangeOutputDevice:(NSNotification *)notification
|
||||
{
|
||||
EZAudioPlayer *player = [notification object];
|
||||
NSLog(@"Player changed output device: %@", [player device]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayerDidChangePlayState:(NSNotification *)notification
|
||||
{
|
||||
EZAudioPlayer *player = [notification object];
|
||||
NSLog(@"Player change play state, isPlaying: %i", [player isPlaying]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -103,29 +170,31 @@
|
||||
- (void)changeVolume:(id)sender
|
||||
{
|
||||
float value = [(UISlider *)sender value];
|
||||
[self.output setVolume:value];
|
||||
[self.player setVolume:value];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)openFileWithFilePathURL:(NSURL *)filePathURL
|
||||
{
|
||||
// Stop playback
|
||||
[self.output stopPlayback];
|
||||
//
|
||||
// Create the EZAudioPlayer
|
||||
//
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL];
|
||||
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL delegate:self];
|
||||
self.eof = NO;
|
||||
//
|
||||
// Update the UI
|
||||
//
|
||||
self.filePathLabel.text = filePathURL.lastPathComponent;
|
||||
self.framePositionSlider.maximumValue = (float)self.audioFile.totalFrames;
|
||||
|
||||
// Set the input format from the EZAudioFile on the output
|
||||
[self.output setInputFormat:[self.audioFile clientFormat]];
|
||||
self.positionSlider.maximumValue = (float)self.audioFile.totalFrames;
|
||||
self.volumeSlider.value = [self.player volume];
|
||||
|
||||
//
|
||||
// Plot the whole waveform
|
||||
//
|
||||
self.audioPlot.plotType = EZPlotTypeBuffer;
|
||||
self.audioPlot.shouldFill = YES;
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
|
||||
__weak typeof (self) weakSelf = self;
|
||||
[self.audioFile getWaveformDataWithCompletionBlock:^(float **waveformData,
|
||||
int length)
|
||||
@@ -133,23 +202,29 @@
|
||||
[weakSelf.audioPlot updateBuffer:waveformData[0]
|
||||
withBufferSize:length];
|
||||
}];
|
||||
|
||||
//
|
||||
// Play the audio file
|
||||
//
|
||||
[self.player setAudioFile:self.audioFile];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)play:(id)sender
|
||||
{
|
||||
if (![self.output isPlaying])
|
||||
if ([self.player isPlaying])
|
||||
{
|
||||
if (self.eof)
|
||||
{
|
||||
[self.audioFile seekToFrame:0];
|
||||
}
|
||||
[self.output startPlayback];
|
||||
[self.player pause];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.output stopPlayback];
|
||||
if (self.audioPlot.shouldMirror && (self.audioPlot.plotType == EZPlotTypeBuffer))
|
||||
{
|
||||
self.audioPlot.shouldMirror = NO;
|
||||
self.audioPlot.shouldFill = NO;
|
||||
}
|
||||
[self.player play];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +232,39 @@
|
||||
|
||||
- (void)seekToFrame:(id)sender
|
||||
{
|
||||
[self.audioFile seekToFrame:(SInt64)[(UISlider *)sender value]];
|
||||
[self.player seekToFrame:(SInt64)[(UISlider *)sender value]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayerDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
playedAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
inAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSelf.audioPlot updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
updatedPosition:(SInt64)framePosition
|
||||
inAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!weakSelf.positionSlider.touchInside)
|
||||
{
|
||||
weakSelf.positionSlider.value = (float)framePosition;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -186,73 +293,6 @@
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFileDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioFile:(EZAudioFile *)audioFile
|
||||
updatedPosition:(SInt64)framePosition
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!weakSelf.framePositionSlider.touchInside)
|
||||
{
|
||||
weakSelf.framePositionSlider.value = (float)framePosition;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDataSource
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (OSStatus) output:(EZOutput *)output
|
||||
shouldFillAudioBufferList:(AudioBufferList *)audioBufferList
|
||||
withNumberOfFrames:(UInt32)frames
|
||||
timestamp:(const AudioTimeStamp *)timestamp
|
||||
{
|
||||
if (self.audioFile)
|
||||
{
|
||||
UInt32 bufferSize;
|
||||
BOOL eof;
|
||||
[self.audioFile readFrames:frames
|
||||
audioBufferList:audioBufferList
|
||||
bufferSize:&bufferSize
|
||||
eof:&eof];
|
||||
if (eof)
|
||||
{
|
||||
[self.audioFile seekToFrame:0];
|
||||
}
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) output:(EZOutput *)output
|
||||
playedAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if ([self.output isPlaying])
|
||||
{
|
||||
if (weakSelf.audioPlot.plotType == EZPlotTypeBuffer &&
|
||||
weakSelf.audioPlot.shouldFill == YES &&
|
||||
weakSelf.audioPlot.shouldMirror == YES)
|
||||
{
|
||||
weakSelf.audioPlot.shouldFill = NO;
|
||||
weakSelf.audioPlot.shouldMirror = NO;
|
||||
}
|
||||
[weakSelf.audioPlot updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
+2
-6
@@ -17,7 +17,6 @@
|
||||
667559C51B3B78890013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559A81B3B78890013E67E /* EZAudioPlayer.m */; };
|
||||
667559C61B3B78890013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559AA1B3B78890013E67E /* EZAudioPlot.m */; };
|
||||
667559C71B3B78890013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559AC1B3B78890013E67E /* EZAudioPlotGL.m */; };
|
||||
667559C81B3B78890013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559AE1B3B78890013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
667559C91B3B78890013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559B01B3B78890013E67E /* EZAudioUtilities.m */; };
|
||||
667559CA1B3B78890013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559B21B3B78890013E67E /* EZMicrophone.m */; };
|
||||
667559CB1B3B78890013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559B41B3B78890013E67E /* EZOutput.m */; };
|
||||
@@ -74,8 +73,6 @@
|
||||
667559AA1B3B78890013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
667559AB1B3B78890013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
667559AC1B3B78890013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
667559AD1B3B78890013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
667559AE1B3B78890013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
667559AF1B3B78890013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
667559B01B3B78890013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
667559B11B3B78890013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -161,8 +158,6 @@
|
||||
667559AA1B3B78890013E67E /* EZAudioPlot.m */,
|
||||
667559AB1B3B78890013E67E /* EZAudioPlotGL.h */,
|
||||
667559AC1B3B78890013E67E /* EZAudioPlotGL.m */,
|
||||
667559AD1B3B78890013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
667559AE1B3B78890013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
667559AF1B3B78890013E67E /* EZAudioUtilities.h */,
|
||||
667559B01B3B78890013E67E /* EZAudioUtilities.m */,
|
||||
667559B11B3B78890013E67E /* EZMicrophone.h */,
|
||||
@@ -370,7 +365,6 @@
|
||||
667559C51B3B78890013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94057105185E805900EB94BA /* RecordViewController.m in Sources */,
|
||||
667559C71B3B78890013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667559C81B3B78890013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
667559C21B3B78890013E67E /* EZAudioFile.m in Sources */,
|
||||
667559CB1B3B78890013E67E /* EZOutput.m in Sources */,
|
||||
667559C91B3B78890013E67E /* EZAudioUtilities.m in Sources */,
|
||||
@@ -508,6 +502,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioRecordExample/EZAudioRecordExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioRecordExample/EZAudioRecordExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
@@ -521,6 +516,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioRecordExample/EZAudioRecordExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioRecordExample/EZAudioRecordExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
|
||||
@@ -14,21 +14,7 @@
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
|
||||
// Override point for customization after application launch.
|
||||
|
||||
// Remember to configure your audio session
|
||||
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
|
||||
NSError *err = NULL;
|
||||
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];
|
||||
if( err ){
|
||||
NSLog(@"There was an error creating the audio session");
|
||||
}
|
||||
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:NULL];
|
||||
if( err ){
|
||||
NSLog(@"There was an error sending the audio to the speakers");
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
+87
-64
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="llE-BN-jHz">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="llE-BN-jHz">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Record View Controller-->
|
||||
@@ -20,70 +20,91 @@
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2wj-z5-SgU" customClass="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<subviews>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1hg-FO-pPe">
|
||||
<rect key="frame" x="18" y="512" width="51" height="31"/>
|
||||
<color key="onTintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" destination="llE-BN-jHz" eventType="valueChanged" id="gDV-6T-Whu"/>
|
||||
</connections>
|
||||
</switch>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Microphone On" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0aj-Ap-Ylp">
|
||||
<rect key="frame" x="85" y="520" width="497" height="16"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="x5e-xg-u5V">
|
||||
<rect key="frame" x="18" y="551" width="51" height="31"/>
|
||||
<connections>
|
||||
<action selector="toggleRecording:" destination="llE-BN-jHz" eventType="valueChanged" id="XcR-8d-Kcd"/>
|
||||
</connections>
|
||||
</switch>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Recording On" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e1t-nE-3QJ">
|
||||
<rect key="frame" x="85" y="559" width="497" height="16"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="r8j-qU-fh6">
|
||||
<rect key="frame" x="18" y="474" width="49" height="30"/>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ua2-c0-har">
|
||||
<rect key="frame" x="0.0" y="455" width="600" height="145"/>
|
||||
<subviews>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1hg-FO-pPe">
|
||||
<rect key="frame" x="18" y="57" width="51" height="31"/>
|
||||
<color key="onTintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" destination="llE-BN-jHz" eventType="valueChanged" id="gDV-6T-Whu"/>
|
||||
</connections>
|
||||
</switch>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Microphone On" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0aj-Ap-Ylp">
|
||||
<rect key="frame" x="85" y="65" width="497" height="16"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="x5e-xg-u5V">
|
||||
<rect key="frame" x="18" y="96" width="51" height="31"/>
|
||||
<color key="onTintColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<connections>
|
||||
<action selector="toggleRecording:" destination="llE-BN-jHz" eventType="valueChanged" id="XcR-8d-Kcd"/>
|
||||
</connections>
|
||||
</switch>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Recording On" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e1t-nE-3QJ">
|
||||
<rect key="frame" x="85" y="104" width="497" height="16"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Not Playing" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zeh-I6-Na6">
|
||||
<rect key="frame" x="85" y="26" width="497" height="16"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lex-aP-CGX">
|
||||
<rect key="frame" x="13" y="19" width="59" height="30"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="LDk-Y3-uk0"/>
|
||||
<constraint firstAttribute="width" constant="59" id="zqS-lz-oEK"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="13"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<state key="normal" title="Play">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="playFile:" destination="llE-BN-jHz" eventType="touchUpInside" id="DDY-Cz-2IW"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.70000000000000007" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="dbU-fb-Yp6"/>
|
||||
<constraint firstAttribute="width" constant="49" id="jPi-0p-2oF"/>
|
||||
<constraint firstAttribute="height" constant="145" id="84N-gU-Dz9"/>
|
||||
<constraint firstAttribute="trailing" secondItem="zeh-I6-Na6" secondAttribute="trailing" constant="18" id="Nnf-8H-wts"/>
|
||||
<constraint firstItem="Lex-aP-CGX" firstAttribute="leading" secondItem="Ua2-c0-har" secondAttribute="leading" constant="13" id="Zb4-yY-8dM"/>
|
||||
<constraint firstItem="zeh-I6-Na6" firstAttribute="top" secondItem="Ua2-c0-har" secondAttribute="top" constant="26" id="l3q-uD-w0G"/>
|
||||
<constraint firstItem="zeh-I6-Na6" firstAttribute="leading" secondItem="Lex-aP-CGX" secondAttribute="trailing" constant="13" id="mnu-nJ-xAa"/>
|
||||
<constraint firstItem="Lex-aP-CGX" firstAttribute="top" secondItem="Ua2-c0-har" secondAttribute="top" constant="19" id="tAe-da-Jb2"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<state key="normal" title="Play">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="playFile:" destination="llE-BN-jHz" eventType="touchUpInside" id="IbI-bz-M5D"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Not Playing" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zeh-I6-Na6">
|
||||
<rect key="frame" x="85" y="481" width="497" height="16"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QZk-8t-iz0">
|
||||
<rect key="frame" x="18" y="18" width="80" height="39"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="light" pointSize="32"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NK6-i1-Kjf" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="107" y="18" width="475" height="39"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="39" id="pnN-yp-8eE"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="0aj-Ap-Ylp" firstAttribute="centerY" secondItem="1hg-FO-pPe" secondAttribute="centerY" id="2ID-SH-h0n"/>
|
||||
<constraint firstItem="x5e-xg-u5V" firstAttribute="centerY" secondItem="e1t-nE-3QJ" secondAttribute="centerY" id="3TN-JD-fXs"/>
|
||||
<constraint firstAttribute="trailing" secondItem="0aj-Ap-Ylp" secondAttribute="trailing" constant="18" id="Nzq-x0-Bn3"/>
|
||||
<constraint firstItem="1hg-FO-pPe" firstAttribute="leading" secondItem="2wj-z5-SgU" secondAttribute="leading" constant="18" id="SGf-Ot-ydT"/>
|
||||
<constraint firstItem="zeh-I6-Na6" firstAttribute="centerY" secondItem="r8j-qU-fh6" secondAttribute="centerY" id="SV5-g6-nAm"/>
|
||||
<constraint firstItem="zeh-I6-Na6" firstAttribute="leading" secondItem="r8j-qU-fh6" secondAttribute="trailing" constant="18" id="WrE-fc-eWU"/>
|
||||
<constraint firstItem="0aj-Ap-Ylp" firstAttribute="leading" secondItem="1hg-FO-pPe" secondAttribute="trailing" constant="18" id="Zlu-hy-toc"/>
|
||||
<constraint firstItem="r8j-qU-fh6" firstAttribute="leading" secondItem="2wj-z5-SgU" secondAttribute="leading" constant="18" id="bfv-fU-4be"/>
|
||||
<constraint firstItem="e1t-nE-3QJ" firstAttribute="leading" secondItem="x5e-xg-u5V" secondAttribute="trailing" constant="18" id="cyW-VV-2vF"/>
|
||||
<constraint firstItem="x5e-xg-u5V" firstAttribute="leading" secondItem="2wj-z5-SgU" secondAttribute="leading" constant="18" id="d1D-pw-daz"/>
|
||||
<constraint firstAttribute="bottom" secondItem="x5e-xg-u5V" secondAttribute="bottom" constant="18" id="j5C-Pr-Qr1"/>
|
||||
<constraint firstItem="1hg-FO-pPe" firstAttribute="top" secondItem="r8j-qU-fh6" secondAttribute="bottom" constant="8" id="kGE-En-5oO"/>
|
||||
<constraint firstAttribute="trailing" secondItem="zeh-I6-Na6" secondAttribute="trailing" constant="18" id="lgq-o9-XKk"/>
|
||||
<constraint firstAttribute="trailing" secondItem="e1t-nE-3QJ" secondAttribute="trailing" constant="18" id="yg8-Wi-4FL"/>
|
||||
<constraint firstItem="x5e-xg-u5V" firstAttribute="top" secondItem="1hg-FO-pPe" secondAttribute="bottom" constant="8" id="zO4-XU-4yd"/>
|
||||
<constraint firstItem="QZk-8t-iz0" firstAttribute="top" secondItem="2wj-z5-SgU" secondAttribute="top" constant="18" id="7aU-qh-lzs"/>
|
||||
<constraint firstItem="QZk-8t-iz0" firstAttribute="leading" secondItem="2wj-z5-SgU" secondAttribute="leading" constant="18" id="Aac-ba-fJG"/>
|
||||
<constraint firstAttribute="trailing" secondItem="NK6-i1-Kjf" secondAttribute="trailing" constant="18" id="BAg-ql-P64"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Ua2-c0-har" secondAttribute="trailing" id="DFS-Lr-ap6"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Ua2-c0-har" secondAttribute="bottom" id="hWL-2I-U11"/>
|
||||
<constraint firstItem="Ua2-c0-har" firstAttribute="leading" secondItem="2wj-z5-SgU" secondAttribute="leading" id="jV7-AG-ClO"/>
|
||||
<constraint firstItem="NK6-i1-Kjf" firstAttribute="leading" secondItem="QZk-8t-iz0" secondAttribute="trailing" constant="9" id="rqh-Ib-RFU"/>
|
||||
<constraint firstItem="NK6-i1-Kjf" firstAttribute="top" secondItem="2wj-z5-SgU" secondAttribute="top" constant="18" id="tRd-Ee-lnl"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
@@ -96,13 +117,15 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="audioPlot" destination="2wj-z5-SgU" id="1ih-MQ-w9g"/>
|
||||
<outlet property="currentTimeLabel" destination="QZk-8t-iz0" id="MP6-0t-jhv"/>
|
||||
<outlet property="microphoneStateLabel" destination="0aj-Ap-Ylp" id="fb1-B6-aY6"/>
|
||||
<outlet property="microphoneSwitch" destination="1hg-FO-pPe" id="SFI-AX-IjC"/>
|
||||
<outlet property="microphoneTextField" destination="0aj-Ap-Ylp" id="748-Fq-ubg"/>
|
||||
<outlet property="playButton" destination="r8j-qU-fh6" id="tmR-Nt-pKO"/>
|
||||
<outlet property="playingTextField" destination="zeh-I6-Na6" id="bsZ-bd-HDD"/>
|
||||
<outlet property="playButton" destination="Lex-aP-CGX" id="K8T-X8-Tfy"/>
|
||||
<outlet property="playingAudioPlot" destination="NK6-i1-Kjf" id="bes-5F-Cfa"/>
|
||||
<outlet property="playingStateLabel" destination="zeh-I6-Na6" id="Tpj-mT-wwx"/>
|
||||
<outlet property="recordSwitch" destination="x5e-xg-u5V" id="yZ8-zX-x4o"/>
|
||||
<outlet property="recordingTextField" destination="e1t-nE-3QJ" id="Vr4-cl-5zt"/>
|
||||
<outlet property="recordingAudioPlot" destination="2wj-z5-SgU" id="2hH-vO-WSb"/>
|
||||
<outlet property="recordingStateLabel" destination="e1t-nE-3QJ" id="PDc-R4-k0n"/>
|
||||
<outlet property="view" destination="PCx-Sz-N5f" id="fk5-lV-jnA"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
|
||||
+90
-11
@@ -11,48 +11,127 @@
|
||||
// Import EZAudio header
|
||||
#import "EZAudio.h"
|
||||
|
||||
// Import AVFoundation to play the file (will save EZAudioFile and EZOutput for separate example)
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
// By default this will record a file to the application's documents directory (within the application's sandbox)
|
||||
#define kAudioFilePath @"EZAudioTest.m4a"
|
||||
|
||||
@interface RecordViewController : UIViewController <AVAudioPlayerDelegate,EZMicrophoneDelegate>
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - RecordViewController
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@interface RecordViewController : UIViewController <EZAudioPlayerDelegate,
|
||||
EZMicrophoneDelegate,
|
||||
EZRecorderDelegate>
|
||||
|
||||
/**
|
||||
The label used to display the current time for recording/playback in the top left
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UILabel *currentTimeLabel;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Use a OpenGL based plot to visualize the data coming in
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlotGL *audioPlot;
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlotGL *recordingAudioPlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A flag indicating whether we are recording or not
|
||||
*/
|
||||
@property (nonatomic,assign) BOOL isRecording;
|
||||
@property (nonatomic, assign) BOOL isRecording;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The microphone component
|
||||
*/
|
||||
@property (nonatomic,strong) EZMicrophone *microphone;
|
||||
@property (nonatomic, strong) EZMicrophone *microphone;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The switch used to toggle the microphone on/off
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UISwitch *microphoneSwitch;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The label used to display the microphone's play state
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UILabel *microphoneStateLabel;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The audio player that will play the recorded file
|
||||
*/
|
||||
@property (nonatomic, strong) EZAudioPlayer *player;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The recorder component
|
||||
*/
|
||||
@property (nonatomic,strong) EZRecorder *recorder;
|
||||
@property (nonatomic, strong) EZRecorder *recorder;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The second audio plot used on the top right to display the current playing audio
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlot *playingAudioPlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The button the user taps to play the recorded audio file
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UIButton *playButton;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The label used to display the audio player play state
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UILabel *playingStateLabel;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The label used to display the recording play state
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UILabel *recordingStateLabel;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The switch used to toggle the recording on/off
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UISwitch *recordSwitch;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Stops the recorder and starts playing whatever has been recorded.
|
||||
*/
|
||||
-(IBAction)playFile:(id)sender;
|
||||
- (IBAction)playFile:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Toggles the microphone on and off. When the microphone is on it will send its delegate (aka this view controller) the audio data in various ways (check out the EZMicrophoneDelegate documentation for more details);
|
||||
*/
|
||||
-(IBAction)toggleMicrophone:(id)sender;
|
||||
- (IBAction)toggleMicrophone:(id)sender;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Toggles the microphone on and off. When the microphone is on it will send its delegate (aka this view controller) the audio data in various ways (check out the EZMicrophoneDelegate documentation for more details);
|
||||
*/
|
||||
-(IBAction)toggleRecording:(id)sender;
|
||||
- (IBAction)toggleRecording:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
+242
-177
@@ -8,53 +8,34 @@
|
||||
|
||||
#import "RecordViewController.h"
|
||||
|
||||
@interface RecordViewController ()
|
||||
// Using AVPlayer for example
|
||||
@property (nonatomic,strong) AVAudioPlayer *audioPlayer;
|
||||
@property (nonatomic,weak) IBOutlet UISwitch *microphoneSwitch;
|
||||
@property (nonatomic,weak) IBOutlet UILabel *microphoneTextField;
|
||||
@property (nonatomic,weak) IBOutlet UIButton *playButton;
|
||||
@property (nonatomic,weak) IBOutlet UILabel *playingTextField;
|
||||
@property (nonatomic,weak) IBOutlet UISwitch *recordSwitch;
|
||||
@property (nonatomic,weak) IBOutlet UILabel *recordingTextField;
|
||||
@end
|
||||
|
||||
@implementation RecordViewController
|
||||
@synthesize audioPlot;
|
||||
@synthesize microphone;
|
||||
@synthesize microphoneSwitch;
|
||||
@synthesize microphoneTextField;
|
||||
@synthesize playButton;
|
||||
@synthesize playingTextField;
|
||||
@synthesize recorder;
|
||||
@synthesize recordSwitch;
|
||||
@synthesize recordingTextField;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Status Bar Style
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
return UIStatusBarStyleLightContent;
|
||||
}
|
||||
|
||||
#pragma mark - Initialization
|
||||
-(id)init {
|
||||
self = [super init];
|
||||
if(self){
|
||||
[self initializeViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(id)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if(self){
|
||||
[self initializeViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
#pragma mark - Initialize View Controller Here
|
||||
-(void)initializeViewController {
|
||||
//
|
||||
// Setup the AVAudioSession. EZMicrophone will not work properly on iOS
|
||||
// if you don't do this!
|
||||
@@ -72,193 +53,277 @@
|
||||
NSLog(@"Error setting up audio session active: %@", error.localizedDescription);
|
||||
}
|
||||
|
||||
//
|
||||
// Customizing the audio plot that'll show the current microphone input/recording
|
||||
//
|
||||
self.recordingAudioPlot.backgroundColor = [UIColor colorWithRed: 0.984 green: 0.71 blue: 0.365 alpha: 1];
|
||||
self.recordingAudioPlot.color = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
self.recordingAudioPlot.plotType = EZPlotTypeRolling;
|
||||
self.recordingAudioPlot.shouldFill = YES;
|
||||
self.recordingAudioPlot.shouldMirror = YES;
|
||||
|
||||
//
|
||||
// Customizing the audio plot that'll show the playback
|
||||
//
|
||||
self.playingAudioPlot.color = [UIColor whiteColor];
|
||||
self.playingAudioPlot.plotType = EZPlotTypeRolling;
|
||||
self.playingAudioPlot.shouldFill = YES;
|
||||
self.playingAudioPlot.shouldMirror = YES;
|
||||
self.playingAudioPlot.gain = 2.5f;
|
||||
|
||||
// Create an instance of the microphone and tell it to use this view controller instance as the delegate
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self];
|
||||
self.player = [EZAudioPlayer audioPlayerWithDelegate:self];
|
||||
|
||||
//
|
||||
// Initialize UI components
|
||||
//
|
||||
self.microphoneStateLabel.text = @"Microphone On";
|
||||
self.recordingStateLabel.text = @"Not Recording";
|
||||
self.playingStateLabel.text = @"Not Playing";
|
||||
self.playButton.enabled = NO;
|
||||
|
||||
//
|
||||
// Setup notifications
|
||||
//
|
||||
[self setupNotifications];
|
||||
|
||||
//
|
||||
// Log out where the file is being written to within the app's documents directory
|
||||
//
|
||||
NSLog(@"File written to application sandbox's documents directory: %@",[self testFilePathURL]);
|
||||
|
||||
//
|
||||
// Start the microphone
|
||||
//
|
||||
[self.microphone startFetchingAudio];
|
||||
}
|
||||
|
||||
#pragma mark - Customize the Audio Plot
|
||||
-(void)viewDidLoad {
|
||||
|
||||
[super viewDidLoad];
|
||||
|
||||
/*
|
||||
Customizing the audio plot's look
|
||||
*/
|
||||
// Background color
|
||||
self.audioPlot.backgroundColor = [UIColor colorWithRed: 0.984 green: 0.71 blue: 0.365 alpha: 1];
|
||||
// Waveform color
|
||||
self.audioPlot.color = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
// Plot type
|
||||
self.audioPlot.plotType = EZPlotTypeRolling;
|
||||
// Fill
|
||||
self.audioPlot.shouldFill = YES;
|
||||
// Mirror
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
|
||||
/*
|
||||
Start the microphone
|
||||
*/
|
||||
[self.microphone startFetchingAudio];
|
||||
self.microphoneTextField.text = @"Microphone On";
|
||||
self.recordingTextField.text = @"Not Recording";
|
||||
self.playingTextField.text = @"Not Playing";
|
||||
|
||||
// Hide the play button
|
||||
self.playButton.hidden = YES;
|
||||
|
||||
/*
|
||||
Log out where the file is being written to within the app's documents directory
|
||||
*/
|
||||
NSLog(@"File written to application sandbox's documents directory: %@",[self testFilePathURL]);
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - Actions
|
||||
-(void)playFile:(id)sender
|
||||
- (void)setupNotifications
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(playerDidChangePlayState:)
|
||||
name:EZAudioPlayerDidChangePlayStateNotification
|
||||
object:self.player];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(playerDidReachEndOfFile:)
|
||||
name:EZAudioPlayerDidReachEndOfFileNotification
|
||||
object:self.player];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Notifications
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)playerDidChangePlayState:(NSNotification *)notification
|
||||
{
|
||||
EZAudioPlayer *player = [notification object];
|
||||
BOOL isPlaying = [player isPlaying];
|
||||
if (isPlaying)
|
||||
{
|
||||
self.recorder.delegate = nil;
|
||||
}
|
||||
self.playingStateLabel.text = isPlaying ? @"Playing" : @"Not Playing";
|
||||
self.playingAudioPlot.hidden = !isPlaying;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)playerDidReachEndOfFile:(NSNotification *)notification
|
||||
{
|
||||
[self.playingAudioPlot clear];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)playFile:(id)sender
|
||||
{
|
||||
//
|
||||
// Update microphone state
|
||||
//
|
||||
[self.microphone stopFetchingAudio];
|
||||
self.microphoneTextField.text = @"Microphone Off";
|
||||
self.microphoneSwitch.on = NO;
|
||||
|
||||
//
|
||||
// Update recording state
|
||||
//
|
||||
self.isRecording = NO;
|
||||
self.recordingTextField.text = @"Not Recording";
|
||||
self.recordingStateLabel.text = @"Not Recording";
|
||||
self.recordSwitch.on = NO;
|
||||
|
||||
// Create Audio Player
|
||||
if( self.audioPlayer )
|
||||
{
|
||||
if( self.audioPlayer.playing )
|
||||
{
|
||||
[self.audioPlayer stop];
|
||||
}
|
||||
self.audioPlayer = nil;
|
||||
}
|
||||
|
||||
//
|
||||
// Close the audio file
|
||||
if( self.recorder )
|
||||
//
|
||||
if (self.recorder)
|
||||
{
|
||||
[self.recorder closeAudioFile];
|
||||
}
|
||||
|
||||
NSError *err;
|
||||
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[self testFilePathURL]
|
||||
error:&err];
|
||||
[self.audioPlayer play];
|
||||
self.audioPlayer.delegate = self;
|
||||
self.playingTextField.text = @"Playing";
|
||||
|
||||
EZAudioFile *audioFile = [EZAudioFile audioFileWithURL:[self testFilePathURL]];
|
||||
[self.player playAudioFile:audioFile];
|
||||
}
|
||||
|
||||
-(void)toggleMicrophone:(id)sender {
|
||||
|
||||
self.playingTextField.text = @"Not Playing";
|
||||
if( self.audioPlayer ){
|
||||
if( self.audioPlayer.playing ) [self.audioPlayer stop];
|
||||
self.audioPlayer = nil;
|
||||
}
|
||||
|
||||
if( ![(UISwitch*)sender isOn] ){
|
||||
[self.microphone stopFetchingAudio];
|
||||
self.microphoneTextField.text = @"Microphone Off";
|
||||
}
|
||||
else {
|
||||
[self.microphone startFetchingAudio];
|
||||
self.microphoneTextField.text = @"Microphone On";
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void)toggleRecording:(id)sender {
|
||||
|
||||
self.playingTextField.text = @"Not Playing";
|
||||
if( self.audioPlayer )
|
||||
{
|
||||
if( self.audioPlayer.playing )
|
||||
{
|
||||
[self.audioPlayer stop];
|
||||
}
|
||||
self.audioPlayer = nil;
|
||||
}
|
||||
self.playButton.hidden = NO;
|
||||
- (void)toggleMicrophone:(id)sender
|
||||
{
|
||||
[self.player pause];
|
||||
|
||||
if( [sender isOn] )
|
||||
BOOL isOn = [(UISwitch*)sender isOn];
|
||||
if (!isOn)
|
||||
{
|
||||
/*
|
||||
Create the recorder
|
||||
*/
|
||||
[EZAudioUtilities printASBD:self.microphone.audioStreamBasicDescription];
|
||||
self.recorder = [EZRecorder recorderWithDestinationURL:[self testFilePathURL]
|
||||
sourceFormat:self.microphone.audioStreamBasicDescription
|
||||
destinationFileType:EZRecorderFileTypeM4A];
|
||||
[self.microphone stopFetchingAudio];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.recorder closeAudioFile];
|
||||
[self.microphone startFetchingAudio];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)toggleRecording:(id)sender
|
||||
{
|
||||
[self.player pause];
|
||||
if ([sender isOn])
|
||||
{
|
||||
//
|
||||
// Create the recorder
|
||||
//
|
||||
[self.recordingAudioPlot clear];
|
||||
[self.microphone startFetchingAudio];
|
||||
self.recorder = [EZRecorder recorderWithURL:[self testFilePathURL]
|
||||
clientFormat:[self.microphone audioStreamBasicDescription]
|
||||
fileType:EZRecorderFileTypeM4A
|
||||
delegate:self];
|
||||
self.playButton.enabled = YES;
|
||||
}
|
||||
self.isRecording = (BOOL)[sender isOn];
|
||||
self.recordingTextField.text = self.isRecording ? @"Recording" : @"Not Recording";
|
||||
self.recordingStateLabel.text = self.isRecording ? @"Recording" : @"Not Recording";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)microphone:(EZMicrophone *)microphone changedPlayingState:(BOOL)isPlaying
|
||||
{
|
||||
self.microphoneStateLabel.text = isPlaying ? @"Microphone On" : @"Microphone Off";
|
||||
self.microphoneSwitch.on = isPlaying;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#warning Thread Safety
|
||||
// Note that any callback that provides streamed audio data (like streaming microphone input) happens on a separate audio thread that should not be blocked. When we feed audio data into any of the UI components we need to explicity create a GCD block on the main thread to properly get the UI to work.
|
||||
-(void)microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
// Getting audio data as an array of float buffer arrays. What does that mean? Because the audio is coming in as a stereo signal the data is split into a left and right channel. So buffer[0] corresponds to the float* data for the left channel while buffer[1] corresponds to the float* data for the right channel.
|
||||
- (void) microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
// Getting audio data as an array of float buffer arrays. What does that mean? Because the audio is coming in as a stereo signal the data is split into a left and right channel. So buffer[0] corresponds to the float* data for the left channel while buffer[1] corresponds to the float* data for the right channel.
|
||||
|
||||
// See the Thread Safety warning above, but in a nutshell these callbacks happen on a separate audio thread. We wrap any UI updating in a GCD block on the main thread to avoid blocking that audio flow.
|
||||
dispatch_async(dispatch_get_main_queue(),^{
|
||||
// All the audio plot needs is the buffer data (float*) and the size. Internally the audio plot will handle all the drawing related code, history management, and freeing its own resources. Hence, one badass line of code gets you a pretty plot :)
|
||||
[self.audioPlot updateBuffer:buffer[0] withBufferSize:bufferSize];
|
||||
});
|
||||
// See the Thread Safety warning above, but in a nutshell these callbacks happen on a separate audio thread. We wrap any UI updating in a GCD block on the main thread to avoid blocking that audio flow.
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// All the audio plot needs is the buffer data (float*) and the size. Internally the audio plot will handle all the drawing related code, history management, and freeing its own resources. Hence, one badass line of code gets you a pretty plot :)
|
||||
[weakSelf.recordingAudioPlot updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
});
|
||||
}
|
||||
|
||||
-(void)microphone:(EZMicrophone *)microphone
|
||||
hasBufferList:(AudioBufferList *)bufferList
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
|
||||
// Getting audio data as a buffer list that can be directly fed into the EZRecorder. This is happening on the audio thread - any UI updating needs a GCD main queue block. This will keep appending data to the tail of the audio file.
|
||||
if( self.isRecording ){
|
||||
[self.recorder appendDataFromBufferList:bufferList
|
||||
withBufferSize:bufferSize];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) microphone:(EZMicrophone *)microphone
|
||||
hasBufferList:(AudioBufferList *)bufferList
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
// Getting audio data as a buffer list that can be directly fed into the EZRecorder. This is happening on the audio thread - any UI updating needs a GCD main queue block. This will keep appending data to the tail of the audio file.
|
||||
if (self.isRecording)
|
||||
{
|
||||
[self.recorder appendDataFromBufferList:bufferList
|
||||
withBufferSize:bufferSize];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - AVAudioPlayerDelegate
|
||||
/*
|
||||
Occurs when the audio player instance completes playback
|
||||
*/
|
||||
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
|
||||
self.audioPlayer = nil;
|
||||
self.playingTextField.text = @"Finished Playing";
|
||||
|
||||
[self.microphone startFetchingAudio];
|
||||
self.microphoneSwitch.on = YES;
|
||||
self.microphoneTextField.text = @"Microphone On";
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZRecorderDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)recorderDidClose:(EZRecorder *)recorder
|
||||
{
|
||||
recorder.delegate = nil;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)recorderUpdatedCurrentTime:(EZRecorder *)recorder
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
NSString *formattedCurrentTime = [recorder formattedCurrentTime];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
weakSelf.currentTimeLabel.text = formattedCurrentTime;
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayerDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
playedAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
inAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSelf.playingAudioPlot updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
updatedPosition:(SInt64)framePosition
|
||||
inAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
weakSelf.currentTimeLabel.text = [audioPlayer formattedCurrentTime];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Utility
|
||||
-(NSArray*)applicationDocuments {
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSArray *)applicationDocuments
|
||||
{
|
||||
return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
}
|
||||
|
||||
-(NSString*)applicationDocumentsDirectory
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)applicationDocumentsDirectory
|
||||
{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
|
||||
return basePath;
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
|
||||
return basePath;
|
||||
}
|
||||
|
||||
-(NSURL*)testFilePathURL {
|
||||
return [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@",
|
||||
[self applicationDocumentsDirectory],
|
||||
kAudioFilePath]];
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSURL *)testFilePathURL
|
||||
{
|
||||
return [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@",
|
||||
[self applicationDocumentsDirectory],
|
||||
kAudioFilePath]];
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
+2
-6
@@ -17,7 +17,6 @@
|
||||
6675598C1B3B78820013E67E /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675596F1B3B78820013E67E /* EZAudioPlayer.m */; };
|
||||
6675598D1B3B78820013E67E /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559711B3B78820013E67E /* EZAudioPlot.m */; };
|
||||
6675598E1B3B78820013E67E /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559731B3B78820013E67E /* EZAudioPlotGL.m */; };
|
||||
6675598F1B3B78820013E67E /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559751B3B78820013E67E /* EZAudioPlotGLKViewController.m */; };
|
||||
667559901B3B78820013E67E /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559771B3B78820013E67E /* EZAudioUtilities.m */; };
|
||||
667559911B3B78820013E67E /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 667559791B3B78820013E67E /* EZMicrophone.m */; };
|
||||
667559921B3B78820013E67E /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 6675597B1B3B78820013E67E /* EZOutput.m */; };
|
||||
@@ -75,8 +74,6 @@
|
||||
667559711B3B78820013E67E /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
667559721B3B78820013E67E /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
667559731B3B78820013E67E /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
667559741B3B78820013E67E /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
667559751B3B78820013E67E /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
667559761B3B78820013E67E /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
667559771B3B78820013E67E /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
667559781B3B78820013E67E /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
@@ -163,8 +160,6 @@
|
||||
667559711B3B78820013E67E /* EZAudioPlot.m */,
|
||||
667559721B3B78820013E67E /* EZAudioPlotGL.h */,
|
||||
667559731B3B78820013E67E /* EZAudioPlotGL.m */,
|
||||
667559741B3B78820013E67E /* EZAudioPlotGLKViewController.h */,
|
||||
667559751B3B78820013E67E /* EZAudioPlotGLKViewController.m */,
|
||||
667559761B3B78820013E67E /* EZAudioUtilities.h */,
|
||||
667559771B3B78820013E67E /* EZAudioUtilities.m */,
|
||||
667559781B3B78820013E67E /* EZMicrophone.h */,
|
||||
@@ -374,7 +369,6 @@
|
||||
6675598C1B3B78820013E67E /* EZAudioPlayer.m in Sources */,
|
||||
9405706E185E69D400EB94BA /* AppDelegate.m in Sources */,
|
||||
6675598E1B3B78820013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
6675598F1B3B78820013E67E /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
667559891B3B78820013E67E /* EZAudioFile.m in Sources */,
|
||||
667559921B3B78820013E67E /* EZOutput.m in Sources */,
|
||||
667559901B3B78820013E67E /* EZAudioUtilities.m in Sources */,
|
||||
@@ -512,6 +506,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioWaveformFromFileExample/EZAudioWaveformFromFileExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioWaveformFromFileExample/EZAudioWaveformFromFileExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
@@ -525,6 +520,7 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioWaveformFromFileExample/EZAudioWaveformFromFileExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioWaveformFromFileExample/EZAudioWaveformFromFileExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="d7h-J5-hmC">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="d7h-J5-hmC">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Waveform From File View Controller-->
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#EZAudio
|
||||
A simple, intuitive audio framework for iOS and OSX.
|
||||
|
||||
# Note as of July 2, 2015
|
||||
Over the last week I've been rewriting the core components of EZAudio to be faster and much more flexible. As EZAudio gets closer its 1.0 release the API has changed a little bit for each component and as a result this repo's README for the [Examples](#Examples) and [Core Components](#CoreComponents) are in a deprecated state, but will be updated tomorrow <b>July 3rd, 2015</b>. As of the `0.7.1` release you should be able to use EZAudio and the Amazing Audio Engine by using the `EZAudio/Core` Cocoapod (see [Using EZAudio & The Amazing Audio Engine](#AmazingAudioEngineCocoapod))
|
||||
|
||||
##Features
|
||||

|
||||
|
||||
@@ -38,7 +41,7 @@ An OpenGL-based, GPU-accelerated audio waveform plot capable of visualizing any
|
||||
|
||||
`EZAudio` was designed to work transparently across all iOS and OSX devices. This means one universal API whether you're building for Mac or iOS. For instance, under the hood an `EZAudioPlot` knows that it will subclass a UIView for iOS or an NSView for OSX and the `EZMicrophone` knows to build on top of the RemoteIO AudioUnit for iOS, but defaults to the system defaults for input and output for OSX.
|
||||
|
||||
##Examples & Docs
|
||||
##<a name="Examples">Examples & Docs
|
||||
|
||||
Within this repo you'll find the examples for iOS and OSX to get you up to speed using each component and plugging them into each other. With just a few lines of code you'll be recording from the microphone, generating audio waveforms, and playing audio files like a boss. See the full Getting Started guide for an interactive look into each of components.
|
||||
|
||||
@@ -75,17 +78,16 @@ Shows how to calculate the real-time FFT of the audio data coming from the `EZMi
|
||||

|
||||
|
||||
### Documentation
|
||||
The official documentation for EZAudio can be found here: http://cocoadocs.org/docsets/EZAudio/0.0.5/
|
||||
The official documentation for EZAudio can be found here: http://cocoadocs.org/docsets/EZAudio/0.9.0/
|
||||
<br>You can also generate the docset yourself using appledocs by running the appledocs on the EZAudio source folder.
|
||||
|
||||
##Getting Started
|
||||
##<a name="GettingStarted">Getting Started
|
||||
To begin using `EZAudio` you must first make sure you have the proper build requirements and frameworks. Below you'll find explanations of each component and code snippets to show how to use each to perform common tasks like getting microphone data, updating audio waveform plots, reading/seeking through audio files, and performing playback.
|
||||
|
||||
###Build Requirements
|
||||
**iOS**
|
||||
- 6.0+
|
||||
|
||||
|
||||
**OSX**
|
||||
- 10.8+
|
||||
|
||||
@@ -95,7 +97,6 @@ To begin using `EZAudio` you must first make sure you have the proper build requ
|
||||
- AVFoundation
|
||||
- GLKit
|
||||
|
||||
|
||||
**OSX**
|
||||
- AudioToolbox
|
||||
- AudioUnit
|
||||
@@ -104,16 +105,24 @@ To begin using `EZAudio` you must first make sure you have the proper build requ
|
||||
- OpenGL
|
||||
- GLKit
|
||||
|
||||
###Adding To Project
|
||||
###<a name="AddingToProject">Adding To Project
|
||||
You can add EZAudio to your project in a few ways: <br><br>1.) The easiest way to use EZAudio is via <a href="http://cocoapods.org/", target="_blank">Cocoapods</a>. Simply add EZAudio to your <a href="http://guides.cocoapods.org/using/the-podfile.html", target="_blank">Podfile</a> like so:
|
||||
|
||||
`
|
||||
pod 'EZAudio', '~> 0.4.0'
|
||||
pod 'EZAudio', '~> 0.9.0'
|
||||
`
|
||||
|
||||
####<a name="AmazingAudioEngineCocoapod">Using EZAudio & The Amazing Audio Engine
|
||||
If you're also using the Amazing Audio Engine then use the `EZAudio/Core` subspec like so:
|
||||
|
||||
`
|
||||
pod 'EZAudio/Core', '~> 0.9.0'
|
||||
`
|
||||
|
||||
2.) Alternatively, you could clone or fork this repo and just drag and drop the source into your project.
|
||||
|
||||
##Core Components
|
||||
##<a name="CoreComponents"></a>Core Components
|
||||
|
||||
`EZAudio` currently offers four components that encompass a wide range of audio functionality. In addition to the functional aspects of these components such as pulling audio data, reading/writing from files, and performing playback they also take special care to hook into the interface components to allow developers to display visual feedback (see the Interface Components below).
|
||||
|
||||
###<a name="EZAudioFile"></a>EZAudioFile
|
||||
|
||||
Reference in New Issue
Block a user