Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 618be0dc70 | |||
| 579f924aef | |||
| 43418bb825 | |||
| f474b55375 | |||
| 232b02904c | |||
| b093e479d7 | |||
| 98707d0cf1 | |||
| fc091642d9 | |||
| 5cd022a510 | |||
| c8b144667a | |||
| 4d0bd00c79 | |||
| fb0e1cff2d | |||
| 4d2c8f3fef | |||
| 1dd7c7bec9 | |||
| 4622815a19 | |||
| 512f896dff | |||
| fd837d46ea | |||
| 689e004814 | |||
| ef6b6ee5a7 | |||
| 8d8246c3c6 | |||
| 1dc2fc2ba9 | |||
| 2431b25204 | |||
| 2e9af21099 | |||
| b06bbb99fb | |||
| 2ac8e4ec42 | |||
| 6739c70063 | |||
| ec55542b8d | |||
| 08874048fc | |||
| cd887d002d | |||
| 0e274696bf | |||
| 820e0d3f21 | |||
| a5ff527a3a | |||
| d725db31bc | |||
| b9f80eeee7 | |||
| 54345f2d6e | |||
| 6cafae6236 | |||
| e0c4d3adca | |||
| b8513ab62d | |||
| f31b90a4e2 | |||
| da4fdb6692 | |||
| 567e0f61e9 |
+2
-2
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "EZAudio"
|
||||
s.version = "0.0.1"
|
||||
s.version = "0.0.2"
|
||||
s.summary = "A simple, intuitive audio framework for iOS and OSX useful for anyone doing audio processing and/or audio-based visualizations."
|
||||
s.homepage = "http://syedharisali.com/projects/EZAudio/getting-started"
|
||||
s.screenshots = "https://s3-us-west-1.amazonaws.com/ezaudio-media/EZAudioSummary.png"
|
||||
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
|
||||
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 => "0.0.1" }
|
||||
s.source = { :git => "https://github.com/syedhali/EZAudio.git", :tag => "0.0.2" }
|
||||
s.source_files = 'EZAudio/*.{h,m,c}'
|
||||
s.exclude_files = 'EZAudio/VERSION'
|
||||
s.ios.frameworks = 'AudioToolbox','GLKit'
|
||||
|
||||
@@ -66,6 +66,38 @@
|
||||
+(void)freeBufferList:(AudioBufferList*)bufferList;
|
||||
|
||||
#pragma mark - AudioStreamBasicDescription Utilties
|
||||
///-----------------------------------------------------------
|
||||
/// @name Creating An AudioStreamBasicDescription
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@param sampleRate The desired sample rate for the AudioStreamBasicDescription
|
||||
@return A new AudioStreamBasicDescription with the specified format.
|
||||
*/
|
||||
+(AudioStreamBasicDescription)monoFloatFormatWithSampleRate:(float)sampleRate;
|
||||
|
||||
/**
|
||||
|
||||
@param sampleRate The desired sample rate for the AudioStreamBasicDescription
|
||||
@return A new AudioStreamBasicDescription with the specified format.
|
||||
*/
|
||||
+(AudioStreamBasicDescription)monoCanonicalFormatWithSampleRate:(float)sampleRate;
|
||||
|
||||
/**
|
||||
|
||||
@param sampleRate The desired sample rate for the AudioStreamBasicDescription
|
||||
@return A new AudioStreamBasicDescription with the specified format.
|
||||
*/
|
||||
+(AudioStreamBasicDescription)stereoCanonicalNonInterleavedFormatWithSampleRate:(float)sampleRate;
|
||||
|
||||
/**
|
||||
|
||||
@param sampleRate The desired sample rate for the AudioStreamBasicDescription
|
||||
@return A new AudioStreamBasicDescription with the specified format.
|
||||
*/
|
||||
+(AudioStreamBasicDescription)stereoFloatInterleavedFormatWithSampleRate:(float)sampleRate;
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name AudioStreamBasicDescription Utilities
|
||||
///-----------------------------------------------------------
|
||||
@@ -91,6 +123,28 @@
|
||||
/// @name Math Utilities
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Appends an array of values to a history buffer and performs an internal shift to add the values to the tail and removes the same number of values from the head.
|
||||
@param buffer A float array of values to append to the tail of the history buffer
|
||||
@param bufferLength The length of the float array being appended to the history buffer
|
||||
@param scrollHistory The target history buffer in which to append the values
|
||||
@param scrollHistoryLength The length of the target history buffer
|
||||
*/
|
||||
+(void)appendBufferAndShift:(float*)buffer
|
||||
withBufferSize:(int)bufferLength
|
||||
toScrollHistory:(float*)scrollHistory
|
||||
withScrollHistorySize:(int)scrollHistoryLength;
|
||||
|
||||
/**
|
||||
Appends a value to a history buffer and performs an internal shift to add the value to the tail and remove the 0th value.
|
||||
@param value The float value to append to the history array
|
||||
@param scrollHistory The target history buffer in which to append the values
|
||||
@param scrollHistoryLength The length of the target history buffer
|
||||
*/
|
||||
+(void) appendValue:(float)value
|
||||
toScrollHistory:(float*)scrollHistory
|
||||
withScrollHistorySize:(int)scrollHistoryLength;
|
||||
|
||||
/**
|
||||
Maps a value from one coordinate system into another one. Takes in the current value to map, the minimum and maximum values of the first coordinate system, and the minimum and maximum values of the second coordinate system and calculates the mapped value in the second coordinate system's constraints.
|
||||
@param value The value expressed in the first coordinate system
|
||||
@@ -128,6 +182,18 @@
|
||||
+(void)checkResult:(OSStatus)result
|
||||
operation:(const char*)operation;
|
||||
|
||||
#pragma mark - Plot Utility
|
||||
///-----------------------------------------------------------
|
||||
/// @name Plot Utility
|
||||
///-----------------------------------------------------------
|
||||
|
||||
+(void)updateScrollHistory:(float**)scrollHistory
|
||||
withLength:(int)scrollHistoryLength
|
||||
atIndex:(int*)index
|
||||
withBuffer:(float*)buffer
|
||||
withBufferSize:(int)bufferSize
|
||||
isResolutionChanging:(BOOL*)isChanging;
|
||||
|
||||
#pragma mark - TPCircularBuffer Utility
|
||||
///-----------------------------------------------------------
|
||||
/// @name TPCircularBuffer Utility
|
||||
|
||||
@@ -44,6 +44,64 @@
|
||||
}
|
||||
|
||||
#pragma mark - AudioStreamBasicDescription Utility
|
||||
/// AudioStreamFormatDescription Helpers
|
||||
|
||||
+(AudioStreamBasicDescription)monoFloatFormatWithSampleRate:(float)sampleRate {
|
||||
AudioStreamBasicDescription asbd;
|
||||
UInt32 byteSize = sizeof(AudioUnitSampleType);
|
||||
asbd.mBitsPerChannel = 8 * byteSize;
|
||||
asbd.mBytesPerFrame = byteSize;
|
||||
asbd.mBytesPerPacket = byteSize;
|
||||
asbd.mChannelsPerFrame = 1;
|
||||
asbd.mFormatFlags = kAudioFormatFlagIsPacked|kAudioFormatFlagIsFloat;
|
||||
asbd.mFormatID = kAudioFormatLinearPCM;
|
||||
asbd.mFramesPerPacket = 1;
|
||||
asbd.mSampleRate = sampleRate;
|
||||
return asbd;
|
||||
}
|
||||
|
||||
+(AudioStreamBasicDescription)monoCanonicalFormatWithSampleRate:(float)sampleRate {
|
||||
AudioStreamBasicDescription asbd;
|
||||
UInt32 byteSize = sizeof(AudioUnitSampleType);
|
||||
asbd.mBitsPerChannel = 8 * byteSize;
|
||||
asbd.mBytesPerFrame = byteSize;
|
||||
asbd.mBytesPerPacket = byteSize;
|
||||
asbd.mChannelsPerFrame = 1;
|
||||
asbd.mFormatFlags = kAudioFormatFlagsCanonical|kAudioFormatFlagIsNonInterleaved;
|
||||
asbd.mFormatID = kAudioFormatLinearPCM;
|
||||
asbd.mFramesPerPacket = 1;
|
||||
asbd.mSampleRate = sampleRate;
|
||||
return asbd;
|
||||
}
|
||||
|
||||
+(AudioStreamBasicDescription)stereoCanonicalNonInterleavedFormatWithSampleRate:(float)sampleRate {
|
||||
AudioStreamBasicDescription asbd;
|
||||
UInt32 byteSize = sizeof(AudioUnitSampleType);
|
||||
asbd.mBitsPerChannel = 8 * byteSize;
|
||||
asbd.mBytesPerFrame = byteSize;
|
||||
asbd.mBytesPerPacket = byteSize;
|
||||
asbd.mChannelsPerFrame = 2;
|
||||
asbd.mFormatFlags = kAudioFormatFlagsCanonical|kAudioFormatFlagIsNonInterleaved;
|
||||
asbd.mFormatID = kAudioFormatLinearPCM;
|
||||
asbd.mFramesPerPacket = 1;
|
||||
asbd.mSampleRate = sampleRate;
|
||||
return asbd;
|
||||
}
|
||||
|
||||
+(AudioStreamBasicDescription)stereoFloatInterleavedFormatWithSampleRate:(float)sampleRate {
|
||||
AudioStreamBasicDescription asbd;
|
||||
UInt32 byteSize = sizeof(AudioUnitSampleType);
|
||||
asbd.mBitsPerChannel = 8 * byteSize;
|
||||
asbd.mBytesPerFrame = 2 * byteSize;
|
||||
asbd.mBytesPerPacket = 2 * byteSize;
|
||||
asbd.mChannelsPerFrame = 2;
|
||||
asbd.mFormatFlags = kAudioFormatFlagIsPacked|kAudioFormatFlagIsFloat;
|
||||
asbd.mFormatID = kAudioFormatLinearPCM;
|
||||
asbd.mFramesPerPacket = 1;
|
||||
asbd.mSampleRate = sampleRate;
|
||||
return asbd;
|
||||
}
|
||||
|
||||
+(void)printASBD:(AudioStreamBasicDescription)asbd {
|
||||
char formatIDString[5];
|
||||
UInt32 formatID = CFSwapInt32HostToBig(asbd.mFormatID);
|
||||
@@ -94,6 +152,35 @@
|
||||
}
|
||||
|
||||
#pragma mark - Math Utility
|
||||
+(void)appendBufferAndShift:(float*)buffer
|
||||
withBufferSize:(int)bufferLength
|
||||
toScrollHistory:(float*)scrollHistory
|
||||
withScrollHistorySize:(int)scrollHistoryLength {
|
||||
NSAssert(scrollHistoryLength>=bufferLength,@"Scroll history array length must be greater buffer length");
|
||||
NSAssert(scrollHistoryLength>0,@"Scroll history array length must be greater than 0");
|
||||
NSAssert(bufferLength>0,@"Buffer array length must be greater than 0");
|
||||
int shiftLength = scrollHistoryLength - bufferLength;
|
||||
size_t floatByteSize = sizeof(float);
|
||||
size_t shiftByteSize = shiftLength * floatByteSize;
|
||||
size_t bufferByteSize = bufferLength * floatByteSize;
|
||||
memmove(&scrollHistory[0],
|
||||
&scrollHistory[bufferLength],
|
||||
shiftByteSize);
|
||||
memmove(&scrollHistory[shiftLength],
|
||||
&buffer[0],
|
||||
bufferByteSize);
|
||||
}
|
||||
|
||||
+(void) appendValue:(float)value
|
||||
toScrollHistory:(float*)scrollHistory
|
||||
withScrollHistorySize:(int)scrollHistoryLength {
|
||||
float val[1]; val[0] = value;
|
||||
[self appendBufferAndShift:val
|
||||
withBufferSize:1
|
||||
toScrollHistory:scrollHistory
|
||||
withScrollHistorySize:scrollHistoryLength];
|
||||
}
|
||||
|
||||
+(float)MAP:(float)value
|
||||
leftMin:(float)leftMin
|
||||
leftMax:(float)leftMax
|
||||
@@ -113,6 +200,40 @@
|
||||
return sqrtf( sum / bufferSize );
|
||||
}
|
||||
|
||||
#pragma mark - Plot Utility
|
||||
+(void)updateScrollHistory:(float **)scrollHistory
|
||||
withLength:(int)scrollHistoryLength
|
||||
atIndex:(int*)index
|
||||
withBuffer:(float *)buffer
|
||||
withBufferSize:(int)bufferSize
|
||||
isResolutionChanging:(BOOL*)isChanging {
|
||||
|
||||
//
|
||||
size_t floatByteSize = sizeof(float);
|
||||
|
||||
//
|
||||
if( *scrollHistory == NULL ){
|
||||
// Create the history buffer
|
||||
*scrollHistory = (float*)calloc(kEZAudioPlotMaxHistoryBufferLength,floatByteSize);
|
||||
}
|
||||
|
||||
//
|
||||
if( !*isChanging ){
|
||||
float rms = [EZAudio RMS:buffer length:bufferSize];
|
||||
if( *index < scrollHistoryLength ){
|
||||
float *hist = *scrollHistory;
|
||||
hist[*index] = rms;
|
||||
(*index)++;
|
||||
}
|
||||
else {
|
||||
[EZAudio appendValue:rms
|
||||
toScrollHistory:*scrollHistory
|
||||
withScrollHistorySize:scrollHistoryLength];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - TPCircularBuffer Utility
|
||||
+(void)circularBuffer:(TPCircularBuffer *)circularBuffer withSize:(int)size {
|
||||
TPCircularBufferInit(circularBuffer,size);
|
||||
@@ -127,6 +248,7 @@
|
||||
|
||||
+(void)freeCircularBuffer:(TPCircularBuffer *)circularBuffer {
|
||||
TPCircularBufferClear(circularBuffer);
|
||||
TPCircularBufferCleanup(circularBuffer);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -76,6 +76,11 @@ typedef void (^WaveformDataCompletionBlock)(float *waveformData, UInt32 length);
|
||||
*/
|
||||
@property (nonatomic,assign) id<EZAudioFileDelegate> audioFileDelegate;
|
||||
|
||||
/**
|
||||
The resolution of the waveform data. This value specifies how the recommendedDrawingFrameRate chooses itself. A low value like 128 will render a waveform containing 128 points representing a low resolution waveform while a high value like 4096 will render a high quality waveform. Higher resolutions provide more detail, but take more work to render in the audio waveform plots (EZAudioPlot or EZAudioPlotGL) while lower resolutions providel less detail, but work better for displaying many at a time (like in a UITableView)
|
||||
*/
|
||||
@property (nonatomic,assign) UInt32 waveformResolution;
|
||||
|
||||
#pragma mark - Initializers
|
||||
///-----------------------------------------------------------
|
||||
/// @name Initializers
|
||||
@@ -191,11 +196,23 @@ typedef void (^WaveformDataCompletionBlock)(float *waveformData, UInt32 length);
|
||||
*/
|
||||
-(SInt64)totalFrames;
|
||||
|
||||
/**
|
||||
Provides the NSURL for the audio file.
|
||||
@return An NSURL representing the path of the EZAudioFile instance.
|
||||
*/
|
||||
-(NSURL*)url;
|
||||
|
||||
#pragma mark - Helpers
|
||||
///-----------------------------------------------------------
|
||||
/// @name Manipulating The Audio Data
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Tells the caller whether the EZAudioFile has cached waveform data that was loaded via the getWaveformDataWithCompletionBlock: function.
|
||||
* @return A BOOL indicating whether there is cached waveform data
|
||||
*/
|
||||
-(BOOL)hasLoadedAudioData;
|
||||
|
||||
/**
|
||||
Asynchronously pulls the waveform amplitude data into a float array for the receiver.
|
||||
@param waveformDataCompletionBlock A WaveformDataCompletionBlock that executes when the waveform data has been extracted. Provides the waveform data as a float array and the length of the array.
|
||||
|
||||
+59
-24
@@ -27,6 +27,8 @@
|
||||
|
||||
#import "EZAudio.h"
|
||||
|
||||
#define kEZAudioFileWaveformDefaultResolution (1024)
|
||||
|
||||
@interface EZAudioFile (){
|
||||
|
||||
// Reading from the audio file
|
||||
@@ -50,6 +52,7 @@
|
||||
|
||||
@implementation EZAudioFile
|
||||
@synthesize audioFileDelegate = _audioFileDelegate;
|
||||
@synthesize waveformResolution = _waveformResolution;
|
||||
|
||||
#pragma mark - Initializers
|
||||
-(EZAudioFile*)initWithURL:(NSURL*)url {
|
||||
@@ -108,7 +111,6 @@
|
||||
UInt32 size = sizeof(_fileFormat);
|
||||
[EZAudio checkResult:ExtAudioFileGetProperty(_audioFile,kExtAudioFileProperty_FileDataFormat, &size, &_fileFormat)
|
||||
operation:"Failed to get audio stream basic description of input file"];
|
||||
[EZAudio printASBD:_fileFormat];
|
||||
|
||||
// Try pulling the total frame size
|
||||
size = sizeof(_totalFrames);
|
||||
@@ -119,15 +121,17 @@
|
||||
_totalDuration = _totalFrames / _fileFormat.mSampleRate;
|
||||
|
||||
// Set the client format on the stream
|
||||
_clientFormat.mBitsPerChannel = 8 * sizeof(AudioUnitSampleType);
|
||||
_clientFormat.mBytesPerFrame = sizeof(AudioUnitSampleType);
|
||||
_clientFormat.mBytesPerPacket = sizeof(AudioUnitSampleType);
|
||||
_clientFormat.mChannelsPerFrame = 1;
|
||||
_clientFormat.mFormatFlags = kAudioFormatFlagsCanonical | kAudioFormatFlagIsNonInterleaved;
|
||||
_clientFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
_clientFormat.mFramesPerPacket = 1;
|
||||
_clientFormat.mSampleRate = 44100;
|
||||
|
||||
switch (_fileFormat.mChannelsPerFrame) {
|
||||
case 1:
|
||||
_clientFormat = [EZAudio monoFloatFormatWithSampleRate:_fileFormat.mSampleRate];
|
||||
break;
|
||||
case 2:
|
||||
_clientFormat = [EZAudio stereoFloatInterleavedFormatWithSampleRate:_fileFormat.mSampleRate];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[EZAudio checkResult:ExtAudioFileSetProperty(_audioFile,
|
||||
kExtAudioFileProperty_ClientDataFormat,
|
||||
sizeof (AudioStreamBasicDescription),
|
||||
@@ -142,6 +146,12 @@
|
||||
_floatBuffers[i] = (float*)malloc(outputBufferSize);
|
||||
}
|
||||
|
||||
// There's no waveform data yet
|
||||
_waveformData = NULL;
|
||||
|
||||
// Set the default resolution for the waveform data
|
||||
_waveformResolution = kEZAudioFileWaveformDefaultResolution;
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Events
|
||||
@@ -154,8 +164,8 @@
|
||||
UInt32 outputBufferSize = 32 * frames; // 32 KB
|
||||
audioBufferList->mNumberBuffers = 1;
|
||||
audioBufferList->mBuffers[0].mNumberChannels = _clientFormat.mChannelsPerFrame;
|
||||
audioBufferList->mBuffers[0].mDataByteSize = outputBufferSize;
|
||||
audioBufferList->mBuffers[0].mData = (AudioUnitSampleType*)malloc(sizeof(AudioUnitSampleType*)*outputBufferSize);
|
||||
audioBufferList->mBuffers[0].mDataByteSize = _clientFormat.mChannelsPerFrame*outputBufferSize;
|
||||
audioBufferList->mBuffers[0].mData = (AudioUnitSampleType*)malloc(_clientFormat.mChannelsPerFrame*sizeof(AudioUnitSampleType*)*outputBufferSize);
|
||||
[EZAudio checkResult:ExtAudioFileRead(_audioFile,
|
||||
&frames,
|
||||
audioBufferList)
|
||||
@@ -191,21 +201,26 @@
|
||||
}
|
||||
|
||||
#pragma mark - Getters
|
||||
-(BOOL)hasLoadedAudioData {
|
||||
return _waveformData != NULL;
|
||||
}
|
||||
|
||||
-(void)getWaveformDataWithCompletionBlock:(WaveformDataCompletionBlock)waveformDataCompletionBlock {
|
||||
|
||||
SInt64 currentFramePosition = _frameIndex;
|
||||
|
||||
if( _waveformData ){
|
||||
if( _waveformData != NULL ){
|
||||
|
||||
waveformDataCompletionBlock( _waveformData, _waveformTotalBuffers );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
_waveformFrameRate = [self recommendedDrawingFrameRate];
|
||||
_waveformTotalBuffers = [self minBuffersWithFrameRate:_waveformFrameRate];
|
||||
_waveformData = (float*)malloc(sizeof(float)*_waveformTotalBuffers);
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0ul), ^{
|
||||
|
||||
_waveformFrameRate = [self recommendedDrawingFrameRate];
|
||||
_waveformTotalBuffers = [self minBuffersWithFrameRate:_waveformFrameRate];
|
||||
_waveformData = (float*)malloc(sizeof(float)*_waveformTotalBuffers);
|
||||
|
||||
for( int i = 0; i < _waveformTotalBuffers; i++ ){
|
||||
|
||||
@@ -218,8 +233,8 @@
|
||||
UInt32 outputBufferSize = 32 * _waveformFrameRate; // 32 KB
|
||||
bufferList->mNumberBuffers = 1;
|
||||
bufferList->mBuffers[0].mNumberChannels = _clientFormat.mChannelsPerFrame;
|
||||
bufferList->mBuffers[0].mDataByteSize = outputBufferSize;
|
||||
bufferList->mBuffers[0].mData = (AudioUnitSampleType*)malloc(sizeof(AudioUnitSampleType*)*outputBufferSize);
|
||||
bufferList->mBuffers[0].mDataByteSize = _clientFormat.mChannelsPerFrame*outputBufferSize;
|
||||
bufferList->mBuffers[0].mData = (AudioUnitSampleType*)malloc(_clientFormat.mChannelsPerFrame*sizeof(AudioUnitSampleType*)*outputBufferSize);
|
||||
|
||||
// Read in the specified number of frames
|
||||
[EZAudio checkResult:ExtAudioFileRead(_audioFile,
|
||||
@@ -230,11 +245,8 @@
|
||||
eof = _waveformFrameRate == 0;
|
||||
_frameIndex += _waveformFrameRate;
|
||||
|
||||
// Convert to floats
|
||||
AEFloatConverterToFloat(_floatConverter,bufferList,_floatBuffers,_waveformFrameRate);
|
||||
|
||||
// Calculate RMS of each buffer
|
||||
float rms = [EZAudio RMS:_floatBuffers[0]
|
||||
float rms = [EZAudio RMS:bufferList->mBuffers[0].mData
|
||||
length:bufferSize];
|
||||
_waveformData[i] = rms;
|
||||
|
||||
@@ -277,6 +289,21 @@
|
||||
return _totalFrames;
|
||||
}
|
||||
|
||||
-(NSURL *)url {
|
||||
return (__bridge NSURL*)_sourceURL;
|
||||
}
|
||||
|
||||
#pragma mark - Setters
|
||||
-(void)setWaveformResolution:(UInt32)waveformResolution {
|
||||
if( _waveformResolution != waveformResolution ){
|
||||
_waveformResolution = waveformResolution;
|
||||
if( _waveformData ){
|
||||
free(_waveformData);
|
||||
_waveformData = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Helpers
|
||||
-(UInt32)minBuffersWithFrameRate:(UInt32)frameRate {
|
||||
frameRate = frameRate > 0 ? frameRate : 1;
|
||||
@@ -284,14 +311,22 @@
|
||||
}
|
||||
|
||||
-(UInt32)recommendedDrawingFrameRate {
|
||||
return (UInt32) _totalFrames / 2057 - 1;
|
||||
return (UInt32) _totalFrames / _waveformResolution - 1;
|
||||
}
|
||||
|
||||
#pragma mark - Cleanup
|
||||
-(void)dealloc {
|
||||
if( _waveformData ){
|
||||
free(_waveformData);
|
||||
_waveformData = NULL;
|
||||
}
|
||||
// if( _floatBuffers ){
|
||||
// free(_floatBuffers);
|
||||
// _floatBuffers = NULL;
|
||||
// }
|
||||
_frameIndex = 0;
|
||||
_waveformFrameRate = 0;
|
||||
_waveformTotalBuffers = 0;
|
||||
[EZAudio checkResult:ExtAudioFileDispose(_audioFile)
|
||||
operation:"Failed to dispose of extended audio file."];
|
||||
}
|
||||
|
||||
+15
-4
@@ -28,10 +28,9 @@
|
||||
|
||||
@class EZAudio;
|
||||
|
||||
/**
|
||||
The default since of the rolling audio plot. TODO: In future release make this real-time adjustable.
|
||||
*/
|
||||
#define kEZAudioPlotHistoryBufferSize 1024
|
||||
#define kEZAudioPlotMaxHistoryBufferLength (8192)
|
||||
|
||||
#define kEZAudioPlotDefaultHistoryBufferLength (1024)
|
||||
|
||||
/**
|
||||
`EZAudioPlot`, a subclass of `EZPlot`, is a cross-platform (iOS and OSX) class that plots an audio waveform using Core Graphics.
|
||||
@@ -48,4 +47,16 @@
|
||||
*/
|
||||
@interface EZAudioPlot : EZPlot
|
||||
|
||||
#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;
|
||||
|
||||
@end
|
||||
|
||||
+48
-39
@@ -27,11 +27,16 @@
|
||||
|
||||
#import "EZAudio.h"
|
||||
|
||||
#define kCircularBufferSizeTemp 512
|
||||
|
||||
@interface EZAudioPlot () {
|
||||
BOOL _hasData;
|
||||
TPCircularBuffer _historyBuffer;
|
||||
// BOOL _hasData;
|
||||
// TPCircularBuffer _historyBuffer;
|
||||
|
||||
// Rolling History
|
||||
BOOL _setMaxLength;
|
||||
float *_scrollHistory;
|
||||
int _scrollHistoryIndex;
|
||||
UInt32 _scrollHistoryLength;
|
||||
BOOL _changingHistorySize;
|
||||
|
||||
CGPoint *_sampleData;
|
||||
UInt32 _sampleLength;
|
||||
@@ -87,6 +92,8 @@
|
||||
self.plotType = EZPlotTypeRolling;
|
||||
self.shouldMirror = NO;
|
||||
self.shouldFill = NO;
|
||||
_scrollHistory = NULL;
|
||||
_scrollHistoryLength = kEZAudioPlotDefaultHistoryBufferLength;
|
||||
}
|
||||
|
||||
#pragma mark - Setters
|
||||
@@ -139,7 +146,7 @@
|
||||
_sampleLength = length;
|
||||
|
||||
for(int i = 0; i < length; i++) {
|
||||
the_sampleData[i] = i == 0 || i == length - 1 ? 0 : the_sampleData[i];
|
||||
the_sampleData[i] = i == 0 ? 0 : the_sampleData[i];
|
||||
_sampleData[i] = CGPointMake(i,the_sampleData[i] * _gain);
|
||||
}
|
||||
|
||||
@@ -150,39 +157,18 @@
|
||||
-(void)updateBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize {
|
||||
if( _plotType == EZPlotTypeRolling ){
|
||||
|
||||
// Initialize the circular buffer
|
||||
!_hasData ? TPCircularBufferInit(&_historyBuffer,kCircularBufferSizeTemp) : 0;
|
||||
_hasData = YES;
|
||||
|
||||
// Initialize
|
||||
_sampleLength = bufferSize;
|
||||
|
||||
// Copy into the circular buffer
|
||||
float rmsValue = [EZAudio RMS:buffer length:bufferSize];
|
||||
float snapshot[1];
|
||||
snapshot[0] = rmsValue;
|
||||
// self.rmsLabel.text = [NSString stringWithFormat:@"RMS: %.4f",rmsValue];
|
||||
BOOL result = TPCircularBufferProduceBytes(&_historyBuffer,
|
||||
snapshot,
|
||||
sizeof(snapshot));
|
||||
if(result){
|
||||
// Populate the graph
|
||||
int32_t availableBytes;
|
||||
float *cBuf = TPCircularBufferTail(&_historyBuffer,&availableBytes);
|
||||
for(int i = 0; i < kCircularBufferSizeTemp; i++) {
|
||||
if( availableBytes == kCircularBufferSizeTemp*sizeof(float) ){
|
||||
cBuf[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
[self _setSampleData:cBuf
|
||||
length:kCircularBufferSizeTemp];
|
||||
if( availableBytes == kCircularBufferSizeTemp*sizeof(float) ){
|
||||
TPCircularBufferConsume(&_historyBuffer,kCircularBufferSizeTemp*sizeof(float));
|
||||
}
|
||||
}
|
||||
else {
|
||||
NSLog(@"Failed to copy bytes to circular buffer 1");
|
||||
}
|
||||
// Update the scroll history datasource
|
||||
[EZAudio updateScrollHistory:&_scrollHistory
|
||||
withLength:_scrollHistoryLength
|
||||
atIndex:&_scrollHistoryIndex
|
||||
withBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
isResolutionChanging:&_changingHistorySize];
|
||||
|
||||
//
|
||||
[self _setSampleData:_scrollHistory
|
||||
length:(!_setMaxLength?kEZAudioPlotMaxHistoryBufferLength:_scrollHistoryLength)];
|
||||
_setMaxLength = YES;
|
||||
|
||||
}
|
||||
else if( _plotType == EZPlotTypeBuffer ){
|
||||
@@ -228,12 +214,14 @@
|
||||
#endif
|
||||
|
||||
if(_sampleLength > 0) {
|
||||
|
||||
_sampleData[_sampleLength-1] = CGPointMake(_sampleLength-1,0.0f);
|
||||
|
||||
CGMutablePathRef halfPath = CGPathCreateMutable();
|
||||
CGPathAddLines(halfPath,
|
||||
NULL,
|
||||
_sampleData,
|
||||
_sampleLength);
|
||||
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
|
||||
double xscale = (frame.size.width) / (float)_sampleLength;
|
||||
@@ -278,7 +266,28 @@
|
||||
#elif TARGET_OS_MAC
|
||||
[[NSGraphicsContext currentContext] restoreGraphicsState];
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma mark - Adjust Resolution
|
||||
-(int)setRollingHistoryLength:(int)historyLength {
|
||||
historyLength = MIN(historyLength,kEZAudioPlotMaxHistoryBufferLength);
|
||||
size_t floatByteSize = sizeof(float);
|
||||
_changingHistorySize = YES;
|
||||
if( _scrollHistoryLength != historyLength ){
|
||||
_scrollHistoryLength = historyLength;
|
||||
}
|
||||
_scrollHistory = realloc(_scrollHistory,_scrollHistoryLength*floatByteSize);
|
||||
if( _scrollHistoryIndex < _scrollHistoryLength ){
|
||||
memset(&_scrollHistory[_scrollHistoryIndex],
|
||||
0,
|
||||
(_scrollHistoryLength-_scrollHistoryIndex)*floatByteSize);
|
||||
}
|
||||
else {
|
||||
_scrollHistoryIndex = _scrollHistoryLength;
|
||||
}
|
||||
_changingHistorySize = NO;
|
||||
return historyLength;
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
free(_sampleData);
|
||||
|
||||
@@ -124,6 +124,18 @@ typedef struct {
|
||||
|
||||
#endif
|
||||
|
||||
#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;
|
||||
|
||||
#pragma mark - Shared Methods
|
||||
///-----------------------------------------------------------
|
||||
/// @name Shared OpenGL Methods
|
||||
|
||||
+83
-36
@@ -54,9 +54,17 @@
|
||||
UInt32 _bufferPlotGraphSize;
|
||||
UInt32 _rollingPlotGraphSize;
|
||||
|
||||
// History buffer
|
||||
UInt32 _historyIndex;
|
||||
float _historyBuffer[kEZAudioPlotHistoryBufferSize];
|
||||
// Rolling History
|
||||
BOOL _setMaxLength;
|
||||
float *_scrollHistory;
|
||||
int _scrollHistoryIndex;
|
||||
UInt32 _scrollHistoryLength;
|
||||
BOOL _changingHistorySize;
|
||||
|
||||
// Copied buffer data
|
||||
float *_copiedBuffer;
|
||||
UInt32 _copiedBufferSize;
|
||||
|
||||
}
|
||||
@property (nonatomic,assign,readonly) EZAudioPlotGLDrawType drawingType;
|
||||
@property (nonatomic,strong) GLKBaseEffect *baseEffect;
|
||||
@@ -105,15 +113,14 @@
|
||||
|
||||
#pragma mark - Initialize Properties Here
|
||||
-(void)initializeView {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// Initialize the subview controller
|
||||
_glViewController = [[EZAudioPlotGLKViewController alloc] init];
|
||||
_glViewController.view.frame = self.frame;
|
||||
_glViewController.view.frame = self.bounds;
|
||||
[self insertSubview:self.glViewController.view atIndex:0];
|
||||
#elif TARGET_OS_MAC
|
||||
_copiedBuffer = NULL;
|
||||
#endif
|
||||
|
||||
// Set the default properties
|
||||
self.gain = 1.0;
|
||||
self.plotType = EZPlotTypeBuffer;
|
||||
@@ -121,10 +128,11 @@
|
||||
self.backgroundColor = [UIColor colorWithRed:0.796 green:0.749 blue:0.663 alpha:1];
|
||||
self.color = [UIColor colorWithRed:0.481 green:0.548 blue:0.637 alpha:1];
|
||||
#elif TARGET_OS_MAC
|
||||
_scrollHistory = NULL;
|
||||
_scrollHistoryLength = kEZAudioPlotDefaultHistoryBufferLength;
|
||||
#endif
|
||||
self.shouldFill = NO;
|
||||
self.shouldMirror = NO;
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Setters
|
||||
@@ -199,15 +207,23 @@
|
||||
[self.glViewController updateBuffer:buffer
|
||||
withBufferSize:bufferSize];
|
||||
#elif TARGET_OS_MAC
|
||||
if( _copiedBuffer == NULL ){
|
||||
_copiedBuffer = (float*)malloc(bufferSize*sizeof(float));
|
||||
}
|
||||
_copiedBufferSize = bufferSize;
|
||||
// Copy the buffer
|
||||
memcpy(_copiedBuffer,
|
||||
buffer,
|
||||
bufferSize*sizeof(float));
|
||||
// Draw based on plot type
|
||||
switch(_plotType) {
|
||||
case EZPlotTypeBuffer:
|
||||
[self _updateBufferPlotBufferWithAudioReceived:buffer
|
||||
withBufferSize:bufferSize];
|
||||
[self _updateBufferPlotBufferWithAudioReceived:_copiedBuffer
|
||||
withBufferSize:_copiedBufferSize];
|
||||
break;
|
||||
case EZPlotTypeRolling:
|
||||
[self _updateRollingPlotBufferWithAudioReceived:buffer
|
||||
withBufferSize:bufferSize];
|
||||
[self _updateRollingPlotBufferWithAudioReceived:_copiedBuffer
|
||||
withBufferSize:_copiedBufferSize];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -430,34 +446,34 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink,
|
||||
// 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 && _drawingType == EZAudioPlotGLDrawTypeLineStrip ){
|
||||
EZAudioPlotGLPoint maxGraph[2*kEZAudioPlotHistoryBufferSize];
|
||||
EZAudioPlotGLPoint maxGraph[2*kEZAudioPlotMaxHistoryBufferLength];
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(maxGraph), maxGraph, GL_STREAM_DRAW );
|
||||
_hasRollingPlotData = YES;
|
||||
}
|
||||
|
||||
// Setup the plot
|
||||
_rollingPlotGraphSize = [EZAudioPlotGL graphSizeForDrawingType:_drawingType
|
||||
withBufferSize:kEZAudioPlotHistoryBufferSize];
|
||||
withBufferSize:_scrollHistoryLength];
|
||||
|
||||
// Fill the graph with data
|
||||
EZAudioPlotGLPoint graph[_rollingPlotGraphSize];
|
||||
|
||||
|
||||
// Update the history buffer
|
||||
_historyBuffer[_historyIndex] = [EZAudio RMS:buffer length:bufferSize];
|
||||
if( _historyIndex == kEZAudioPlotHistoryBufferSize - 1 ){
|
||||
_historyIndex = 0;
|
||||
for(int i = 0; i < kEZAudioPlotHistoryBufferSize; i++) _historyBuffer[i] = 0.0f;
|
||||
}
|
||||
else {
|
||||
_historyIndex++;
|
||||
}
|
||||
|
||||
// Update the scroll history datasource
|
||||
[EZAudio updateScrollHistory:&_scrollHistory
|
||||
withLength:_scrollHistoryLength
|
||||
atIndex:&_scrollHistoryIndex
|
||||
withBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
isResolutionChanging:&_changingHistorySize];
|
||||
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_rollingPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:_historyBuffer
|
||||
withBufferSize:kEZAudioPlotHistoryBufferSize
|
||||
withBuffer:_scrollHistory
|
||||
withBufferSize:_scrollHistoryLength
|
||||
withGain:self.gain];
|
||||
|
||||
// Update the drawing
|
||||
@@ -486,16 +502,18 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink,
|
||||
// Draw frame
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Plot either a buffer plot or a rolling plot
|
||||
switch(_plotType) {
|
||||
case EZPlotTypeBuffer:
|
||||
[self _drawBufferPlot];
|
||||
break;
|
||||
case EZPlotTypeRolling:
|
||||
[self _drawRollingPlot];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if( _hasBufferPlotData || _hasRollingPlotData ){
|
||||
// Plot either a buffer plot or a rolling plot
|
||||
switch(_plotType) {
|
||||
case EZPlotTypeBuffer:
|
||||
[self _drawBufferPlot];
|
||||
break;
|
||||
case EZPlotTypeRolling:
|
||||
[self _drawRollingPlot];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush and unlock
|
||||
@@ -623,9 +641,39 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink,
|
||||
// when it encounters something that has been release
|
||||
CVDisplayLinkStop(_displayLink);
|
||||
CVDisplayLinkRelease(_displayLink);
|
||||
|
||||
if( _copiedBuffer != NULL ){
|
||||
free( _copiedBuffer );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark - Adjust Resolution
|
||||
-(int)setRollingHistoryLength:(int)historyLength {
|
||||
#if TARGET_OS_IPHONE
|
||||
return [self.glViewController setRollingHistoryLength:historyLength];
|
||||
#elif TARGET_OS_MAC
|
||||
historyLength = MIN(historyLength,kEZAudioPlotMaxHistoryBufferLength);
|
||||
size_t floatByteSize = sizeof(float);
|
||||
_changingHistorySize = YES;
|
||||
if( _scrollHistoryLength != historyLength ){
|
||||
_scrollHistoryLength = historyLength;
|
||||
}
|
||||
_scrollHistory = realloc(_scrollHistory,_scrollHistoryLength*floatByteSize);
|
||||
if( _scrollHistoryIndex < _scrollHistoryLength ){
|
||||
memset(&_scrollHistory[_scrollHistoryIndex],
|
||||
0,
|
||||
(_scrollHistoryLength-_scrollHistoryIndex)*floatByteSize);
|
||||
}
|
||||
else {
|
||||
_scrollHistoryIndex = _scrollHistoryLength;
|
||||
}
|
||||
_changingHistorySize = NO;
|
||||
return historyLength;
|
||||
#endif
|
||||
return kEZAudioPlotDefaultHistoryBufferLength;
|
||||
}
|
||||
|
||||
#pragma mark - Graph Methods
|
||||
+(void)fillGraph:(EZAudioPlotGLPoint*)graph
|
||||
withGraphSize:(UInt32)graphSize
|
||||
@@ -648,8 +696,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink,
|
||||
else if( drawingType == EZAudioPlotGLDrawTypeTriangleStrip ) {
|
||||
// graph size = 2 * buffer size to draw triangles and fill regions properly
|
||||
for(int i = 0; i < graphSize; i+=2){
|
||||
int bufferIndex = (int)[EZAudio
|
||||
MAP:i
|
||||
int bufferIndex = (int)[EZAudio MAP:i
|
||||
leftMin:0
|
||||
leftMax:graphSize
|
||||
rightMin:0
|
||||
|
||||
@@ -80,6 +80,18 @@
|
||||
*/
|
||||
@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;
|
||||
|
||||
#pragma mark - Get Samples
|
||||
///-----------------------------------------------------------
|
||||
/// @name Updating The Plot
|
||||
|
||||
@@ -42,9 +42,12 @@
|
||||
UInt32 _bufferPlotGraphSize;
|
||||
UInt32 _rollingPlotGraphSize;
|
||||
|
||||
// History buffer
|
||||
UInt32 _historyIndex;
|
||||
float _historyBuffer[kEZAudioPlotHistoryBufferSize];
|
||||
// Rolling History
|
||||
BOOL _setMaxLength;
|
||||
float *_scrollHistory;
|
||||
int _scrollHistoryIndex;
|
||||
UInt32 _scrollHistoryLength;
|
||||
BOOL _changingHistorySize;
|
||||
|
||||
}
|
||||
@end
|
||||
@@ -88,6 +91,8 @@
|
||||
self.baseEffect = [[GLKBaseEffect alloc] init];
|
||||
self.baseEffect.useConstantColor = GL_TRUE;
|
||||
self.preferredFramesPerSecond = 60;
|
||||
_scrollHistory = NULL;
|
||||
_scrollHistoryLength = kEZAudioPlotDefaultHistoryBufferLength;
|
||||
}
|
||||
|
||||
#pragma mark - View Did Load
|
||||
@@ -121,6 +126,27 @@
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Adjust Resolution
|
||||
-(int)setRollingHistoryLength:(int)historyLength {
|
||||
historyLength = MIN(historyLength,kEZAudioPlotMaxHistoryBufferLength);
|
||||
size_t floatByteSize = sizeof(float);
|
||||
_changingHistorySize = YES;
|
||||
if( _scrollHistoryLength != historyLength ){
|
||||
_scrollHistoryLength = historyLength;
|
||||
}
|
||||
_scrollHistory = realloc(_scrollHistory,_scrollHistoryLength*floatByteSize);
|
||||
if( _scrollHistoryIndex < _scrollHistoryLength ){
|
||||
memset(&_scrollHistory[_scrollHistoryIndex],
|
||||
0,
|
||||
(_scrollHistoryLength-_scrollHistoryIndex)*floatByteSize);
|
||||
}
|
||||
else {
|
||||
_scrollHistoryIndex = _scrollHistoryLength;
|
||||
}
|
||||
_changingHistorySize = NO;
|
||||
return historyLength;
|
||||
}
|
||||
|
||||
#pragma mark - Get Samples
|
||||
-(void)updateBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize {
|
||||
@@ -191,35 +217,35 @@
|
||||
// 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 && _drawingType == EZAudioPlotGLDrawTypeLineStrip ){
|
||||
EZAudioPlotGLPoint maxGraph[2*kEZAudioPlotHistoryBufferSize];
|
||||
EZAudioPlotGLPoint maxGraph[2*kEZAudioPlotMaxHistoryBufferLength];
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(maxGraph), maxGraph, GL_STREAM_DRAW );
|
||||
_hasRollingPlotData = YES;
|
||||
}
|
||||
|
||||
// Setup the plot
|
||||
_rollingPlotGraphSize = [EZAudioPlotGL graphSizeForDrawingType:_drawingType
|
||||
withBufferSize:kEZAudioPlotHistoryBufferSize];
|
||||
withBufferSize:_scrollHistoryLength];
|
||||
|
||||
// Fill the graph with data
|
||||
EZAudioPlotGLPoint graph[_rollingPlotGraphSize];
|
||||
|
||||
// Update the history buffer
|
||||
_historyBuffer[_historyIndex] = [EZAudio RMS:buffer length:bufferSize];
|
||||
if( _historyIndex == kEZAudioPlotHistoryBufferSize - 1 ){
|
||||
_historyIndex = 0;
|
||||
for(int i = 0; i < kEZAudioPlotHistoryBufferSize; i++) _historyBuffer[i] = 0.0f;
|
||||
}
|
||||
else {
|
||||
_historyIndex++;
|
||||
}
|
||||
|
||||
|
||||
// Update the scroll history datasource
|
||||
[EZAudio updateScrollHistory:&_scrollHistory
|
||||
withLength:_scrollHistoryLength
|
||||
atIndex:&_scrollHistoryIndex
|
||||
withBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
isResolutionChanging:&_changingHistorySize];
|
||||
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_rollingPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:_historyBuffer
|
||||
withBufferSize:kEZAudioPlotHistoryBufferSize
|
||||
withGain:self.gain];
|
||||
withGraphSize:_rollingPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:_scrollHistory
|
||||
withBufferSize:_scrollHistoryLength
|
||||
withGain:self.gain];
|
||||
|
||||
// Update the drawing
|
||||
if( !_hasRollingPlotData ){
|
||||
@@ -234,13 +260,13 @@
|
||||
|
||||
#pragma mark - Drawing
|
||||
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
|
||||
// Clear the context
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if( _hasBufferPlotData || _hasRollingPlotData ){
|
||||
// Prepare the effect for drawing
|
||||
[self.baseEffect prepareToDraw];
|
||||
|
||||
// Clear the context
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Plot either a buffer plot or a rolling plot
|
||||
switch(_plotType) {
|
||||
case EZPlotTypeBuffer:
|
||||
|
||||
+49
-8
@@ -119,17 +119,35 @@
|
||||
*/
|
||||
-(EZMicrophone*)initWithMicrophoneDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate;
|
||||
|
||||
/**
|
||||
Creates an instance of the EZMicrophone with a custom AudioStreamBasicDescription and provides the caller to specify a delegate to respond to the audioReceived callback. This will not start fetching the audio until startFetchingAudio has been called. Use initWithMicrophoneDelegate:startsImmediately: to instantiate this class and immediately start fetching audio data.
|
||||
@param microphoneDelegate A EZMicrophoneDelegate delegate that will receive the audioReceived callback.
|
||||
@param audioStreamBasicDescription A custom AudioStreamBasicFormat for the microphone input.
|
||||
@return An instance of the EZMicrophone class. This should be strongly retained.
|
||||
*/
|
||||
-(EZMicrophone*)initWithMicrophoneDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription;
|
||||
|
||||
/**
|
||||
Creates an instance of the EZMicrophone with a delegate to respond to the audioReceived callback and allows the caller to specify whether they'd immediately like to start fetching the audio data.
|
||||
|
||||
@param microphoneDelegate A EZMicrophoneDelegate delegate that will receive the audioReceived callback.
|
||||
@param startsImmediately A boolean indicating whether to start fetching the data immediately. IF YES, the delegate's audioReceived callback will immediately start getting called.
|
||||
|
||||
@return An instance of the EZMicrophone class. This should be strongly retained.
|
||||
*/
|
||||
-(EZMicrophone*)initWithMicrophoneDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
startsImmediately:(BOOL)startsImmediately;
|
||||
|
||||
/**
|
||||
Creates an instance of the EZMicrophone with a custom AudioStreamBasicDescription and provides the caller with a delegate to respond to the audioReceived callback and allows the caller to specify whether they'd immediately like to start fetching the audio data.
|
||||
@param microphoneDelegate A EZMicrophoneDelegate delegate that will receive the audioReceived callback.
|
||||
@param audioStreamBasicDescription A custom AudioStreamBasicFormat for the microphone input.
|
||||
@param startsImmediately A boolean indicating whether to start fetching the data immediately. IF YES, the delegate's audioReceived callback will immediately start getting called.
|
||||
@return An instance of the EZMicrophone class. This should be strongly retained.
|
||||
*/
|
||||
-(EZMicrophone*)initWithMicrophoneDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription
|
||||
startsImmediately:(BOOL)startsImmediately;
|
||||
|
||||
#pragma mark - Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
@@ -137,20 +155,19 @@
|
||||
|
||||
/**
|
||||
Creates an instance of the EZMicrophone with a delegate to respond to the audioReceived callback. This will not start fetching the audio until startFetchingAudio has been called. Use microphoneWithDelegate:startsImmediately: to instantiate this class and immediately start fetching audio data.
|
||||
|
||||
@param microphoneDelegate A EZMicrophoneDelegate delegate that will receive the audioReceived callback.
|
||||
|
||||
@return An instance of the EZMicrophone class. This should be declared as a strong property!
|
||||
*/
|
||||
+(EZMicrophone*)microphoneWithDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate;
|
||||
|
||||
/**
|
||||
Creates an instance of the EZMicrophone with a delegate to respond to the audioReceived callback and allows the caller to specify whether they'd immediately like to start fetching the audio data.
|
||||
|
||||
Creates an instance of the EZMicrophone with a delegate to respond to the audioReceived callback. This will not start fetching the audio until startFetchingAudio has been called. Use microphoneWithDelegate:startsImmediately: to instantiate this class and immediately start fetching audio data.
|
||||
@param microphoneDelegate A EZMicrophoneDelegate delegate that will receive the audioReceived callback.
|
||||
@param startsImmediately A boolean indicating whether to start fetching the data immediately. IF YES, the delegate's audioReceived callback will immediately start getting called.
|
||||
@return An instance of the EZMicrophone class. This should be strongly retained.
|
||||
@param audioStreamBasicDescription A custom AudioStreamBasicFormat for the microphone input.
|
||||
@return An instance of the EZMicrophone class. This should be declared as a strong property!
|
||||
*/
|
||||
+(EZMicrophone*)microphoneWithDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription;
|
||||
|
||||
/**
|
||||
Creates an instance of the EZMicrophone with a delegate to respond to the audioReceived callback and allows the caller to specify whether they'd immediately like to start fetching the audio data.
|
||||
@@ -162,6 +179,18 @@
|
||||
+(EZMicrophone*)microphoneWithDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
startsImmediately:(BOOL)startsImmediately;
|
||||
|
||||
/**
|
||||
Creates an instance of the EZMicrophone with a delegate to respond to the audioReceived callback and allows the caller to specify whether they'd immediately like to start fetching the audio data.
|
||||
|
||||
@param microphoneDelegate A EZMicrophoneDelegate delegate that will receive the audioReceived callback.
|
||||
@param audioStreamBasicDescription A custom AudioStreamBasicFormat for the microphone input.
|
||||
@param startsImmediately A boolean indicating whether to start fetching the data immediately. IF YES, the delegate's audioReceived callback will immediately start getting called.
|
||||
@return An instance of the EZMicrophone class. This should be strongly retained.
|
||||
*/
|
||||
+(EZMicrophone*)microphoneWithDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription
|
||||
startsImmediately:(BOOL)startsImmediately;
|
||||
|
||||
#pragma mark - Singleton
|
||||
///-----------------------------------------------------------
|
||||
/// @name Shared Instance
|
||||
@@ -199,4 +228,16 @@
|
||||
*/
|
||||
-(AudioStreamBasicDescription)audioStreamBasicDescription;
|
||||
|
||||
#pragma mark - Setters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Microphone Input Format
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the AudioStreamBasicDescription on the microphone input.
|
||||
@warning Do not set this while fetching audio (startFetchingAudio)
|
||||
@param asbd The new AudioStreamBasicDescription to use in place of the current audio format description.
|
||||
*/
|
||||
-(void)setAudioStreamBasicDescription:(AudioStreamBasicDescription)asbd;
|
||||
|
||||
@end
|
||||
|
||||
+334
-289
@@ -32,27 +32,45 @@
|
||||
|
||||
#import "EZAudio.h"
|
||||
|
||||
/// Buses
|
||||
static const AudioUnitScope kEZAudioMicrophoneInputBus = 1;
|
||||
static const AudioUnitScope kEZAudioMicrophoneOutputBus = 0;
|
||||
|
||||
/// Flags
|
||||
#if TARGET_OS_IPHONE
|
||||
static const UInt32 kEZAudioMicrophoneDisableFlag = 1;
|
||||
#elif TARGET_OS_MAC
|
||||
static const UInt32 kEZAudioMicrophoneDisableFlag = 0;
|
||||
#endif
|
||||
static const UInt32 kEZAudioMicrophoneEnableFlag = 1;
|
||||
|
||||
@interface EZMicrophone (){
|
||||
/// Internal
|
||||
BOOL _customASBD;
|
||||
BOOL _isConfigured;
|
||||
BOOL _isFetching;
|
||||
|
||||
/// Stream Description
|
||||
AEFloatConverter *converter;
|
||||
AEFloatConverter *converter;
|
||||
AudioStreamBasicDescription streamFormat;
|
||||
|
||||
/// Audio Graph and Input/Output Units
|
||||
AUGraph graph;
|
||||
AudioUnit microphoneInput;
|
||||
AudioUnit outputUnit;
|
||||
|
||||
/// Audio Buffers
|
||||
float **floatBuffers;
|
||||
AudioBufferList *microphoneInputBuffer;
|
||||
|
||||
/// Sample Time Offsets
|
||||
Float64 firstInputSampleTime;
|
||||
Float64 inToOutSampleTimeOffset;
|
||||
/// Device Parameters
|
||||
Float64 _deviceSampleRate;
|
||||
Float32 _deviceBufferDuration;
|
||||
UInt32 _deviceBufferFrameSize;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#elif TARGET_OS_MAC
|
||||
Float64 inputScopeSampleRate;
|
||||
#endif
|
||||
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -67,26 +85,15 @@ static OSStatus inputCallback(void *inRefCon,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData ) {
|
||||
|
||||
EZMicrophone *microphone = (__bridge EZMicrophone*)inRefCon;
|
||||
OSStatus result = noErr;
|
||||
#if TARGET_OS_IPHONE
|
||||
// Render audio into buffer
|
||||
result = AudioUnitRender(microphone->microphoneInput,
|
||||
ioActionFlags,
|
||||
inTimeStamp,
|
||||
1,
|
||||
inNumberFrames,
|
||||
microphone->microphoneInputBuffer);
|
||||
#elif TARGET_OS_MAC
|
||||
// Retrive the captured samples from the input
|
||||
result = AudioUnitRender(microphone->microphoneInput,
|
||||
ioActionFlags,
|
||||
inTimeStamp,
|
||||
inBusNumber,
|
||||
inNumberFrames,
|
||||
microphone->microphoneInputBuffer);
|
||||
#endif
|
||||
if( !result ){
|
||||
// Notify delegate (OF-style)
|
||||
@autoreleasepool {
|
||||
@@ -139,13 +146,31 @@ static OSStatus inputCallback(void *inRefCon,
|
||||
return self;
|
||||
}
|
||||
|
||||
-(EZMicrophone *)initWithMicrophoneDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription {
|
||||
self = [self initWithMicrophoneDelegate:microphoneDelegate];
|
||||
if(self){
|
||||
_customASBD = YES;
|
||||
streamFormat = audioStreamBasicDescription;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(EZMicrophone *)initWithMicrophoneDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
startsImmediately:(BOOL)startsImmediately {
|
||||
self = [self initWithMicrophoneDelegate:microphoneDelegate];
|
||||
if(self){
|
||||
if(startsImmediately){
|
||||
[self startFetchingAudio];
|
||||
}
|
||||
startsImmediately ? [self startFetchingAudio] : -1;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(EZMicrophone *)initWithMicrophoneDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription
|
||||
startsImmediately:(BOOL)startsImmediately {
|
||||
self = [self initWithMicrophoneDelegate:microphoneDelegate withAudioStreamBasicDescription:audioStreamBasicDescription];
|
||||
if(self){
|
||||
startsImmediately ? [self startFetchingAudio] : -1;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -155,12 +180,26 @@ static OSStatus inputCallback(void *inRefCon,
|
||||
return [[EZMicrophone alloc] initWithMicrophoneDelegate:microphoneDelegate];
|
||||
}
|
||||
|
||||
+(EZMicrophone *)microphoneWithDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription {
|
||||
return [[EZMicrophone alloc] initWithMicrophoneDelegate:microphoneDelegate
|
||||
withAudioStreamBasicDescription:audioStreamBasicDescription];
|
||||
}
|
||||
|
||||
+(EZMicrophone *)microphoneWithDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
startsImmediately:(BOOL)startsImmediately {
|
||||
return [[EZMicrophone alloc] initWithMicrophoneDelegate:microphoneDelegate
|
||||
startsImmediately:startsImmediately];
|
||||
}
|
||||
|
||||
+(EZMicrophone *)microphoneWithDelegate:(id<EZMicrophoneDelegate>)microphoneDelegate
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription
|
||||
startsImmediately:(BOOL)startsImmediately {
|
||||
return [[EZMicrophone alloc] initWithMicrophoneDelegate:microphoneDelegate
|
||||
withAudioStreamBasicDescription:audioStreamBasicDescription
|
||||
startsImmediately:startsImmediately];
|
||||
}
|
||||
|
||||
#pragma mark - Singleton
|
||||
+(EZMicrophone*)sharedMicrophone {
|
||||
static EZMicrophone *_sharedMicrophone = nil;
|
||||
@@ -216,218 +255,142 @@ static OSStatus inputCallback(void *inRefCon,
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
-(void)setAudioStreamBasicDescription:(AudioStreamBasicDescription)asbd {
|
||||
if( self.microphoneOn ){
|
||||
NSAssert(self.microphoneOn,@"Cannot set the AudioStreamBasicDescription while microphone is fetching audio");
|
||||
}
|
||||
else {
|
||||
_customASBD = YES;
|
||||
streamFormat = asbd;
|
||||
[self _configureStreamFormatWithSampleRate:_deviceSampleRate];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Configure The Input Unit
|
||||
|
||||
-(void)_createInputUnit {
|
||||
|
||||
// Create localized copy of self
|
||||
EZMicrophone *microphone = (EZMicrophone*)self;
|
||||
// Get component description for input
|
||||
AudioComponentDescription inputComponentDescription = [self _getInputAudioComponentDescription];
|
||||
|
||||
AudioComponentDescription inputComponentDescription = {
|
||||
.componentType = kAudioUnitType_Output,
|
||||
.componentSubType = kAudioUnitSubType_RemoteIO,
|
||||
.componentManufacturer = kAudioUnitManufacturer_Apple,
|
||||
.componentFlags = 0,
|
||||
.componentFlagsMask = 0
|
||||
};
|
||||
|
||||
// Try and find the component
|
||||
AudioComponent inputComponent = AudioComponentFindNext( NULL , &inputComponentDescription );
|
||||
if( inputComponent == NULL ){
|
||||
NSLog(@"Couldn't get input component unit!");
|
||||
return;
|
||||
}
|
||||
// Get the input component
|
||||
AudioComponent inputComponent = [self _getInputComponentWithAudioComponentDescription:inputComponentDescription];
|
||||
|
||||
// Create a new instance of the component and store it for internal use
|
||||
[EZAudio checkResult:AudioComponentInstanceNew(inputComponent,
|
||||
µphone->microphoneInput)
|
||||
operation:"Couldn't open component for microphone input unit."];
|
||||
[self _createNewInstanceForInputComponent:inputComponent];
|
||||
|
||||
// Enable I/O on microphone input unit
|
||||
UInt32 disableFlag = 1; UInt32 enableFlag = 1;
|
||||
AudioUnitScope outputBus = 0; AudioUnitScope inputBus = 1;
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphone->microphoneInput,
|
||||
kAudioOutputUnitProperty_EnableIO,
|
||||
kAudioUnitScope_Input,
|
||||
inputBus,
|
||||
&enableFlag,
|
||||
sizeof(enableFlag))
|
||||
operation:"Couldn't enable input on the remote i/o unit"];
|
||||
// Enable Input Scope
|
||||
[self _enableInputScope];
|
||||
|
||||
// Could set the output if we wanted to play out the mic's buffer
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphone->microphoneInput,
|
||||
kAudioOutputUnitProperty_EnableIO,
|
||||
kAudioUnitScope_Output,
|
||||
outputBus,
|
||||
&disableFlag,
|
||||
sizeof(disableFlag))
|
||||
operation:"Couldn't enable input on the remote i/o unit"];
|
||||
// Disable Output Scope
|
||||
[self _disableOutputScope];
|
||||
|
||||
// Get the hardware sample rate
|
||||
Float64 hardwareSampleRate = 44100;
|
||||
#if !(TARGET_IPHONE_SIMULATOR)
|
||||
UInt32 propSize = sizeof(hardwareSampleRate);
|
||||
[EZAudio checkResult:AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate,
|
||||
&propSize,
|
||||
&hardwareSampleRate)
|
||||
operation:"Could not get hardware sample rate"];
|
||||
#endif
|
||||
// Get the default device if we need to (OSX only, iOS uses RemoteIO)
|
||||
#if TARGET_OS_IPHONE
|
||||
// Do nothing (using RemoteIO)
|
||||
#elif TARGET_OS_MAC
|
||||
[self _configureDefaultDevice];
|
||||
#endif
|
||||
|
||||
// Set the stream format
|
||||
microphone->streamFormat.mBitsPerChannel = 8 * sizeof(AudioUnitSampleType);
|
||||
microphone->streamFormat.mBytesPerFrame = sizeof(AudioUnitSampleType);
|
||||
microphone->streamFormat.mBytesPerPacket = sizeof(AudioUnitSampleType);
|
||||
microphone->streamFormat.mChannelsPerFrame = 2;
|
||||
microphone->streamFormat.mFormatFlags = kAudioFormatFlagsCanonical | kAudioFormatFlagIsNonInterleaved;
|
||||
microphone->streamFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
microphone->streamFormat.mFramesPerPacket = 1;
|
||||
microphone->streamFormat.mSampleRate = hardwareSampleRate;
|
||||
// Configure device and pull hardware specific sampling rate (default = 44.1 kHz)
|
||||
_deviceSampleRate = [self _configureDeviceSampleRateWithDefault:44100.0];
|
||||
|
||||
// Get the buffer duration (approximate for simulator, real device will have it's preferred value set)
|
||||
Float32 bufferDuration = 0.0232;
|
||||
UInt32 propertySize = sizeof(bufferDuration);
|
||||
#if !(TARGET_IPHONE_SIMULATOR)
|
||||
[EZAudio checkResult:AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration,
|
||||
sizeof(propertySize),
|
||||
&bufferDuration)
|
||||
operation:"Couldn't set the preferred buffer duration"];
|
||||
// Get the preferred buffer size
|
||||
[EZAudio checkResult:AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration,
|
||||
&propertySize,
|
||||
&bufferDuration)
|
||||
operation:"Could not get preferred buffer size"];
|
||||
#endif
|
||||
// Configure device and pull hardware specific buffer duration (default = 0.0232)
|
||||
_deviceBufferDuration = [self _configureDeviceBufferDurationWithDefault:0.0232];
|
||||
|
||||
// Configure the stream format with the hardware sample rate
|
||||
[self _configureStreamFormatWithSampleRate:_deviceSampleRate];
|
||||
|
||||
// Notify delegate the audio stream basic description was successfully created
|
||||
[self _notifyDelegateOfStreamFormat];
|
||||
|
||||
// Get buffer frame size
|
||||
_deviceBufferFrameSize = [self _getBufferFrameSize];
|
||||
|
||||
// Create the audio buffer list and pre-malloc the buffers in the list
|
||||
propertySize = offsetof( AudioBufferList, mBuffers[0] ) + ( sizeof( AudioBuffer ) * microphone->streamFormat.mChannelsPerFrame );
|
||||
microphone->microphoneInputBuffer = (AudioBufferList*)malloc(propertySize);
|
||||
[self _configureAudioBufferListWithFrameSize:_deviceBufferFrameSize];
|
||||
|
||||
// Get the maximum number of frames
|
||||
UInt32 bufferSizeFrames;
|
||||
|
||||
propertySize = sizeof(UInt32);
|
||||
[EZAudio checkResult:AudioUnitGetProperty(microphone->microphoneInput,
|
||||
kAudioUnitProperty_MaximumFramesPerSlice,
|
||||
kAudioUnitScope_Global,
|
||||
outputBus,
|
||||
&bufferSizeFrames,
|
||||
&propertySize)
|
||||
operation:"Failed to get maximum number of frames"];
|
||||
|
||||
microphone->microphoneInputBuffer->mNumberBuffers = microphone->streamFormat.mChannelsPerFrame;
|
||||
UInt32 bufferSizeBytes = bufferSizeFrames * microphone->streamFormat.mBytesPerFrame;
|
||||
for( UInt32 i = 0; i < microphone->microphoneInputBuffer->mNumberBuffers; i++ ){
|
||||
microphone->microphoneInputBuffer->mBuffers[i].mNumberChannels = 1;
|
||||
microphone->microphoneInputBuffer->mBuffers[i].mDataByteSize = bufferSizeBytes;
|
||||
microphone->microphoneInputBuffer->mBuffers[i].mData = malloc(bufferSizeBytes);
|
||||
}
|
||||
|
||||
// Setup the converter, but do a lazy set for the float buffer
|
||||
microphone->converter = [[AEFloatConverter alloc] initWithSourceFormat:microphone->streamFormat];
|
||||
microphone->floatBuffers = (float**)malloc(sizeof(float*)*microphone->streamFormat.mChannelsPerFrame);
|
||||
for ( int i=0; i<microphone->streamFormat.mChannelsPerFrame; i++ ) {
|
||||
microphone->floatBuffers[i] = (float*)malloc(bufferSizeBytes);
|
||||
assert(microphone->floatBuffers[i]);
|
||||
}
|
||||
|
||||
// Set the stream format for output on the microphone's input scope
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphone->microphoneInput,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
outputBus,
|
||||
µphone->streamFormat,
|
||||
sizeof(microphone->streamFormat))
|
||||
operation:"Could not set microphone's stream format bus 0"];
|
||||
|
||||
// Set the stream format for the input on the microphone's output scope
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphone->microphoneInput,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Output,
|
||||
inputBus,
|
||||
µphone->streamFormat,
|
||||
sizeof(microphone->streamFormat))
|
||||
operation:"Could not set microphone's stream format bus 1"];
|
||||
|
||||
// Notify delegate the audio stream basic description was successfully created
|
||||
if( microphone.microphoneDelegate ){
|
||||
if( [microphone.microphoneDelegate respondsToSelector:@selector(microphone:hasAudioStreamBasicDescription:) ] ){
|
||||
[microphone.microphoneDelegate microphone:microphone
|
||||
hasAudioStreamBasicDescription:microphone->streamFormat];
|
||||
}
|
||||
}
|
||||
// Set the float converter's stream format
|
||||
[self _configureFloatConverterWithFrameSize:_deviceBufferFrameSize];
|
||||
|
||||
// Setup input callback
|
||||
AURenderCallbackStruct microphoneCallbackStruct;
|
||||
microphoneCallbackStruct.inputProc = inputCallback;
|
||||
microphoneCallbackStruct.inputProcRefCon = (__bridge void *)microphone;
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphone->microphoneInput,
|
||||
kAudioOutputUnitProperty_SetInputCallback,
|
||||
kAudioUnitScope_Global,
|
||||
inputBus,
|
||||
µphoneCallbackStruct,
|
||||
sizeof(microphoneCallbackStruct))
|
||||
operation:"Couldn't set input callback"];
|
||||
[self _configureInputCallback];
|
||||
|
||||
// Disable buffer allocation for the recorder (optional - do this if we want to pass in our own)
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphone->microphoneInput,
|
||||
kAudioUnitProperty_ShouldAllocateBuffer,
|
||||
kAudioUnitScope_Output,
|
||||
inputBus,
|
||||
&disableFlag,
|
||||
sizeof(disableFlag))
|
||||
operation:"Could not disable audio unit allocating its own buffers"];
|
||||
// Disable buffer allocation (optional - do this if we want to pass in our own)
|
||||
[self _disableCallbackBufferAllocation];
|
||||
|
||||
// Initialize the audio unit
|
||||
[EZAudio checkResult:AudioUnitInitialize( microphone->microphoneInput )
|
||||
[EZAudio checkResult:AudioUnitInitialize( microphoneInput )
|
||||
operation:"Couldn't initialize the input unit"];
|
||||
|
||||
}
|
||||
#elif TARGET_OS_MAC
|
||||
-(void)_createInputUnit {
|
||||
|
||||
#pragma mark - Audio Component Initialization
|
||||
-(AudioComponentDescription)_getInputAudioComponentDescription {
|
||||
|
||||
// Create localized copy of self
|
||||
EZMicrophone *microphone = (EZMicrophone*)self;
|
||||
|
||||
// Create component description for input HAL
|
||||
AudioComponentDescription inputComponentDescription = {0};
|
||||
// Create an input component description for mic input
|
||||
AudioComponentDescription inputComponentDescription;
|
||||
inputComponentDescription.componentType = kAudioUnitType_Output;
|
||||
inputComponentDescription.componentSubType = kAudioUnitSubType_HALOutput;
|
||||
inputComponentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
inputComponentDescription.componentFlags = 0;
|
||||
inputComponentDescription.componentFlagsMask = 0;
|
||||
#if TARGET_OS_IPHONE
|
||||
inputComponentDescription.componentSubType = kAudioUnitSubType_RemoteIO;
|
||||
#elif TARGET_OS_MAC
|
||||
inputComponentDescription.componentSubType = kAudioUnitSubType_HALOutput;
|
||||
#endif
|
||||
|
||||
// Return the successfully created input component description
|
||||
return inputComponentDescription;
|
||||
|
||||
}
|
||||
|
||||
-(AudioComponent)_getInputComponentWithAudioComponentDescription:(AudioComponentDescription)audioComponentDescription {
|
||||
|
||||
// Try and find the component
|
||||
AudioComponent inputComponent = AudioComponentFindNext( NULL , &inputComponentDescription );
|
||||
if( inputComponent == NULL ){
|
||||
NSLog(@"Couldn't get input component unit!");
|
||||
return;
|
||||
}
|
||||
AudioComponent inputComponent = AudioComponentFindNext( NULL , &audioComponentDescription );
|
||||
NSAssert(inputComponent,@"Couldn't get input component unit!");
|
||||
return inputComponent;
|
||||
|
||||
// Create a new instance of the component and store it for internal use
|
||||
[EZAudio checkResult:AudioComponentInstanceNew(inputComponent,
|
||||
µphone->microphoneInput )
|
||||
}
|
||||
|
||||
-(void)_createNewInstanceForInputComponent:(AudioComponent)audioComponent {
|
||||
|
||||
[EZAudio checkResult:AudioComponentInstanceNew(audioComponent,
|
||||
µphoneInput )
|
||||
operation:"Couldn't open component for microphone input unit."];
|
||||
|
||||
// Enable I/O on microphone input unit
|
||||
UInt32 disableFlag = 0; UInt32 enableFlag = 1;
|
||||
AudioUnitScope outputBus = 0; AudioUnitScope inputBus = 1;
|
||||
// Input Scope
|
||||
[EZAudio checkResult:AudioUnitSetProperty( microphone->microphoneInput,
|
||||
kAudioOutputUnitProperty_EnableIO,
|
||||
kAudioUnitScope_Input,
|
||||
inputBus,
|
||||
&enableFlag,
|
||||
sizeof(enableFlag))
|
||||
operation:"Couldn't enable input on I/O unit."];
|
||||
// Output Scope
|
||||
[EZAudio checkResult:AudioUnitSetProperty( microphone->microphoneInput,
|
||||
}
|
||||
|
||||
#pragma mark - Input/Output Scope Initialization
|
||||
-(void)_disableOutputScope {
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphoneInput,
|
||||
kAudioOutputUnitProperty_EnableIO,
|
||||
kAudioUnitScope_Output,
|
||||
outputBus,
|
||||
&disableFlag,
|
||||
sizeof(enableFlag))
|
||||
kEZAudioMicrophoneOutputBus,
|
||||
&kEZAudioMicrophoneDisableFlag,
|
||||
sizeof(kEZAudioMicrophoneDisableFlag))
|
||||
operation:"Couldn't disable output on I/O unit."];
|
||||
|
||||
}
|
||||
|
||||
-(void)_enableInputScope {
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphoneInput,
|
||||
kAudioOutputUnitProperty_EnableIO,
|
||||
kAudioUnitScope_Input,
|
||||
kEZAudioMicrophoneInputBus,
|
||||
&kEZAudioMicrophoneEnableFlag,
|
||||
sizeof(kEZAudioMicrophoneEnableFlag))
|
||||
operation:"Couldn't enable input on I/O unit."];
|
||||
}
|
||||
|
||||
#pragma mark - Pull Default Device (OSX)
|
||||
#if TARGET_OS_IPHONE
|
||||
// Not needed, using RemoteIO
|
||||
#elif TARGET_OS_MAC
|
||||
-(void)_configureDefaultDevice {
|
||||
// Get the default audio input device (pulls an abstract type from system preferences)
|
||||
AudioDeviceID defaultDevice = kAudioObjectUnknown;
|
||||
UInt32 propertySize = sizeof(defaultDevice);
|
||||
AudioDeviceID defaultDevice = kAudioObjectUnknown;
|
||||
UInt32 propSize = sizeof(defaultDevice);
|
||||
AudioObjectPropertyAddress defaultDeviceProperty;
|
||||
defaultDeviceProperty.mSelector = kAudioHardwarePropertyDefaultInputDevice;
|
||||
defaultDeviceProperty.mScope = kAudioObjectPropertyScopeGlobal;
|
||||
@@ -436,117 +399,199 @@ static OSStatus inputCallback(void *inRefCon,
|
||||
&defaultDeviceProperty,
|
||||
0,
|
||||
NULL,
|
||||
&propertySize,
|
||||
&propSize,
|
||||
&defaultDevice)
|
||||
operation:"Couldn't get default input device"];
|
||||
|
||||
// Set the default device on the microphone input unit
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphone->microphoneInput,
|
||||
propSize = sizeof(defaultDevice);
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphoneInput,
|
||||
kAudioOutputUnitProperty_CurrentDevice,
|
||||
kAudioUnitScope_Global,
|
||||
outputBus,
|
||||
kEZAudioMicrophoneOutputBus,
|
||||
&defaultDevice,
|
||||
sizeof(defaultDevice))
|
||||
propSize)
|
||||
operation:"Couldn't set default device on I/O unit"];
|
||||
|
||||
// Get the stream format description from the newly created input unit and assign it to the output of the input unit
|
||||
propertySize = sizeof(AudioStreamBasicDescription);
|
||||
[EZAudio checkResult:AudioUnitGetProperty( microphone->microphoneInput,
|
||||
AudioStreamBasicDescription inputScopeFormat;
|
||||
propSize = sizeof(AudioStreamBasicDescription);
|
||||
[EZAudio checkResult:AudioUnitGetProperty(microphoneInput,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Output,
|
||||
inputBus,
|
||||
µphone->streamFormat,
|
||||
&propertySize)
|
||||
kEZAudioMicrophoneInputBus,
|
||||
&inputScopeFormat,
|
||||
&propSize)
|
||||
operation:"Couldn't get ASBD from input unit (1)"];
|
||||
|
||||
// Assign the same stream format description from the output of the input unit and pull the sample rate
|
||||
AudioStreamBasicDescription deviceFormat;
|
||||
[EZAudio checkResult:AudioUnitGetProperty( microphone->microphoneInput,
|
||||
AudioStreamBasicDescription outputScopeFormat;
|
||||
propSize = sizeof(AudioStreamBasicDescription);
|
||||
[EZAudio checkResult:AudioUnitGetProperty(microphoneInput,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
inputBus,
|
||||
&deviceFormat,
|
||||
&propertySize)
|
||||
kEZAudioMicrophoneInputBus,
|
||||
&outputScopeFormat,
|
||||
&propSize)
|
||||
operation:"Couldn't get ASBD from input unit (2)"];
|
||||
|
||||
microphone->streamFormat.mBitsPerChannel = 8 * sizeof(AudioUnitSampleType);
|
||||
microphone->streamFormat.mBytesPerFrame = sizeof(AudioUnitSampleType);
|
||||
microphone->streamFormat.mBytesPerPacket = sizeof(AudioUnitSampleType);
|
||||
microphone->streamFormat.mChannelsPerFrame = 2;
|
||||
microphone->streamFormat.mFormatFlags = kAudioFormatFlagsCanonical | kAudioFormatFlagIsNonInterleaved;
|
||||
microphone->streamFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
microphone->streamFormat.mFramesPerPacket = 1;
|
||||
microphone->streamFormat.mSampleRate = deviceFormat.mSampleRate;
|
||||
|
||||
// Readjust property size for ASBD and set the value on the input unit
|
||||
propertySize = sizeof(AudioStreamBasicDescription);
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphone->microphoneInput,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Output,
|
||||
inputBus,
|
||||
µphone->streamFormat,
|
||||
propertySize)
|
||||
operation:"Couldn't set ASBD on input unit"];
|
||||
|
||||
// Notify delegate the audio stream basic description was successfully created
|
||||
if( microphone.microphoneDelegate ){
|
||||
if( [microphone.microphoneDelegate respondsToSelector:@selector(microphone:hasAudioStreamBasicDescription:) ] ){
|
||||
[microphone.microphoneDelegate microphone:microphone
|
||||
hasAudioStreamBasicDescription:microphone->streamFormat];
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the audio buffers to capture the input audio
|
||||
UInt32 bufferSizeFrames = 0;
|
||||
propertySize = sizeof(UInt32);
|
||||
[EZAudio checkResult:AudioUnitGetProperty(microphone->microphoneInput,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
kAudioUnitScope_Global,
|
||||
outputBus,
|
||||
&bufferSizeFrames,
|
||||
&propertySize)
|
||||
operation:"Could not get buffer frame size from input unit"];
|
||||
|
||||
UInt32 bufferSizeBytes = bufferSizeFrames * sizeof(Float32);
|
||||
|
||||
// Create the audio buffer list and pre-malloc the buffers in the list
|
||||
propertySize = offsetof( AudioBufferList, mBuffers[0] ) + ( sizeof( AudioBuffer ) * microphone->streamFormat.mChannelsPerFrame );
|
||||
microphone->microphoneInputBuffer = (AudioBufferList*)malloc(propertySize);
|
||||
microphone->microphoneInputBuffer->mNumberBuffers = microphone->streamFormat.mChannelsPerFrame;
|
||||
for( UInt32 i = 0; i < microphone->microphoneInputBuffer->mNumberBuffers; i++ ){
|
||||
microphone->microphoneInputBuffer->mBuffers[i].mNumberChannels = 1;
|
||||
microphone->microphoneInputBuffer->mBuffers[i].mDataByteSize = bufferSizeBytes;
|
||||
microphone->microphoneInputBuffer->mBuffers[i].mData = malloc(bufferSizeBytes);
|
||||
}
|
||||
|
||||
// Set the convert's stream format
|
||||
microphone->converter = [[AEFloatConverter alloc] initWithSourceFormat:microphone->streamFormat];
|
||||
microphone->floatBuffers = (float**)malloc(sizeof(float*)*microphone->streamFormat.mChannelsPerFrame);
|
||||
assert(microphone->floatBuffers);
|
||||
for ( int i=0; i<microphone->streamFormat.mChannelsPerFrame; i++ ) {
|
||||
microphone->floatBuffers[i] = (float*)malloc(bufferSizeBytes);
|
||||
assert(microphone->floatBuffers[i]);
|
||||
}
|
||||
|
||||
// Setup input callback
|
||||
AURenderCallbackStruct microphoneCallbackStruct;
|
||||
microphoneCallbackStruct.inputProc = inputCallback;
|
||||
microphoneCallbackStruct.inputProcRefCon = (__bridge void *)microphone;
|
||||
[EZAudio checkResult:AudioUnitSetProperty( microphone->microphoneInput,
|
||||
kAudioOutputUnitProperty_SetInputCallback,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
µphoneCallbackStruct,
|
||||
sizeof(microphoneCallbackStruct))
|
||||
operation:"Couldn't set input callback"];
|
||||
|
||||
// Initialize the audio unit
|
||||
[EZAudio checkResult:AudioUnitInitialize( microphone->microphoneInput )
|
||||
operation:"Couldn't initialize the input unit"];
|
||||
microphone->firstInputSampleTime = -1;
|
||||
microphone->inToOutSampleTimeOffset = -1;
|
||||
// Store the input scope's sample rate
|
||||
inputScopeSampleRate = inputScopeFormat.mSampleRate;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark - Pull Sample Rate
|
||||
-(Float64)_configureDeviceSampleRateWithDefault:(float)defaultSampleRate {
|
||||
Float64 hardwareSampleRate = defaultSampleRate;
|
||||
#if TARGET_OS_IPHONE
|
||||
// Use approximations for simulator and pull from real device if connected
|
||||
#if !(TARGET_IPHONE_SIMULATOR)
|
||||
// Sample Rate
|
||||
UInt32 propSize = sizeof(Float64);
|
||||
[EZAudio checkResult:AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate,
|
||||
&propSize,
|
||||
&hardwareSampleRate)
|
||||
operation:"Could not get hardware sample rate from device"];
|
||||
#endif
|
||||
#elif TARGET_OS_MAC
|
||||
hardwareSampleRate = inputScopeSampleRate;
|
||||
#endif
|
||||
return hardwareSampleRate;
|
||||
}
|
||||
|
||||
#pragma mark - Pull Buffer Duration
|
||||
-(Float32)_configureDeviceBufferDurationWithDefault:(float)defaultBufferDuration {
|
||||
Float32 bufferDuration = defaultBufferDuration; // Type 1/43 by default
|
||||
#if TARGET_OS_IPHONE
|
||||
// Use approximations for simulator and pull from real device if connected
|
||||
#if !(TARGET_IPHONE_SIMULATOR)
|
||||
UInt32 propSize = sizeof(Float32);
|
||||
[EZAudio checkResult:AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration,
|
||||
propSize,
|
||||
&bufferDuration)
|
||||
operation:"Couldn't set the preferred buffer duration from device"];
|
||||
// Buffer Size
|
||||
propSize = sizeof(bufferDuration);
|
||||
[EZAudio checkResult:AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration,
|
||||
&propSize,
|
||||
&bufferDuration)
|
||||
operation:"Could not get preferred buffer size from device"];
|
||||
#endif
|
||||
#elif TARGET_OS_MAC
|
||||
|
||||
#endif
|
||||
return bufferDuration;
|
||||
}
|
||||
|
||||
#pragma mark - Pull Buffer Frame Size
|
||||
-(UInt32)_getBufferFrameSize {
|
||||
UInt32 bufferFrameSize;
|
||||
UInt32 propSize = sizeof(bufferFrameSize);
|
||||
[EZAudio checkResult:AudioUnitGetProperty(microphoneInput,
|
||||
#if TARGET_OS_IPHONE
|
||||
kAudioUnitProperty_MaximumFramesPerSlice,
|
||||
#elif TARGET_OS_MAC
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
#endif
|
||||
kAudioUnitScope_Global,
|
||||
kEZAudioMicrophoneOutputBus,
|
||||
&bufferFrameSize,
|
||||
&propSize)
|
||||
operation:"Failed to get buffer frame size"];
|
||||
return bufferFrameSize;
|
||||
}
|
||||
|
||||
#pragma mark - Stream Format Initialization
|
||||
-(void)_configureStreamFormatWithSampleRate:(Float64)sampleRate {
|
||||
// Set the stream format
|
||||
if( !_customASBD ){
|
||||
streamFormat = [EZAudio stereoCanonicalNonInterleavedFormatWithSampleRate:sampleRate];
|
||||
}
|
||||
else {
|
||||
streamFormat.mSampleRate = sampleRate;
|
||||
}
|
||||
UInt32 propSize = sizeof(streamFormat);
|
||||
// Set the stream format for output on the microphone's input scope
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphoneInput,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
kEZAudioMicrophoneOutputBus,
|
||||
&streamFormat,
|
||||
propSize)
|
||||
operation:"Could not set microphone's stream format bus 0"];
|
||||
|
||||
// Set the stream format for the input on the microphone's output scope
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphoneInput,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Output,
|
||||
kEZAudioMicrophoneInputBus,
|
||||
&streamFormat,
|
||||
propSize)
|
||||
operation:"Could not set microphone's stream format bus 1"];
|
||||
}
|
||||
|
||||
-(void)_notifyDelegateOfStreamFormat {
|
||||
if( _microphoneDelegate ){
|
||||
if( [_microphoneDelegate respondsToSelector:@selector(microphone:hasAudioStreamBasicDescription:) ] ){
|
||||
[_microphoneDelegate microphone:self
|
||||
hasAudioStreamBasicDescription:streamFormat];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - AudioBufferList Initialization
|
||||
-(void)_configureAudioBufferListWithFrameSize:(UInt32)bufferFrameSize {
|
||||
UInt32 bufferSizeBytes = bufferFrameSize * streamFormat.mBytesPerFrame;
|
||||
UInt32 propSize = offsetof( AudioBufferList, mBuffers[0] ) + ( sizeof( AudioBuffer ) *streamFormat.mChannelsPerFrame );
|
||||
microphoneInputBuffer = (AudioBufferList*)malloc(propSize);
|
||||
microphoneInputBuffer->mNumberBuffers = streamFormat.mChannelsPerFrame;
|
||||
for( UInt32 i = 0; i < microphoneInputBuffer->mNumberBuffers; i++ ){
|
||||
microphoneInputBuffer->mBuffers[i].mNumberChannels = 1;
|
||||
microphoneInputBuffer->mBuffers[i].mDataByteSize = bufferSizeBytes;
|
||||
microphoneInputBuffer->mBuffers[i].mData = malloc(bufferSizeBytes);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Float Converter Initialization
|
||||
-(void)_configureFloatConverterWithFrameSize:(UInt32)bufferFrameSize {
|
||||
UInt32 bufferSizeBytes = bufferFrameSize * streamFormat.mBytesPerFrame;
|
||||
converter = [[AEFloatConverter alloc] initWithSourceFormat:streamFormat];
|
||||
floatBuffers = (float**)malloc(sizeof(float*)*streamFormat.mChannelsPerFrame);
|
||||
assert(floatBuffers);
|
||||
for ( int i=0; i<streamFormat.mChannelsPerFrame; i++ ) {
|
||||
floatBuffers[i] = (float*)malloc(bufferSizeBytes);
|
||||
assert(floatBuffers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Input Callback Initialization
|
||||
-(void)_configureInputCallback {
|
||||
AURenderCallbackStruct microphoneCallbackStruct;
|
||||
microphoneCallbackStruct.inputProc = inputCallback;
|
||||
microphoneCallbackStruct.inputProcRefCon = (__bridge void *)self;
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphoneInput,
|
||||
kAudioOutputUnitProperty_SetInputCallback,
|
||||
kAudioUnitScope_Global,
|
||||
// output bus for mac
|
||||
#if TARGET_OS_IPHONE
|
||||
kEZAudioMicrophoneInputBus,
|
||||
#elif TARGET_OS_MAC
|
||||
kEZAudioMicrophoneOutputBus,
|
||||
#endif
|
||||
µphoneCallbackStruct,
|
||||
sizeof(microphoneCallbackStruct))
|
||||
operation:"Couldn't set input callback"];
|
||||
}
|
||||
|
||||
-(void)_disableCallbackBufferAllocation {
|
||||
[EZAudio checkResult:AudioUnitSetProperty(microphoneInput,
|
||||
kAudioUnitProperty_ShouldAllocateBuffer,
|
||||
kAudioUnitScope_Output,
|
||||
kEZAudioMicrophoneInputBus,
|
||||
&kEZAudioMicrophoneDisableFlag,
|
||||
sizeof(kEZAudioMicrophoneDisableFlag))
|
||||
operation:"Could not disable audio unit allocating its own buffers"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -106,6 +106,16 @@ inNumberFrames:(UInt32)inNumberFrames
|
||||
*/
|
||||
-(id)initWithDataSource:(id<EZOutputDataSource>)dataSource;
|
||||
|
||||
/**
|
||||
Creates a new instance of the EZOutput and allows the caller to specify an EZOutputDataSource.
|
||||
@param dataSource The EZOutputDataSource that will be used to pull the audio data for the output callback.
|
||||
@param audioStreamBasicDescription The AudioStreamBasicDescription of the EZOutput.
|
||||
@warning AudioStreamBasicDescriptions that are invalid will cause the EZOutput to fail to initialize
|
||||
@return A newly created instance of the EZOutput class.
|
||||
*/
|
||||
-(id) initWithDataSource:(id<EZOutputDataSource>)dataSource
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription;
|
||||
|
||||
#pragma mark - Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
@@ -118,6 +128,16 @@ inNumberFrames:(UInt32)inNumberFrames
|
||||
*/
|
||||
+(EZOutput*)outputWithDataSource:(id<EZOutputDataSource>)dataSource;
|
||||
|
||||
/**
|
||||
Class method to create a new instance of the EZOutput and allows the caller to specify an EZOutputDataSource.
|
||||
@param dataSource The EZOutputDataSource that will be used to pull the audio data for the output callback.
|
||||
@param audioStreamBasicDescription The AudioStreamBasicDescription of the EZOutput.
|
||||
@warning AudioStreamBasicDescriptions that are invalid will cause the EZOutput to fail to initialize
|
||||
@return A newly created instance of the EZOutput class.
|
||||
*/
|
||||
+(EZOutput*)outputWithDataSource:(id<EZOutputDataSource>)dataSource
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription;
|
||||
|
||||
#pragma mark - Singleton
|
||||
///-----------------------------------------------------------
|
||||
/// @name Shared Instance
|
||||
@@ -155,4 +175,16 @@ inNumberFrames:(UInt32)inNumberFrames
|
||||
*/
|
||||
-(BOOL)isPlaying;
|
||||
|
||||
#pragma mark - Setters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Output Format
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the AudioStreamBasicDescription on the output.
|
||||
@warning Do not set this during playback.
|
||||
@param asbd The new AudioStreamBasicDescription to use in place of the current audio format description.
|
||||
*/
|
||||
-(void)setAudioStreamBasicDescription:(AudioStreamBasicDescription)asbd;
|
||||
|
||||
@end
|
||||
|
||||
+130
-42
@@ -27,9 +27,18 @@
|
||||
|
||||
#import "EZAudio.h"
|
||||
|
||||
/// Buses
|
||||
static const AudioUnitScope kEZAudioMicrophoneOutputBus = 0;
|
||||
|
||||
/// Flags
|
||||
static const UInt32 kEZAudioMicrophoneEnableFlag = 1;
|
||||
static const UInt32 kEZAudioMicrophoneDisableFlag = 0;
|
||||
|
||||
@interface EZOutput (){
|
||||
BOOL _isPlaying;
|
||||
AudioUnit _outputUnit;
|
||||
BOOL _customASBD;
|
||||
BOOL _isPlaying;
|
||||
AudioStreamBasicDescription _outputASBD;
|
||||
AudioUnit _outputUnit;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -57,8 +66,8 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
|
||||
TPCircularBuffer *circularBuffer = [output.outputDataSource outputShouldUseCircularBuffer:output];
|
||||
if( !circularBuffer ){
|
||||
Float32 *left = (Float32*)ioData->mBuffers[0].mData;
|
||||
Float32 *right = (Float32*)ioData->mBuffers[1].mData;
|
||||
AudioUnitSampleType *left = (AudioUnitSampleType*)ioData->mBuffers[0].mData;
|
||||
AudioUnitSampleType *right = (AudioUnitSampleType*)ioData->mBuffers[1].mData;
|
||||
for(int i = 0; i < inNumberFrames; i++ ){
|
||||
left[ i ] = 0.0f;
|
||||
right[ i ] = 0.0f;
|
||||
@@ -72,7 +81,8 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
|
||||
// Get the desired amount of bytes to copy
|
||||
int32_t bytesToCopy = ioData->mBuffers[0].mDataByteSize;
|
||||
AudioSampleType *targetBuffer = (AudioSampleType*)ioData->mBuffers[0].mData;
|
||||
AudioSampleType *left = (AudioSampleType*)ioData->mBuffers[0].mData;
|
||||
AudioSampleType *right = (AudioSampleType*)ioData->mBuffers[1].mData;
|
||||
|
||||
// Get the available bytes in the circular buffer
|
||||
int32_t availableBytes;
|
||||
@@ -80,7 +90,8 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
|
||||
// Ideally we'd have all the bytes to be copied, but compare it against the available bytes (get min)
|
||||
int32_t amount = MIN(bytesToCopy,availableBytes);
|
||||
memcpy(targetBuffer,buffer,amount);
|
||||
memcpy(left,buffer,amount);
|
||||
memcpy(right,buffer,amount);
|
||||
|
||||
// Consume those bytes ( this will internally push the head of the circular buffer )
|
||||
TPCircularBufferConsume(circularBuffer,amount);
|
||||
@@ -93,28 +104,21 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
needsBufferListWithFrames:inNumberFrames
|
||||
withBufferSize:&bufferSize];
|
||||
if( !bufferList ){
|
||||
Float32 *left = (Float32*)ioData->mBuffers[0].mData;
|
||||
Float32 *right = (Float32*)ioData->mBuffers[1].mData;
|
||||
for(int i = 0; i < inNumberFrames; i++ ){
|
||||
left[ i ] = 0.0f;
|
||||
right[ i ] = 0.0f;
|
||||
}
|
||||
return noErr;
|
||||
};
|
||||
|
||||
// Interleaved
|
||||
if( !(ioData->mNumberBuffers == 1) ){
|
||||
Float32 *left = (Float32*)ioData->mBuffers[0].mData;
|
||||
Float32 *right = (Float32*)ioData->mBuffers[1].mData;
|
||||
AudioUnitSampleType *left = (AudioUnitSampleType*)ioData->mBuffers[0].mData;
|
||||
AudioUnitSampleType *right = (AudioUnitSampleType*)ioData->mBuffers[1].mData;
|
||||
AudioUnitSampleType *interleaved = (AudioUnitSampleType*)bufferList->mBuffers[0].mData;
|
||||
for(int i = 0; i < inNumberFrames; i++ ){
|
||||
if( bufferList ){
|
||||
Float32 *interleaved = (Float32*)bufferList->mBuffers[0].mData;
|
||||
left[i] = interleaved[i];
|
||||
right[i] = interleaved[i];
|
||||
*left++ = *interleaved++;
|
||||
*right++ = *interleaved++;
|
||||
}
|
||||
else {
|
||||
left[ i ] = 0.0f;
|
||||
right[ i ] = 0.0f;
|
||||
*left++ = 0.0f;
|
||||
*right++ = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,11 +156,28 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id) initWithDataSource:(id<EZOutputDataSource>)dataSource
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription {
|
||||
self = [super init];
|
||||
if(self){
|
||||
_customASBD = YES;
|
||||
_outputASBD = audioStreamBasicDescription;
|
||||
self.outputDataSource = dataSource;
|
||||
[self _configureOutput];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Class Initializers
|
||||
+(EZOutput*)outputWithDataSource:(id<EZOutputDataSource>)dataSource {
|
||||
return [[EZOutput alloc] initWithDataSource:dataSource];
|
||||
}
|
||||
|
||||
+(EZOutput *)outputWithDataSource:(id<EZOutputDataSource>)dataSource
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription {
|
||||
return [[EZOutput alloc] initWithDataSource:dataSource withAudioStreamBasicDescription:audioStreamBasicDescription];
|
||||
}
|
||||
|
||||
#pragma mark - Singleton
|
||||
+(EZOutput*)sharedOutput {
|
||||
static EZOutput *_sharedOutput = nil;
|
||||
@@ -167,18 +188,60 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
return _sharedOutput;
|
||||
}
|
||||
|
||||
#pragma mark - Private Configuration
|
||||
#pragma mark - Audio Component Initialization
|
||||
-(AudioComponentDescription)_getOutputAudioComponentDescription {
|
||||
// Create an output component description for default output device
|
||||
AudioComponentDescription outputComponentDescription;
|
||||
outputComponentDescription.componentFlags = 0;
|
||||
outputComponentDescription.componentFlagsMask = 0;
|
||||
outputComponentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
#if TARGET_OS_IPHONE
|
||||
outputComponentDescription.componentSubType = kAudioUnitSubType_RemoteIO;
|
||||
#elif TARGET_OS_MAC
|
||||
outputComponentDescription.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
#endif
|
||||
outputComponentDescription.componentType = kAudioUnitType_Output;
|
||||
return outputComponentDescription;
|
||||
}
|
||||
|
||||
-(AudioComponent)_getOutputComponentWithAudioComponentDescription:(AudioComponentDescription)outputComponentDescription {
|
||||
// Try and find the component
|
||||
AudioComponent outputComponent = AudioComponentFindNext( NULL , &outputComponentDescription );
|
||||
NSAssert(outputComponent,@"Couldn't get input component unit!");
|
||||
return outputComponent;
|
||||
}
|
||||
|
||||
-(void)_createNewInstanceForOutputComponent:(AudioComponent)outputComponent {
|
||||
//
|
||||
[EZAudio checkResult:AudioComponentInstanceNew( outputComponent, &_outputUnit )
|
||||
operation:"Failed to open component for output unit"];
|
||||
}
|
||||
|
||||
#pragma mark - Configure The Output Unit
|
||||
|
||||
//-(void)_configureOutput {
|
||||
//
|
||||
// // Get component description for output
|
||||
// AudioComponentDescription outputComponentDescription = [self _getOutputAudioComponentDescription];
|
||||
//
|
||||
// // Get the output component
|
||||
// AudioComponent outputComponent = [self _getOutputComponentWithAudioComponentDescription:outputComponentDescription];
|
||||
//
|
||||
// // Create a new instance of the component and store it for internal use
|
||||
// [self _createNewInstanceForOutputComponent:outputComponent];
|
||||
//
|
||||
//}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
-(void)_configureOutput {
|
||||
|
||||
//
|
||||
AudioComponentDescription outputcd;
|
||||
outputcd.componentFlags = 0;
|
||||
outputcd.componentFlagsMask = 0;
|
||||
outputcd.componentFlags = 0;
|
||||
outputcd.componentFlagsMask = 0;
|
||||
outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
outputcd.componentSubType = kAudioUnitSubType_RemoteIO;
|
||||
outputcd.componentType = kAudioUnitType_Output;
|
||||
outputcd.componentSubType = kAudioUnitSubType_RemoteIO;
|
||||
outputcd.componentType = kAudioUnitType_Output;
|
||||
|
||||
//
|
||||
AudioComponent comp = AudioComponentFindNext(NULL,&outputcd);
|
||||
@@ -186,8 +249,8 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
operation:"Failed to get output unit"];
|
||||
|
||||
// Setup the output unit for playback
|
||||
UInt32 oneFlag = 1;
|
||||
AudioUnitElement bus0 = 0;
|
||||
UInt32 oneFlag = 1;
|
||||
AudioUnitElement bus0 = 0;
|
||||
[EZAudio checkResult:AudioUnitSetProperty(_outputUnit,
|
||||
kAudioOutputUnitProperty_EnableIO,
|
||||
kAudioUnitScope_Output,
|
||||
@@ -206,25 +269,18 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
operation:"Could not get hardware sample rate"];
|
||||
#endif
|
||||
|
||||
// Setup an ASBD in canonical format
|
||||
AudioStreamBasicDescription asbd;
|
||||
memset(&asbd, 0, sizeof(asbd));
|
||||
asbd.mBitsPerChannel = 8 * sizeof(AudioUnitSampleType);
|
||||
asbd.mBytesPerFrame = sizeof(AudioUnitSampleType);
|
||||
asbd.mBytesPerPacket = sizeof(AudioUnitSampleType);
|
||||
asbd.mChannelsPerFrame = 2;
|
||||
asbd.mFormatFlags = kAudioFormatFlagsCanonical | kAudioFormatFlagIsNonInterleaved;
|
||||
asbd.mFormatID = kAudioFormatLinearPCM;
|
||||
asbd.mFramesPerPacket = 1;
|
||||
asbd.mSampleRate = hardwareSampleRate;
|
||||
// Setup an ASBD in canonical format by default
|
||||
if( !_customASBD ){
|
||||
_outputASBD = [EZAudio stereoCanonicalNonInterleavedFormatWithSampleRate:hardwareSampleRate];
|
||||
}
|
||||
|
||||
// Set the format for output
|
||||
[EZAudio checkResult:AudioUnitSetProperty(_outputUnit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
bus0,
|
||||
&asbd,
|
||||
sizeof(asbd))
|
||||
&_outputASBD,
|
||||
sizeof(_outputASBD))
|
||||
operation:"Couldn't set the ASBD for input scope/bos 0"];
|
||||
|
||||
//
|
||||
@@ -262,9 +318,22 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
}
|
||||
[EZAudio checkResult:AudioComponentInstanceNew(comp,&_outputUnit)
|
||||
operation:"Failed to open component for output unit"];
|
||||
|
||||
|
||||
|
||||
|
||||
// Setup an ASBD in canonical format by default
|
||||
if( !_customASBD ){
|
||||
_outputASBD = [EZAudio stereoCanonicalNonInterleavedFormatWithSampleRate:44100];
|
||||
}
|
||||
|
||||
// Set the format for output
|
||||
[EZAudio checkResult:AudioUnitSetProperty(_outputUnit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
0,
|
||||
&_outputASBD,
|
||||
sizeof(_outputASBD))
|
||||
operation:"Couldn't set the ASBD for input scope/bos 0"];
|
||||
|
||||
//
|
||||
AURenderCallbackStruct input;
|
||||
input.inputProc = OutputRenderCallback;
|
||||
@@ -306,6 +375,25 @@ static OSStatus OutputRenderCallback(void *inRefCon,
|
||||
return _isPlaying;
|
||||
}
|
||||
|
||||
#pragma mark - Setters
|
||||
-(void)setAudioStreamBasicDescription:(AudioStreamBasicDescription)asbd {
|
||||
if( self.isPlaying ){
|
||||
NSAssert(self.isPlaying,@"Cannot set the AudioStreamBasicDescription while output is performing playback");
|
||||
}
|
||||
else {
|
||||
_customASBD = YES;
|
||||
_outputASBD = asbd;
|
||||
// Set the format for output
|
||||
[EZAudio checkResult:AudioUnitSetProperty(_outputUnit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
0,
|
||||
&_outputASBD,
|
||||
sizeof(_outputASBD))
|
||||
operation:"Couldn't set the ASBD for input scope/bos 0"];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
[EZAudio checkResult:AudioOutputUnitStop(_outputUnit)
|
||||
operation:"Failed to uninitialize output unit"];
|
||||
|
||||
@@ -95,6 +95,7 @@ typedef NS_ENUM(NSInteger,EZPlotType){
|
||||
///-----------------------------------------------------------
|
||||
/// @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.
|
||||
|
||||
+22
-20
@@ -66,14 +66,7 @@ typedef struct {
|
||||
|
||||
#pragma mark - Class Format Helper
|
||||
+(AudioStreamBasicDescription)defaultDestinationFormat {
|
||||
AudioStreamBasicDescription destinationFormat;
|
||||
destinationFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
destinationFormat.mChannelsPerFrame = 1;
|
||||
destinationFormat.mBitsPerChannel = 16;
|
||||
destinationFormat.mBytesPerPacket = destinationFormat.mBytesPerFrame = 2 * destinationFormat.mChannelsPerFrame;
|
||||
destinationFormat.mFramesPerPacket = 1;
|
||||
destinationFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; // little-endian
|
||||
destinationFormat.mSampleRate = 44100.0;
|
||||
AudioStreamBasicDescription destinationFormat = [EZAudio stereoFloatInterleavedFormatWithSampleRate:44100.0];
|
||||
return destinationFormat;
|
||||
}
|
||||
|
||||
@@ -82,16 +75,24 @@ typedef struct {
|
||||
}
|
||||
|
||||
#pragma mark - Private Configuation
|
||||
-(void)_configureRecorderForExistingFile {
|
||||
|
||||
}
|
||||
|
||||
-(void)_configureRecorderForNewFile {
|
||||
|
||||
}
|
||||
|
||||
-(void)_configureRecorder {
|
||||
|
||||
// Create the extended audio file
|
||||
[EZAudio checkResult:ExtAudioFileCreateWithURL(_destinationFileURL,
|
||||
kAudioFileCAFType,
|
||||
&_destinationFormat,
|
||||
NULL,
|
||||
kAudioFileFlags_EraseFile,
|
||||
&_destinationFile)
|
||||
operation:"Failed to create ExtendedAudioFile reference"];
|
||||
kAudioFileCAFType,
|
||||
&_destinationFormat,
|
||||
NULL,
|
||||
kAudioFileFlags_EraseFile,
|
||||
&_destinationFile)
|
||||
operation:"Could not open audio file"];
|
||||
|
||||
// Set the client format
|
||||
_clientFormat = _destinationFormat;
|
||||
@@ -112,7 +113,7 @@ typedef struct {
|
||||
operation:"Failed to initialize with ExtAudioFileWriteAsync"];
|
||||
|
||||
// Setup the audio converter
|
||||
[EZAudio checkResult:AudioConverterNew(&_sourceFormat, &_clientFormat, &_audioConverter)
|
||||
[EZAudio checkResult:AudioConverterNew(&_sourceFormat, &_destinationFormat, &_audioConverter)
|
||||
operation:"Failed to create new audio converter"];
|
||||
|
||||
}
|
||||
@@ -126,18 +127,19 @@ typedef struct {
|
||||
AudioBufferList *convertedData = [EZAudio audioBufferList];
|
||||
convertedData->mNumberBuffers = 1;
|
||||
convertedData->mBuffers[0].mNumberChannels = _clientFormat.mChannelsPerFrame;
|
||||
convertedData->mBuffers[0].mDataByteSize = outputBufferSize;
|
||||
convertedData->mBuffers[0].mData = (UInt8*)malloc(sizeof(UInt8)*outputBufferSize);
|
||||
convertedData->mBuffers[0].mDataByteSize = outputBufferSize*_clientFormat.mChannelsPerFrame;
|
||||
convertedData->mBuffers[0].mData = (AudioUnitSampleType*)malloc(sizeof(AudioUnitSampleType)*outputBufferSize*_clientFormat.mChannelsPerFrame);
|
||||
|
||||
[EZAudio checkResult:AudioConverterFillComplexBuffer(_audioConverter,
|
||||
complexInputDataProc,
|
||||
&(EZRecorderConverterStruct){ .sourceBuffer = bufferList },
|
||||
&bufferSize,
|
||||
convertedData,
|
||||
NULL) operation:"Failed while converting buffers"];
|
||||
NULL)
|
||||
operation:"Failed while converting buffers"];
|
||||
|
||||
// Write the destination audio buffer list into t
|
||||
[EZAudio checkResult:ExtAudioFileWriteAsync(_destinationFile, bufferSize, convertedData)
|
||||
[EZAudio checkResult:ExtAudioFileWriteAsync(_destinationFile,bufferSize,convertedData)
|
||||
operation:"Failed to write audio data to file"];
|
||||
|
||||
// Free resources
|
||||
@@ -158,7 +160,7 @@ static OSStatus complexInputDataProc(AudioConverterRef inAudioConver
|
||||
|
||||
memcpy(ioData,
|
||||
recorderStruct->sourceBuffer,
|
||||
sizeof(AudioBufferList) + (recorderStruct->sourceBuffer->mNumberBuffers-1)*sizeof(AudioBuffer));
|
||||
sizeof(AudioBufferList)+(recorderStruct->sourceBuffer->mNumberBuffers-1)*sizeof(AudioBuffer));
|
||||
recorderStruct->sourceBuffer = NULL;
|
||||
|
||||
return noErr;
|
||||
|
||||
@@ -27,3 +27,16 @@ THE SOFTWARE.
|
||||
Initial release.
|
||||
Components include: EZAudioFile, EZAudioPlot, EZAudioPlotGL, EZMicrophone, EZOutput, and EZRecorder.
|
||||
Provided 6 example projects: CoreGraphicsWaveform, OpenGLWaveform, WaveformFromFile, PassThrough, Record, and PlayFile.
|
||||
|
||||
0.0.2
|
||||
Fix for Cocoapod spec. Forgot to include files with .c extension.
|
||||
|
||||
0.0.3
|
||||
Changing EZAudioPlot and EZAudioPlotGL to scroll for the EZPlotTypeRolling instead of wiping the screen clean when hitting the end
|
||||
Allowed EZMicrophone EZOutput to have custom AudioStreamBasicDescription setters
|
||||
Fixed bug in EZAudioFile's getWaveformData function where it was not exiting after sending back cached waveform data (rereading from the audio file)
|
||||
Added stereo support for EZMicrophone, EZAudioFile, EZRecorder, and EZOutput
|
||||
Added more memory cleanup for EZAudioFile
|
||||
Added adjustable rolling length for EZAudioPlot and EZAudioPlotGL so those rolling graphs can now range from 128 to 8192 whereas before it was fixed at 1024
|
||||
Added adjustable resolution for waveform data coming from the EZAudioFile so output from the getWaveformDataWithCompletionBlock: function can literally be of any size. Try 128 for a low resolution waveform or 8192 for a much higher resolution waveform.
|
||||
Added quick fix for EZOutput to properly route stereo data coming from a circular buffer datasource. Next version (0.0.4) needs to add EZConverter to allow quick conversions between non-interleaved and interleaved formats.
|
||||
|
||||
@@ -23,4 +23,4 @@ THE SOFTWARE.
|
||||
|
||||
==========================================================================================
|
||||
|
||||
0.0.1
|
||||
0.0.2
|
||||
|
||||
@@ -19,4 +19,7 @@
|
||||
<FileRef
|
||||
location = "group:EZAudioPassThroughExample/EZAudioPassThroughExample.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:EZAudioFFTExample/EZAudioFFTExample.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
@@ -0,0 +1,610 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
9417A8F71871492000D9D37B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A8F61871492000D9D37B /* Cocoa.framework */; };
|
||||
9417A9011871492000D9D37B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9417A8FF1871492000D9D37B /* InfoPlist.strings */; };
|
||||
9417A9031871492000D9D37B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9021871492000D9D37B /* main.m */; };
|
||||
9417A9071871492100D9D37B /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9051871492100D9D37B /* Credits.rtf */; };
|
||||
9417A90A1871492100D9D37B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9091871492100D9D37B /* AppDelegate.m */; };
|
||||
9417A90D1871492100D9D37B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9417A90B1871492100D9D37B /* MainMenu.xib */; };
|
||||
9417A90F1871492100D9D37B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9417A90E1871492100D9D37B /* Images.xcassets */; };
|
||||
9417A9161871492100D9D37B /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A9151871492100D9D37B /* XCTest.framework */; };
|
||||
9417A9171871492100D9D37B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A8F61871492000D9D37B /* Cocoa.framework */; };
|
||||
9417A91F1871492100D9D37B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9417A91D1871492100D9D37B /* InfoPlist.strings */; };
|
||||
9417A9211871492100D9D37B /* EZAudioFFTExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9201871492100D9D37B /* EZAudioFFTExampleTests.m */; };
|
||||
9417A9441871493900D9D37B /* AEFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A92C1871493900D9D37B /* AEFloatConverter.m */; };
|
||||
9417A9451871493900D9D37B /* EZAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A92E1871493900D9D37B /* EZAudio.m */; };
|
||||
9417A9461871493900D9D37B /* EZAudioFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9301871493900D9D37B /* EZAudioFile.m */; };
|
||||
9417A9471871493900D9D37B /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9321871493900D9D37B /* EZAudioPlot.m */; };
|
||||
9417A9481871493900D9D37B /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9341871493900D9D37B /* EZAudioPlotGL.m */; };
|
||||
9417A9491871493900D9D37B /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9361871493900D9D37B /* EZAudioPlotGLKViewController.m */; };
|
||||
9417A94A1871493900D9D37B /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9381871493900D9D37B /* EZMicrophone.m */; };
|
||||
9417A94B1871493900D9D37B /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A93A1871493900D9D37B /* EZOutput.m */; };
|
||||
9417A94C1871493900D9D37B /* EZPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A93C1871493900D9D37B /* EZPlot.m */; };
|
||||
9417A94D1871493900D9D37B /* EZRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A93E1871493900D9D37B /* EZRecorder.m */; };
|
||||
9417A94E1871493900D9D37B /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 9417A93F1871493900D9D37B /* TPCircularBuffer.c */; };
|
||||
9417A94F1871493900D9D37B /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9421871493900D9D37B /* CHANGELOG */; };
|
||||
9417A9501871493900D9D37B /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9431871493900D9D37B /* VERSION */; };
|
||||
9417A954187149EA00D9D37B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A951187149EA00D9D37B /* AudioToolbox.framework */; };
|
||||
9417A955187149EA00D9D37B /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A952187149EA00D9D37B /* AudioUnit.framework */; };
|
||||
9417A956187149EA00D9D37B /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A953187149EA00D9D37B /* CoreAudio.framework */; };
|
||||
9417A959187149F000D9D37B /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A957187149F000D9D37B /* GLKit.framework */; };
|
||||
9417A95A187149F000D9D37B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A958187149F000D9D37B /* OpenGL.framework */; };
|
||||
9417A95C18714A1000D9D37B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A95B18714A1000D9D37B /* QuartzCore.framework */; };
|
||||
9417A95E18714A2A00D9D37B /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A95D18714A2A00D9D37B /* Accelerate.framework */; };
|
||||
9417A9D61872130200D9D37B /* FFTViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9D41872130200D9D37B /* FFTViewController.m */; };
|
||||
9417A9D71872130200D9D37B /* FFTViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9D51872130200D9D37B /* FFTViewController.xib */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
9417A9181871492100D9D37B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9417A8EB1871492000D9D37B /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 9417A8F21871492000D9D37B;
|
||||
remoteInfo = EZAudioFFTExample;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
9417A8F31871492000D9D37B /* EZAudioFFTExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioFFTExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9417A8F61871492000D9D37B /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
9417A8F91871492000D9D37B /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
9417A8FA1871492000D9D37B /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
9417A8FB1871492000D9D37B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
9417A8FE1871492000D9D37B /* EZAudioFFTExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioFFTExample-Info.plist"; sourceTree = "<group>"; };
|
||||
9417A9001871492000D9D37B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
9417A9021871492000D9D37B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
9417A9041871492000D9D37B /* EZAudioFFTExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "EZAudioFFTExample-Prefix.pch"; sourceTree = "<group>"; };
|
||||
9417A9061871492100D9D37B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
9417A9081871492100D9D37B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
9417A9091871492100D9D37B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
9417A90C1871492100D9D37B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
9417A90E1871492100D9D37B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
9417A9141871492100D9D37B /* EZAudioFFTExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EZAudioFFTExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9417A9151871492100D9D37B /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
9417A91C1871492100D9D37B /* EZAudioFFTExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioFFTExampleTests-Info.plist"; sourceTree = "<group>"; };
|
||||
9417A91E1871492100D9D37B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
9417A9201871492100D9D37B /* EZAudioFFTExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFTExampleTests.m; sourceTree = "<group>"; };
|
||||
9417A92B1871493900D9D37B /* AEFloatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEFloatConverter.h; sourceTree = "<group>"; };
|
||||
9417A92C1871493900D9D37B /* AEFloatConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AEFloatConverter.m; sourceTree = "<group>"; };
|
||||
9417A92D1871493900D9D37B /* EZAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudio.h; sourceTree = "<group>"; };
|
||||
9417A92E1871493900D9D37B /* EZAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudio.m; sourceTree = "<group>"; };
|
||||
9417A92F1871493900D9D37B /* EZAudioFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFile.h; sourceTree = "<group>"; };
|
||||
9417A9301871493900D9D37B /* EZAudioFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFile.m; sourceTree = "<group>"; };
|
||||
9417A9311871493900D9D37B /* EZAudioPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlot.h; sourceTree = "<group>"; };
|
||||
9417A9321871493900D9D37B /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
9417A9331871493900D9D37B /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
9417A9341871493900D9D37B /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
9417A9351871493900D9D37B /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
9417A9361871493900D9D37B /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
9417A9371871493900D9D37B /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
9417A9381871493900D9D37B /* EZMicrophone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZMicrophone.m; sourceTree = "<group>"; };
|
||||
9417A9391871493900D9D37B /* EZOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZOutput.h; sourceTree = "<group>"; };
|
||||
9417A93A1871493900D9D37B /* EZOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZOutput.m; sourceTree = "<group>"; };
|
||||
9417A93B1871493900D9D37B /* EZPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZPlot.h; sourceTree = "<group>"; };
|
||||
9417A93C1871493900D9D37B /* EZPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZPlot.m; sourceTree = "<group>"; };
|
||||
9417A93D1871493900D9D37B /* EZRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZRecorder.h; sourceTree = "<group>"; };
|
||||
9417A93E1871493900D9D37B /* EZRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZRecorder.m; sourceTree = "<group>"; };
|
||||
9417A93F1871493900D9D37B /* TPCircularBuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = TPCircularBuffer.c; sourceTree = "<group>"; };
|
||||
9417A9401871493900D9D37B /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
9417A9421871493900D9D37B /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
9417A9431871493900D9D37B /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
9417A951187149EA00D9D37B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
9417A952187149EA00D9D37B /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||
9417A953187149EA00D9D37B /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
||||
9417A957187149F000D9D37B /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
|
||||
9417A958187149F000D9D37B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||
9417A95B18714A1000D9D37B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
9417A95D18714A2A00D9D37B /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
9417A9D31872130200D9D37B /* FFTViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FFTViewController.h; sourceTree = "<group>"; };
|
||||
9417A9D41872130200D9D37B /* FFTViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FFTViewController.m; sourceTree = "<group>"; };
|
||||
9417A9D51872130200D9D37B /* FFTViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FFTViewController.xib; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
9417A8F01871492000D9D37B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A95E18714A2A00D9D37B /* Accelerate.framework in Frameworks */,
|
||||
9417A95C18714A1000D9D37B /* QuartzCore.framework in Frameworks */,
|
||||
9417A959187149F000D9D37B /* GLKit.framework in Frameworks */,
|
||||
9417A95A187149F000D9D37B /* OpenGL.framework in Frameworks */,
|
||||
9417A954187149EA00D9D37B /* AudioToolbox.framework in Frameworks */,
|
||||
9417A955187149EA00D9D37B /* AudioUnit.framework in Frameworks */,
|
||||
9417A956187149EA00D9D37B /* CoreAudio.framework in Frameworks */,
|
||||
9417A8F71871492000D9D37B /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9417A9111871492100D9D37B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9171871492100D9D37B /* Cocoa.framework in Frameworks */,
|
||||
9417A9161871492100D9D37B /* XCTest.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
9417A8EA1871492000D9D37B = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A8FC1871492000D9D37B /* EZAudioFFTExample */,
|
||||
9417A91A1871492100D9D37B /* EZAudioFFTExampleTests */,
|
||||
9417A8F51871492000D9D37B /* Frameworks */,
|
||||
9417A8F41871492000D9D37B /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8F41871492000D9D37B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A8F31871492000D9D37B /* EZAudioFFTExample.app */,
|
||||
9417A9141871492100D9D37B /* EZAudioFFTExampleTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8F51871492000D9D37B /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A95D18714A2A00D9D37B /* Accelerate.framework */,
|
||||
9417A95B18714A1000D9D37B /* QuartzCore.framework */,
|
||||
9417A957187149F000D9D37B /* GLKit.framework */,
|
||||
9417A958187149F000D9D37B /* OpenGL.framework */,
|
||||
9417A951187149EA00D9D37B /* AudioToolbox.framework */,
|
||||
9417A952187149EA00D9D37B /* AudioUnit.framework */,
|
||||
9417A953187149EA00D9D37B /* CoreAudio.framework */,
|
||||
9417A8F61871492000D9D37B /* Cocoa.framework */,
|
||||
9417A9151871492100D9D37B /* XCTest.framework */,
|
||||
9417A8F81871492000D9D37B /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8F81871492000D9D37B /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A8F91871492000D9D37B /* AppKit.framework */,
|
||||
9417A8FA1871492000D9D37B /* CoreData.framework */,
|
||||
9417A8FB1871492000D9D37B /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8FC1871492000D9D37B /* EZAudioFFTExample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A92A1871493900D9D37B /* EZAudio */,
|
||||
9417A9081871492100D9D37B /* AppDelegate.h */,
|
||||
9417A9091871492100D9D37B /* AppDelegate.m */,
|
||||
9417A9D31872130200D9D37B /* FFTViewController.h */,
|
||||
9417A9D41872130200D9D37B /* FFTViewController.m */,
|
||||
9417A9D51872130200D9D37B /* FFTViewController.xib */,
|
||||
9417A90B1871492100D9D37B /* MainMenu.xib */,
|
||||
9417A90E1871492100D9D37B /* Images.xcassets */,
|
||||
9417A8FD1871492000D9D37B /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioFFTExample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8FD1871492000D9D37B /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A8FE1871492000D9D37B /* EZAudioFFTExample-Info.plist */,
|
||||
9417A8FF1871492000D9D37B /* InfoPlist.strings */,
|
||||
9417A9021871492000D9D37B /* main.m */,
|
||||
9417A9041871492000D9D37B /* EZAudioFFTExample-Prefix.pch */,
|
||||
9417A9051871492100D9D37B /* Credits.rtf */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A91A1871492100D9D37B /* EZAudioFFTExampleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9201871492100D9D37B /* EZAudioFFTExampleTests.m */,
|
||||
9417A91B1871492100D9D37B /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioFFTExampleTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A91B1871492100D9D37B /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A91C1871492100D9D37B /* EZAudioFFTExampleTests-Info.plist */,
|
||||
9417A91D1871492100D9D37B /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A92A1871493900D9D37B /* EZAudio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A92B1871493900D9D37B /* AEFloatConverter.h */,
|
||||
9417A92C1871493900D9D37B /* AEFloatConverter.m */,
|
||||
9417A92D1871493900D9D37B /* EZAudio.h */,
|
||||
9417A92E1871493900D9D37B /* EZAudio.m */,
|
||||
9417A92F1871493900D9D37B /* EZAudioFile.h */,
|
||||
9417A9301871493900D9D37B /* EZAudioFile.m */,
|
||||
9417A9311871493900D9D37B /* EZAudioPlot.h */,
|
||||
9417A9321871493900D9D37B /* EZAudioPlot.m */,
|
||||
9417A9331871493900D9D37B /* EZAudioPlotGL.h */,
|
||||
9417A9341871493900D9D37B /* EZAudioPlotGL.m */,
|
||||
9417A9351871493900D9D37B /* EZAudioPlotGLKViewController.h */,
|
||||
9417A9361871493900D9D37B /* EZAudioPlotGLKViewController.m */,
|
||||
9417A9371871493900D9D37B /* EZMicrophone.h */,
|
||||
9417A9381871493900D9D37B /* EZMicrophone.m */,
|
||||
9417A9391871493900D9D37B /* EZOutput.h */,
|
||||
9417A93A1871493900D9D37B /* EZOutput.m */,
|
||||
9417A93B1871493900D9D37B /* EZPlot.h */,
|
||||
9417A93C1871493900D9D37B /* EZPlot.m */,
|
||||
9417A93D1871493900D9D37B /* EZRecorder.h */,
|
||||
9417A93E1871493900D9D37B /* EZRecorder.m */,
|
||||
9417A93F1871493900D9D37B /* TPCircularBuffer.c */,
|
||||
9417A9401871493900D9D37B /* TPCircularBuffer.h */,
|
||||
9417A9411871493900D9D37B /* VERSION */,
|
||||
);
|
||||
name = EZAudio;
|
||||
path = ../../../../EZAudio;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9411871493900D9D37B /* VERSION */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9421871493900D9D37B /* CHANGELOG */,
|
||||
9417A9431871493900D9D37B /* VERSION */,
|
||||
);
|
||||
path = VERSION;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
9417A8F21871492000D9D37B /* EZAudioFFTExample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9417A9241871492100D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExample" */;
|
||||
buildPhases = (
|
||||
9417A8EF1871492000D9D37B /* Sources */,
|
||||
9417A8F01871492000D9D37B /* Frameworks */,
|
||||
9417A8F11871492000D9D37B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = EZAudioFFTExample;
|
||||
productName = EZAudioFFTExample;
|
||||
productReference = 9417A8F31871492000D9D37B /* EZAudioFFTExample.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
9417A9131871492100D9D37B /* EZAudioFFTExampleTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9417A9271871492100D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExampleTests" */;
|
||||
buildPhases = (
|
||||
9417A9101871492100D9D37B /* Sources */,
|
||||
9417A9111871492100D9D37B /* Frameworks */,
|
||||
9417A9121871492100D9D37B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
9417A9191871492100D9D37B /* PBXTargetDependency */,
|
||||
);
|
||||
name = EZAudioFFTExampleTests;
|
||||
productName = EZAudioFFTExampleTests;
|
||||
productReference = 9417A9141871492100D9D37B /* EZAudioFFTExampleTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
9417A8EB1871492000D9D37B /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Syed Haris Ali";
|
||||
TargetAttributes = {
|
||||
9417A9131871492100D9D37B = {
|
||||
TestTargetID = 9417A8F21871492000D9D37B;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 9417A8EE1871492000D9D37B /* Build configuration list for PBXProject "EZAudioFFTExample" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 9417A8EA1871492000D9D37B;
|
||||
productRefGroup = 9417A8F41871492000D9D37B /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
9417A8F21871492000D9D37B /* EZAudioFFTExample */,
|
||||
9417A9131871492100D9D37B /* EZAudioFFTExampleTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
9417A8F11871492000D9D37B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9011871492000D9D37B /* InfoPlist.strings in Resources */,
|
||||
9417A9D71872130200D9D37B /* FFTViewController.xib in Resources */,
|
||||
9417A90F1871492100D9D37B /* Images.xcassets in Resources */,
|
||||
9417A9071871492100D9D37B /* Credits.rtf in Resources */,
|
||||
9417A9501871493900D9D37B /* VERSION in Resources */,
|
||||
9417A90D1871492100D9D37B /* MainMenu.xib in Resources */,
|
||||
9417A94F1871493900D9D37B /* CHANGELOG in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9417A9121871492100D9D37B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A91F1871492100D9D37B /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
9417A8EF1871492000D9D37B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A94D1871493900D9D37B /* EZRecorder.m in Sources */,
|
||||
9417A9471871493900D9D37B /* EZAudioPlot.m in Sources */,
|
||||
9417A94C1871493900D9D37B /* EZPlot.m in Sources */,
|
||||
9417A9D61872130200D9D37B /* FFTViewController.m in Sources */,
|
||||
9417A9441871493900D9D37B /* AEFloatConverter.m in Sources */,
|
||||
9417A94A1871493900D9D37B /* EZMicrophone.m in Sources */,
|
||||
9417A94B1871493900D9D37B /* EZOutput.m in Sources */,
|
||||
9417A9451871493900D9D37B /* EZAudio.m in Sources */,
|
||||
9417A94E1871493900D9D37B /* TPCircularBuffer.c in Sources */,
|
||||
9417A9481871493900D9D37B /* EZAudioPlotGL.m in Sources */,
|
||||
9417A9461871493900D9D37B /* EZAudioFile.m in Sources */,
|
||||
9417A90A1871492100D9D37B /* AppDelegate.m in Sources */,
|
||||
9417A9491871493900D9D37B /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
9417A9031871492000D9D37B /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9417A9101871492100D9D37B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9211871492100D9D37B /* EZAudioFFTExampleTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
9417A9191871492100D9D37B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 9417A8F21871492000D9D37B /* EZAudioFFTExample */;
|
||||
targetProxy = 9417A9181871492100D9D37B /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
9417A8FF1871492000D9D37B /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A9001871492000D9D37B /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9051871492100D9D37B /* Credits.rtf */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A9061871492100D9D37B /* en */,
|
||||
);
|
||||
name = Credits.rtf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A90B1871492100D9D37B /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A90C1871492100D9D37B /* Base */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A91D1871492100D9D37B /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A91E1871492100D9D37B /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
9417A9221871492100D9D37B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9417A9231871492100D9D37B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9417A9251871492100D9D37B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExample/EZAudioFFTExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9417A9261871492100D9D37B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExample/EZAudioFFTExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9417A9281871492100D9D37B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioFFTExample.app/Contents/MacOS/EZAudioFFTExample";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "EZAudioFFTExampleTests/EZAudioFFTExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9417A9291871492100D9D37B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioFFTExample.app/Contents/MacOS/EZAudioFFTExample";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExampleTests/EZAudioFFTExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
9417A8EE1871492000D9D37B /* Build configuration list for PBXProject "EZAudioFFTExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9417A9221871492100D9D37B /* Debug */,
|
||||
9417A9231871492100D9D37B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9417A9241871492100D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9417A9251871492100D9D37B /* Debug */,
|
||||
9417A9261871492100D9D37B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9417A9271871492100D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExampleTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9417A9281871492100D9D37B /* Debug */,
|
||||
9417A9291871492100D9D37B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 9417A8EB1871492000D9D37B /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 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 <Cocoa/Cocoa.h>
|
||||
|
||||
#import "FFTViewController.h"
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
|
||||
/**
|
||||
The FFTViewController
|
||||
*/
|
||||
@property (nonatomic,strong) FFTViewController *fftViewController;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 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 "AppDelegate.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
@synthesize fftViewController;
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
// Swap in our view controller in the window's content view
|
||||
self.fftViewController = [[FFTViewController alloc] init];
|
||||
// Resize view controller to content view's current size
|
||||
self.fftViewController.view.frame = [self.window.contentView frame];
|
||||
// Add resizing flags to make the view controller resize with the window
|
||||
self.fftViewController.view.autoresizingMask = (NSViewWidthSizable|NSViewHeightSizable);
|
||||
// Add in the core graphics view controller as subview
|
||||
[self.window.contentView addSubview:self.fftViewController.view];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,679 @@
|
||||
<?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">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="EZAudioFFTExample" id="56">
|
||||
<menu key="submenu" title="EZAudioFFTExample" systemMenu="apple" id="57">
|
||||
<items>
|
||||
<menuItem title="About EZAudioFFTExample" 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"/>
|
||||
</menuItem>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
|
||||
<menuItem isSeparatorItem="YES" id="143">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Services" id="131">
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide EZAudioFFTExample" 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 isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit EZAudioFFTExample" 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">
|
||||
<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">
|
||||
<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">
|
||||
<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>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<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">
|
||||
<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 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">
|
||||
<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 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>
|
||||
</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">
|
||||
<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">
|
||||
<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>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="348">
|
||||
<menu key="submenu" title="Substitutions" id="349">
|
||||
<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">
|
||||
<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>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="450">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="451">
|
||||
<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>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<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>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="375">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="376">
|
||||
<items>
|
||||
<menuItem title="Font" id="377">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<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">
|
||||
<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"/>
|
||||
<menu key="submenu" title="Kern" id="415">
|
||||
<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>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="398">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="411">
|
||||
<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>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="399">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="405">
|
||||
<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">
|
||||
<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>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="496">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<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 isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="508">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="509">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<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">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<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>
|
||||
</menuItem>
|
||||
<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>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="295">
|
||||
<menu key="submenu" title="View" id="296">
|
||||
<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>
|
||||
</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">
|
||||
<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">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="490">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="EZAudioFFTExample Help" keyEquivalent="?" id="492">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</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"/>
|
||||
<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"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="PCv-Jm-jzO" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="PCv-Jm-jzO" secondAttribute="trailing" id="A2i-gs-EWe"/>
|
||||
<constraint firstItem="PCv-Jm-jzO" firstAttribute="leading" secondItem="372" secondAttribute="leading" id="Gex-TR-aqy"/>
|
||||
<constraint firstAttribute="bottom" secondItem="PCv-Jm-jzO" secondAttribute="bottom" id="Kqa-V4-EDP"/>
|
||||
<constraint firstItem="PCv-Jm-jzO" firstAttribute="top" secondItem="372" secondAttribute="top" id="MeC-7d-nwe"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</window>
|
||||
<customObject id="494" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="audioPlot" destination="PCv-Jm-jzO" id="aGl-Mf-G6W"/>
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager"/>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.sha.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2013 Syed Haris Ali. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// FFTViewController.h
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 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 <Cocoa/Cocoa.h>
|
||||
|
||||
/**
|
||||
EZAudio
|
||||
*/
|
||||
#import "EZAudio.h"
|
||||
|
||||
/**
|
||||
Accelerate
|
||||
*/
|
||||
#import <Accelerate/Accelerate.h>
|
||||
|
||||
/**
|
||||
The FFTViewController demonstrates how to use the Accelerate framework to calculate the real-time FFT of audio data provided by an EZAudioMicrophone.
|
||||
*/
|
||||
@interface FFTViewController : NSViewController <EZMicrophoneDelegate>
|
||||
|
||||
#pragma mark - Components
|
||||
/**
|
||||
EZAudioPlot for frequency plot
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlot *audioPlotFreq;
|
||||
|
||||
/**
|
||||
EZAudioPlot for time plot
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlotGL *audioPlotTime;
|
||||
|
||||
/**
|
||||
Microphone
|
||||
*/
|
||||
@property (nonatomic,strong) EZMicrophone *microphone;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,176 @@
|
||||
//
|
||||
// FFTViewController.m
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 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 "FFTViewController.h"
|
||||
|
||||
@interface FFTViewController (){
|
||||
COMPLEX_SPLIT _A;
|
||||
FFTSetup _FFTSetup;
|
||||
BOOL _isFFTSetup;
|
||||
vDSP_Length _log2n;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation FFTViewController
|
||||
@synthesize audioPlotFreq;
|
||||
@synthesize audioPlotTime;
|
||||
@synthesize microphone;
|
||||
|
||||
#pragma mark - Initialization
|
||||
-(id)init {
|
||||
self = [super initWithNibName:NSStringFromClass(self.class) bundle:nil];
|
||||
if(self){
|
||||
[self initializeViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithNibName:NSStringFromClass(self.class) bundle:nil];
|
||||
if(self){
|
||||
[self initializeViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
||||
self = [super initWithNibName:NSStringFromClass(self.class) bundle:nil];
|
||||
if(self){
|
||||
[self initializeViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Initialize View Controller
|
||||
-(void)initializeViewController {
|
||||
// Create an instance of the microphone and tell it to use this view controller instance as the delegate
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self
|
||||
startsImmediately:YES];
|
||||
}
|
||||
|
||||
#pragma mark - Customize the Audio Plot
|
||||
-(void)awakeFromNib {
|
||||
|
||||
// Setup time domain audio plot
|
||||
self.audioPlotTime.backgroundColor = [NSColor colorWithCalibratedRed: 0.569 green: 0.82 blue: 0.478 alpha: 1];
|
||||
self.audioPlotTime.color = [NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
self.audioPlotTime.shouldFill = YES;
|
||||
self.audioPlotTime.shouldMirror = YES;
|
||||
self.audioPlotTime.plotType = EZPlotTypeRolling;
|
||||
|
||||
// Setup frequency domain audio plot
|
||||
self.audioPlotFreq.backgroundColor = [NSColor colorWithCalibratedRed: 0.984 green: 0.471 blue: 0.525 alpha: 1];
|
||||
self.audioPlotFreq.color = [NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
self.audioPlotFreq.shouldFill = YES;
|
||||
self.audioPlotFreq.plotType = EZPlotTypeBuffer;
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - FFT
|
||||
/**
|
||||
Adapted from http://batmobile.blogs.ilrt.org/fourier-transforms-on-an-iphone/
|
||||
*/
|
||||
-(void)createFFTWithBufferSize:(float)bufferSize withAudioData:(float*)data {
|
||||
|
||||
// Setup the length
|
||||
_log2n = log2f(bufferSize);
|
||||
|
||||
// Calculate the weights array. This is a one-off operation.
|
||||
_FFTSetup = vDSP_create_fftsetup(_log2n, FFT_RADIX2);
|
||||
|
||||
// For an FFT, numSamples must be a power of 2, i.e. is always even
|
||||
int nOver2 = bufferSize/2;
|
||||
|
||||
// Populate *window with the values for a hamming window function
|
||||
float *window = (float *)malloc(sizeof(float)*bufferSize);
|
||||
vDSP_hamm_window(window, bufferSize, 0);
|
||||
// Window the samples
|
||||
vDSP_vmul(data, 1, window, 1, data, 1, bufferSize);
|
||||
|
||||
// Define complex buffer
|
||||
_A.realp = (float *) malloc(nOver2*sizeof(float));
|
||||
_A.imagp = (float *) malloc(nOver2*sizeof(float));
|
||||
|
||||
}
|
||||
|
||||
-(void)updateFFTWithBufferSize:(float)bufferSize withAudioData:(float*)data {
|
||||
|
||||
// For an FFT, numSamples must be a power of 2, i.e. is always even
|
||||
int nOver2 = bufferSize/2;
|
||||
|
||||
// Pack samples:
|
||||
// C(re) -> A[n], C(im) -> A[n+1]
|
||||
vDSP_ctoz((COMPLEX*)data, 2, &_A, 1, nOver2);
|
||||
|
||||
// Perform a forward FFT using fftSetup and A
|
||||
// Results are returned in A
|
||||
vDSP_fft_zrip(_FFTSetup, &_A, 1, _log2n, FFT_FORWARD);
|
||||
|
||||
// Convert COMPLEX_SPLIT A result to magnitudes
|
||||
float amp[nOver2];
|
||||
float maxMag = 0;
|
||||
|
||||
for(int i=0; i<nOver2; i++) {
|
||||
// Calculate the magnitude
|
||||
float mag = _A.realp[i]*_A.realp[i]+_A.imagp[i]*_A.imagp[i];
|
||||
maxMag = mag > maxMag ? mag : maxMag;
|
||||
}
|
||||
for(int i=0; i<nOver2; i++) {
|
||||
// Calculate the magnitude
|
||||
float mag = _A.realp[i]*_A.realp[i]+_A.imagp[i]*_A.imagp[i];
|
||||
// Bind the value to be less than 1.0 to fit in the graph
|
||||
amp[i] = [EZAudio MAP:mag leftMin:0.0 leftMax:maxMag rightMin:0.0 rightMax:1.0];
|
||||
}
|
||||
|
||||
// Update the frequency domain plot
|
||||
[self.audioPlotFreq updateBuffer:amp
|
||||
withBufferSize:nOver2];
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
-(void) microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
// Update time domain plot
|
||||
[self.audioPlotTime updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
|
||||
// Setup the FFT if it's not already setup
|
||||
if( !_isFFTSetup ){
|
||||
[self createFFTWithBufferSize:bufferSize withAudioData:buffer[0]];
|
||||
_isFFTSetup = YES;
|
||||
}
|
||||
|
||||
// Get the FFT data
|
||||
[self updateFFTWithBufferSize:bufferSize withAudioData:buffer[0]];
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,48 @@
|
||||
<?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">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="FFTViewController">
|
||||
<connections>
|
||||
<outlet property="audioPlotFreq" destination="4V2-1I-w64" id="SkA-7R-4V8"/>
|
||||
<outlet property="audioPlotTime" destination="Zcc-CT-67u" id="lE0-d7-KUs"/>
|
||||
<outlet property="view" destination="1" id="2"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<customView id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<splitView dividerStyle="thin" translatesAutoresizingMaskIntoConstraints="NO" id="78b-rz-Bpl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<customView fixedFrame="YES" id="Zcc-CT-67u" customClass="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="132"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</customView>
|
||||
<customView fixedFrame="YES" id="4V2-1I-w64" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="133" width="480" height="139"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
<holdingPriorities>
|
||||
<real value="250"/>
|
||||
<real value="250"/>
|
||||
</holdingPriorities>
|
||||
</splitView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="78b-rz-Bpl" secondAttribute="bottom" id="CZL-aU-xpy"/>
|
||||
<constraint firstAttribute="trailing" secondItem="78b-rz-Bpl" secondAttribute="trailing" id="eXt-EL-upz"/>
|
||||
<constraint firstItem="78b-rz-Bpl" firstAttribute="top" secondItem="1" secondAttribute="top" id="lFP-vc-nHC"/>
|
||||
<constraint firstItem="78b-rz-Bpl" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="lWl-1T-nHB"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\paperw9840\paperh8400
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
|
||||
|
||||
\f0\b\fs24 \cf0 Engineering:
|
||||
\b0 \
|
||||
Some people\
|
||||
\
|
||||
|
||||
\b Human Interface Design:
|
||||
\b0 \
|
||||
Some other people\
|
||||
\
|
||||
|
||||
\b Testing:
|
||||
\b0 \
|
||||
Hopefully not nobody\
|
||||
\
|
||||
|
||||
\b Documentation:
|
||||
\b0 \
|
||||
Whoever\
|
||||
\
|
||||
|
||||
\b With special thanks to:
|
||||
\b0 \
|
||||
Mom\
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// main.m
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/29/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.sha.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// EZAudioFFTExampleTests.m
|
||||
// EZAudioFFTExampleTests
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/29/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface EZAudioFFTExampleTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation EZAudioFFTExampleTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testExample
|
||||
{
|
||||
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@end
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
+1
-1
@@ -151,7 +151,7 @@ withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
-(void)microphone:(EZMicrophone *)microphone hasAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription {
|
||||
// The AudioStreamBasicDescription of the microphone stream. This is useful when configuring the EZRecorder or telling another component what audio format type to expect.
|
||||
// Here's a print function to allow you to inspect it a little easier
|
||||
[EZAudio printASBD:audioStreamBasicDescription];
|
||||
// [EZAudio printASBD:audioStreamBasicDescription];
|
||||
}
|
||||
|
||||
-(void)microphone:(EZMicrophone *)microphone
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?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="4514" systemVersion="13B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@
|
||||
941D71C31864C457007D52D8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
941D71C51864C457007D52D8 /* EZAudioPassThroughExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "EZAudioPassThroughExample-Prefix.pch"; sourceTree = "<group>"; };
|
||||
941D71C71864C457007D52D8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
941D71C91864C457007D52D8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
941D71C91864C457007D52D8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = EZAudioPassThroughExample/AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
||||
941D71CA1864C457007D52D8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
941D71CD1864C457007D52D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
941D71CF1864C457007D52D8 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
|
||||
@@ -5,6 +5,23 @@
|
||||
// Created by Syed Haris Ali on 12/20/13.
|
||||
// Copyright (c) 2013 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 <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@@ -5,6 +5,23 @@
|
||||
// Created by Syed Haris Ali on 12/20/13.
|
||||
// Copyright (c) 2013 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 "AppDelegate.h"
|
||||
|
||||
|
||||
+22
@@ -5,6 +5,23 @@
|
||||
// Created by Syed Haris Ali on 12/20/13.
|
||||
// Copyright (c) 2013 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 <Cocoa/Cocoa.h>
|
||||
|
||||
@@ -21,6 +38,11 @@
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlotGL *audioPlot;
|
||||
|
||||
/**
|
||||
The Microphone
|
||||
*/
|
||||
@property (nonatomic,strong) EZMicrophone *microphone;
|
||||
|
||||
#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)
|
||||
|
||||
+21
-2
@@ -5,6 +5,23 @@
|
||||
// Created by Syed Haris Ali on 12/20/13.
|
||||
// Copyright (c) 2013 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 "PassThroughViewController.h"
|
||||
|
||||
@@ -14,6 +31,8 @@
|
||||
@end
|
||||
|
||||
@implementation PassThroughViewController
|
||||
@synthesize audioPlot;
|
||||
@synthesize microphone;
|
||||
|
||||
#pragma mark - Initialization
|
||||
-(id)init {
|
||||
@@ -44,8 +63,7 @@
|
||||
/**
|
||||
Initialize the circular buffer
|
||||
*/
|
||||
[EZAudio circularBuffer:&_circularBuffer
|
||||
withSize:1024];
|
||||
[EZAudio circularBuffer:&_circularBuffer withSize:2048];
|
||||
}
|
||||
|
||||
#pragma mark - Customize the Audio Plot
|
||||
@@ -70,6 +88,7 @@
|
||||
/**
|
||||
Start the output
|
||||
*/
|
||||
[[EZOutput sharedOutput] setAudioStreamBasicDescription:[EZMicrophone sharedMicrophone].audioStreamBasicDescription];
|
||||
[EZOutput sharedOutput].outputDataSource = self;
|
||||
[[EZOutput sharedOutput] startPlayback];
|
||||
|
||||
|
||||
+1
-1
@@ -188,8 +188,8 @@
|
||||
94056F0D185BD83400EB94BA /* AppDelegate.m */,
|
||||
94056F2E185BD86D00EB94BA /* PlayFileViewController.h */,
|
||||
94056F2F185BD86D00EB94BA /* PlayFileViewController.m */,
|
||||
9417A6D41865928C00D9D37B /* simple-drum-beat.wav */,
|
||||
94056F30185BD86D00EB94BA /* PlayFileViewController.xib */,
|
||||
9417A6D41865928C00D9D37B /* simple-drum-beat.wav */,
|
||||
94056F0F185BD83400EB94BA /* MainMenu.xib */,
|
||||
94056F12185BD83400EB94BA /* Images.xcassets */,
|
||||
94056F01185BD83400EB94BA /* Supporting Files */,
|
||||
|
||||
+9
-6
@@ -167,14 +167,17 @@
|
||||
// Stop playback
|
||||
[[EZOutput sharedOutput] stopPlayback];
|
||||
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL andDelegate:self];
|
||||
self.eof = NO;
|
||||
self.filePathLabel.stringValue = filePathURL.lastPathComponent;
|
||||
self.framePositionSlider.minValue = 0.0f;
|
||||
self.framePositionSlider.maxValue = (double)self.audioFile.totalFrames;
|
||||
self.playButton.state = NSOffState;
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL andDelegate:self];
|
||||
self.eof = NO;
|
||||
self.filePathLabel.stringValue = filePathURL.lastPathComponent;
|
||||
self.framePositionSlider.minValue = 0.0f;
|
||||
self.framePositionSlider.maxValue = (double)self.audioFile.totalFrames;
|
||||
self.playButton.state = NSOffState;
|
||||
self.plotSegmentControl.selectedSegment = 1;
|
||||
|
||||
// Set the client format from the EZAudioFile on the output
|
||||
[[EZOutput sharedOutput] setAudioStreamBasicDescription:self.audioFile.clientFormat];
|
||||
|
||||
// Plot the whole waveform
|
||||
self.audioPlot.plotType = EZPlotTypeBuffer;
|
||||
self.audioPlot.shouldFill = YES;
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@
|
||||
// Plot the whole waveform
|
||||
self.audioPlot.plotType = EZPlotTypeBuffer;
|
||||
self.audioPlot.shouldFill = YES;
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
self.audioPlot.shouldMirror = YES;
|
||||
[self.audioFile getWaveformDataWithCompletionBlock:^(float *waveformData, UInt32 length) {
|
||||
[self.audioPlot updateBuffer:waveformData withBufferSize:length];
|
||||
}];
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="vXZ-lx-hvc">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="vXZ-lx-hvc">
|
||||
<dependencies>
|
||||
<deployment defaultVersion="1536" identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
||||
+7
-1
@@ -8,7 +8,9 @@
|
||||
|
||||
#import "CoreGraphicsWaveformViewController.h"
|
||||
|
||||
@interface CoreGraphicsWaveformViewController ()
|
||||
@interface CoreGraphicsWaveformViewController (){
|
||||
float scale;
|
||||
}
|
||||
#pragma mark - UI Extras
|
||||
@property (nonatomic,weak) IBOutlet UILabel *microphoneTextLabel;
|
||||
@end
|
||||
@@ -63,6 +65,10 @@
|
||||
|
||||
}
|
||||
|
||||
-(void)pinch:(UIPinchGestureRecognizer*)pinch {
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
-(void)changePlotType:(id)sender {
|
||||
NSInteger selectedSegment = [sender selectedSegmentIndex];
|
||||
|
||||
@@ -19,4 +19,7 @@
|
||||
<FileRef
|
||||
location = "group:EZAudioCoreGraphicsWaveformExample/../EZAudioPassThroughExample/EZAudioPassThroughExample.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:EZAudioFFTExample/EZAudioFFTExample.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
@@ -0,0 +1,592 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
9417A96C1871E88300D9D37B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A96B1871E88300D9D37B /* Foundation.framework */; };
|
||||
9417A96E1871E88300D9D37B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A96D1871E88300D9D37B /* CoreGraphics.framework */; };
|
||||
9417A9701871E88300D9D37B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A96F1871E88300D9D37B /* UIKit.framework */; };
|
||||
9417A9761871E88300D9D37B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9741871E88300D9D37B /* InfoPlist.strings */; };
|
||||
9417A9781871E88300D9D37B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9771871E88300D9D37B /* main.m */; };
|
||||
9417A97C1871E88300D9D37B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A97B1871E88300D9D37B /* AppDelegate.m */; };
|
||||
9417A97F1871E88300D9D37B /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9417A97D1871E88300D9D37B /* Main_iPhone.storyboard */; };
|
||||
9417A9821871E88300D9D37B /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9801871E88300D9D37B /* Main_iPad.storyboard */; };
|
||||
9417A9871871E88300D9D37B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9861871E88300D9D37B /* Images.xcassets */; };
|
||||
9417A98E1871E88300D9D37B /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A98D1871E88300D9D37B /* XCTest.framework */; };
|
||||
9417A98F1871E88300D9D37B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A96B1871E88300D9D37B /* Foundation.framework */; };
|
||||
9417A9901871E88300D9D37B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A96F1871E88300D9D37B /* UIKit.framework */; };
|
||||
9417A9981871E88300D9D37B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9961871E88300D9D37B /* InfoPlist.strings */; };
|
||||
9417A99A1871E88300D9D37B /* EZAudioFFTExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9991871E88300D9D37B /* EZAudioFFTExampleTests.m */; };
|
||||
9417A9A41871E89500D9D37B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A9A31871E89500D9D37B /* AudioToolbox.framework */; };
|
||||
9417A9A61871E8A100D9D37B /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A9A51871E8A100D9D37B /* GLKit.framework */; };
|
||||
9417A9C11871E96300D9D37B /* AEFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9A91871E96300D9D37B /* AEFloatConverter.m */; };
|
||||
9417A9C21871E96300D9D37B /* EZAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9AB1871E96300D9D37B /* EZAudio.m */; };
|
||||
9417A9C31871E96300D9D37B /* EZAudioFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9AD1871E96300D9D37B /* EZAudioFile.m */; };
|
||||
9417A9C41871E96300D9D37B /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9AF1871E96300D9D37B /* EZAudioPlot.m */; };
|
||||
9417A9C51871E96300D9D37B /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9B11871E96300D9D37B /* EZAudioPlotGL.m */; };
|
||||
9417A9C61871E96300D9D37B /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9B31871E96300D9D37B /* EZAudioPlotGLKViewController.m */; };
|
||||
9417A9C71871E96300D9D37B /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9B51871E96300D9D37B /* EZMicrophone.m */; };
|
||||
9417A9C81871E96300D9D37B /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9B71871E96300D9D37B /* EZOutput.m */; };
|
||||
9417A9C91871E96300D9D37B /* EZPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9B91871E96300D9D37B /* EZPlot.m */; };
|
||||
9417A9CA1871E96300D9D37B /* EZRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9BB1871E96300D9D37B /* EZRecorder.m */; };
|
||||
9417A9CB1871E96300D9D37B /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9BC1871E96300D9D37B /* TPCircularBuffer.c */; };
|
||||
9417A9CC1871E96300D9D37B /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9BF1871E96300D9D37B /* CHANGELOG */; };
|
||||
9417A9CD1871E96300D9D37B /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9C01871E96300D9D37B /* VERSION */; };
|
||||
9417A9D01871E97D00D9D37B /* FFTViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9CF1871E97D00D9D37B /* FFTViewController.m */; };
|
||||
9417A9D21871EA5900D9D37B /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A9D11871EA5900D9D37B /* Accelerate.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
9417A9911871E88300D9D37B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9417A9601871E88300D9D37B /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 9417A9671871E88300D9D37B;
|
||||
remoteInfo = EZAudioFFTExample;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
9417A9681871E88300D9D37B /* EZAudioFFTExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioFFTExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9417A96B1871E88300D9D37B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
9417A96D1871E88300D9D37B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
9417A96F1871E88300D9D37B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
9417A9731871E88300D9D37B /* EZAudioFFTExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioFFTExample-Info.plist"; sourceTree = "<group>"; };
|
||||
9417A9751871E88300D9D37B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
9417A9771871E88300D9D37B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
9417A9791871E88300D9D37B /* EZAudioFFTExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "EZAudioFFTExample-Prefix.pch"; sourceTree = "<group>"; };
|
||||
9417A97A1871E88300D9D37B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
9417A97B1871E88300D9D37B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
9417A97E1871E88300D9D37B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = "<group>"; };
|
||||
9417A9811871E88300D9D37B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPad.storyboard; sourceTree = "<group>"; };
|
||||
9417A9861871E88300D9D37B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
9417A98C1871E88300D9D37B /* EZAudioFFTExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EZAudioFFTExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9417A98D1871E88300D9D37B /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
9417A9951871E88300D9D37B /* EZAudioFFTExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioFFTExampleTests-Info.plist"; sourceTree = "<group>"; };
|
||||
9417A9971871E88300D9D37B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
9417A9991871E88300D9D37B /* EZAudioFFTExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFTExampleTests.m; sourceTree = "<group>"; };
|
||||
9417A9A31871E89500D9D37B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
9417A9A51871E8A100D9D37B /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
|
||||
9417A9A81871E96300D9D37B /* AEFloatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEFloatConverter.h; sourceTree = "<group>"; };
|
||||
9417A9A91871E96300D9D37B /* AEFloatConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AEFloatConverter.m; sourceTree = "<group>"; };
|
||||
9417A9AA1871E96300D9D37B /* EZAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudio.h; sourceTree = "<group>"; };
|
||||
9417A9AB1871E96300D9D37B /* EZAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudio.m; sourceTree = "<group>"; };
|
||||
9417A9AC1871E96300D9D37B /* EZAudioFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFile.h; sourceTree = "<group>"; };
|
||||
9417A9AD1871E96300D9D37B /* EZAudioFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFile.m; sourceTree = "<group>"; };
|
||||
9417A9AE1871E96300D9D37B /* EZAudioPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlot.h; sourceTree = "<group>"; };
|
||||
9417A9AF1871E96300D9D37B /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
9417A9B01871E96300D9D37B /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
9417A9B11871E96300D9D37B /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
9417A9B21871E96300D9D37B /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
9417A9B31871E96300D9D37B /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
9417A9B41871E96300D9D37B /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
9417A9B51871E96300D9D37B /* EZMicrophone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZMicrophone.m; sourceTree = "<group>"; };
|
||||
9417A9B61871E96300D9D37B /* EZOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZOutput.h; sourceTree = "<group>"; };
|
||||
9417A9B71871E96300D9D37B /* EZOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZOutput.m; sourceTree = "<group>"; };
|
||||
9417A9B81871E96300D9D37B /* EZPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZPlot.h; sourceTree = "<group>"; };
|
||||
9417A9B91871E96300D9D37B /* EZPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZPlot.m; sourceTree = "<group>"; };
|
||||
9417A9BA1871E96300D9D37B /* EZRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZRecorder.h; sourceTree = "<group>"; };
|
||||
9417A9BB1871E96300D9D37B /* EZRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZRecorder.m; sourceTree = "<group>"; };
|
||||
9417A9BC1871E96300D9D37B /* TPCircularBuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = TPCircularBuffer.c; sourceTree = "<group>"; };
|
||||
9417A9BD1871E96300D9D37B /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
9417A9BF1871E96300D9D37B /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
9417A9C01871E96300D9D37B /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
9417A9CE1871E97D00D9D37B /* FFTViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FFTViewController.h; sourceTree = "<group>"; };
|
||||
9417A9CF1871E97D00D9D37B /* FFTViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FFTViewController.m; sourceTree = "<group>"; };
|
||||
9417A9D11871EA5900D9D37B /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
9417A9651871E88300D9D37B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9D21871EA5900D9D37B /* Accelerate.framework in Frameworks */,
|
||||
9417A9A61871E8A100D9D37B /* GLKit.framework in Frameworks */,
|
||||
9417A9A41871E89500D9D37B /* AudioToolbox.framework in Frameworks */,
|
||||
9417A96E1871E88300D9D37B /* CoreGraphics.framework in Frameworks */,
|
||||
9417A9701871E88300D9D37B /* UIKit.framework in Frameworks */,
|
||||
9417A96C1871E88300D9D37B /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9417A9891871E88300D9D37B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A98E1871E88300D9D37B /* XCTest.framework in Frameworks */,
|
||||
9417A9901871E88300D9D37B /* UIKit.framework in Frameworks */,
|
||||
9417A98F1871E88300D9D37B /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
9417A95F1871E88300D9D37B = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9711871E88300D9D37B /* EZAudioFFTExample */,
|
||||
9417A9931871E88300D9D37B /* EZAudioFFTExampleTests */,
|
||||
9417A96A1871E88300D9D37B /* Frameworks */,
|
||||
9417A9691871E88300D9D37B /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9691871E88300D9D37B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9681871E88300D9D37B /* EZAudioFFTExample.app */,
|
||||
9417A98C1871E88300D9D37B /* EZAudioFFTExampleTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A96A1871E88300D9D37B /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9D11871EA5900D9D37B /* Accelerate.framework */,
|
||||
9417A9A51871E8A100D9D37B /* GLKit.framework */,
|
||||
9417A9A31871E89500D9D37B /* AudioToolbox.framework */,
|
||||
9417A96B1871E88300D9D37B /* Foundation.framework */,
|
||||
9417A96D1871E88300D9D37B /* CoreGraphics.framework */,
|
||||
9417A96F1871E88300D9D37B /* UIKit.framework */,
|
||||
9417A98D1871E88300D9D37B /* XCTest.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9711871E88300D9D37B /* EZAudioFFTExample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9A71871E96300D9D37B /* EZAudio */,
|
||||
9417A97A1871E88300D9D37B /* AppDelegate.h */,
|
||||
9417A97B1871E88300D9D37B /* AppDelegate.m */,
|
||||
9417A97D1871E88300D9D37B /* Main_iPhone.storyboard */,
|
||||
9417A9801871E88300D9D37B /* Main_iPad.storyboard */,
|
||||
9417A9CE1871E97D00D9D37B /* FFTViewController.h */,
|
||||
9417A9CF1871E97D00D9D37B /* FFTViewController.m */,
|
||||
9417A9861871E88300D9D37B /* Images.xcassets */,
|
||||
9417A9721871E88300D9D37B /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioFFTExample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9721871E88300D9D37B /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9731871E88300D9D37B /* EZAudioFFTExample-Info.plist */,
|
||||
9417A9741871E88300D9D37B /* InfoPlist.strings */,
|
||||
9417A9771871E88300D9D37B /* main.m */,
|
||||
9417A9791871E88300D9D37B /* EZAudioFFTExample-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9931871E88300D9D37B /* EZAudioFFTExampleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9991871E88300D9D37B /* EZAudioFFTExampleTests.m */,
|
||||
9417A9941871E88300D9D37B /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioFFTExampleTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9941871E88300D9D37B /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9951871E88300D9D37B /* EZAudioFFTExampleTests-Info.plist */,
|
||||
9417A9961871E88300D9D37B /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9A71871E96300D9D37B /* EZAudio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9A81871E96300D9D37B /* AEFloatConverter.h */,
|
||||
9417A9A91871E96300D9D37B /* AEFloatConverter.m */,
|
||||
9417A9AA1871E96300D9D37B /* EZAudio.h */,
|
||||
9417A9AB1871E96300D9D37B /* EZAudio.m */,
|
||||
9417A9AC1871E96300D9D37B /* EZAudioFile.h */,
|
||||
9417A9AD1871E96300D9D37B /* EZAudioFile.m */,
|
||||
9417A9AE1871E96300D9D37B /* EZAudioPlot.h */,
|
||||
9417A9AF1871E96300D9D37B /* EZAudioPlot.m */,
|
||||
9417A9B01871E96300D9D37B /* EZAudioPlotGL.h */,
|
||||
9417A9B11871E96300D9D37B /* EZAudioPlotGL.m */,
|
||||
9417A9B21871E96300D9D37B /* EZAudioPlotGLKViewController.h */,
|
||||
9417A9B31871E96300D9D37B /* EZAudioPlotGLKViewController.m */,
|
||||
9417A9B41871E96300D9D37B /* EZMicrophone.h */,
|
||||
9417A9B51871E96300D9D37B /* EZMicrophone.m */,
|
||||
9417A9B61871E96300D9D37B /* EZOutput.h */,
|
||||
9417A9B71871E96300D9D37B /* EZOutput.m */,
|
||||
9417A9B81871E96300D9D37B /* EZPlot.h */,
|
||||
9417A9B91871E96300D9D37B /* EZPlot.m */,
|
||||
9417A9BA1871E96300D9D37B /* EZRecorder.h */,
|
||||
9417A9BB1871E96300D9D37B /* EZRecorder.m */,
|
||||
9417A9BC1871E96300D9D37B /* TPCircularBuffer.c */,
|
||||
9417A9BD1871E96300D9D37B /* TPCircularBuffer.h */,
|
||||
9417A9BE1871E96300D9D37B /* VERSION */,
|
||||
);
|
||||
name = EZAudio;
|
||||
path = ../../../../EZAudio;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9BE1871E96300D9D37B /* VERSION */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9BF1871E96300D9D37B /* CHANGELOG */,
|
||||
9417A9C01871E96300D9D37B /* VERSION */,
|
||||
);
|
||||
path = VERSION;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
9417A9671871E88300D9D37B /* EZAudioFFTExample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9417A99D1871E88300D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExample" */;
|
||||
buildPhases = (
|
||||
9417A9641871E88300D9D37B /* Sources */,
|
||||
9417A9651871E88300D9D37B /* Frameworks */,
|
||||
9417A9661871E88300D9D37B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = EZAudioFFTExample;
|
||||
productName = EZAudioFFTExample;
|
||||
productReference = 9417A9681871E88300D9D37B /* EZAudioFFTExample.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
9417A98B1871E88300D9D37B /* EZAudioFFTExampleTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9417A9A01871E88300D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExampleTests" */;
|
||||
buildPhases = (
|
||||
9417A9881871E88300D9D37B /* Sources */,
|
||||
9417A9891871E88300D9D37B /* Frameworks */,
|
||||
9417A98A1871E88300D9D37B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
9417A9921871E88300D9D37B /* PBXTargetDependency */,
|
||||
);
|
||||
name = EZAudioFFTExampleTests;
|
||||
productName = EZAudioFFTExampleTests;
|
||||
productReference = 9417A98C1871E88300D9D37B /* EZAudioFFTExampleTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
9417A9601871E88300D9D37B /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Syed Haris Ali";
|
||||
TargetAttributes = {
|
||||
9417A98B1871E88300D9D37B = {
|
||||
TestTargetID = 9417A9671871E88300D9D37B;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 9417A9631871E88300D9D37B /* Build configuration list for PBXProject "EZAudioFFTExample" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 9417A95F1871E88300D9D37B;
|
||||
productRefGroup = 9417A9691871E88300D9D37B /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
9417A9671871E88300D9D37B /* EZAudioFFTExample */,
|
||||
9417A98B1871E88300D9D37B /* EZAudioFFTExampleTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
9417A9661871E88300D9D37B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9821871E88300D9D37B /* Main_iPad.storyboard in Resources */,
|
||||
9417A9871871E88300D9D37B /* Images.xcassets in Resources */,
|
||||
9417A97F1871E88300D9D37B /* Main_iPhone.storyboard in Resources */,
|
||||
9417A9CD1871E96300D9D37B /* VERSION in Resources */,
|
||||
9417A9761871E88300D9D37B /* InfoPlist.strings in Resources */,
|
||||
9417A9CC1871E96300D9D37B /* CHANGELOG in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9417A98A1871E88300D9D37B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9981871E88300D9D37B /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
9417A9641871E88300D9D37B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9CB1871E96300D9D37B /* TPCircularBuffer.c in Sources */,
|
||||
9417A9C81871E96300D9D37B /* EZOutput.m in Sources */,
|
||||
9417A9C61871E96300D9D37B /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
9417A9C11871E96300D9D37B /* AEFloatConverter.m in Sources */,
|
||||
9417A97C1871E88300D9D37B /* AppDelegate.m in Sources */,
|
||||
9417A9C41871E96300D9D37B /* EZAudioPlot.m in Sources */,
|
||||
9417A9C31871E96300D9D37B /* EZAudioFile.m in Sources */,
|
||||
9417A9D01871E97D00D9D37B /* FFTViewController.m in Sources */,
|
||||
9417A9C51871E96300D9D37B /* EZAudioPlotGL.m in Sources */,
|
||||
9417A9781871E88300D9D37B /* main.m in Sources */,
|
||||
9417A9C91871E96300D9D37B /* EZPlot.m in Sources */,
|
||||
9417A9C71871E96300D9D37B /* EZMicrophone.m in Sources */,
|
||||
9417A9CA1871E96300D9D37B /* EZRecorder.m in Sources */,
|
||||
9417A9C21871E96300D9D37B /* EZAudio.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9417A9881871E88300D9D37B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A99A1871E88300D9D37B /* EZAudioFFTExampleTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
9417A9921871E88300D9D37B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 9417A9671871E88300D9D37B /* EZAudioFFTExample */;
|
||||
targetProxy = 9417A9911871E88300D9D37B /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
9417A9741871E88300D9D37B /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A9751871E88300D9D37B /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A97D1871E88300D9D37B /* Main_iPhone.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A97E1871E88300D9D37B /* Base */,
|
||||
);
|
||||
name = Main_iPhone.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9801871E88300D9D37B /* Main_iPad.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A9811871E88300D9D37B /* Base */,
|
||||
);
|
||||
name = Main_iPad.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9961871E88300D9D37B /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A9971871E88300D9D37B /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
9417A99B1871E88300D9D37B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9417A99C1871E88300D9D37B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9417A99E1871E88300D9D37B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExample/EZAudioFFTExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9417A99F1871E88300D9D37B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExample/EZAudioFFTExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9417A9A11871E88300D9D37B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioFFTExample.app/EZAudioFFTExample";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "EZAudioFFTExampleTests/EZAudioFFTExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9417A9A21871E88300D9D37B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioFFTExample.app/EZAudioFFTExample";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExampleTests/EZAudioFFTExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
9417A9631871E88300D9D37B /* Build configuration list for PBXProject "EZAudioFFTExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9417A99B1871E88300D9D37B /* Debug */,
|
||||
9417A99C1871E88300D9D37B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9417A99D1871E88300D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9417A99E1871E88300D9D37B /* Debug */,
|
||||
9417A99F1871E88300D9D37B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
9417A9A01871E88300D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExampleTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9417A9A11871E88300D9D37B /* Debug */,
|
||||
9417A9A21871E88300D9D37B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 9417A9601871E88300D9D37B /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 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 <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 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 "AppDelegate.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
// Override point for customization after application launch.
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application
|
||||
{
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
{
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
{
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
@end
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FFTViewController" sceneMemberID="viewController">
|
||||
<connections>
|
||||
<outlet property="audioPlotFreq" destination="DSa-vR-ySS" id="JP5-yB-Jqo"/>
|
||||
<outlet property="audioPlotTime" destination="Za4-u7-8h1" id="ox5-AQ-DaQ"/>
|
||||
<outlet property="view" destination="e0f-bI-AGV" id="oLT-9I-NIK"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<view contentMode="scaleToFill" id="e0f-bI-AGV">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Za4-u7-8h1" customClass="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="284"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="284" id="lUL-Pa-hHs"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="DSa-vR-ySS" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="284" width="320" height="284"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="lessThanOrEqual" priority="86" constant="284" id="aNL-Q8-MOw"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="DSa-vR-ySS" secondAttribute="trailing" id="FOI-4L-3b8"/>
|
||||
<constraint firstItem="DSa-vR-ySS" firstAttribute="leading" secondItem="e0f-bI-AGV" secondAttribute="leading" id="LTm-AL-Oqz"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Za4-u7-8h1" secondAttribute="trailing" id="SLb-8B-cNK"/>
|
||||
<constraint firstItem="DSa-vR-ySS" firstAttribute="top" secondItem="Za4-u7-8h1" secondAttribute="bottom" id="cef-HS-Uiw"/>
|
||||
<constraint firstItem="Za4-u7-8h1" firstAttribute="leading" secondItem="e0f-bI-AGV" secondAttribute="leading" id="fe0-ef-NkA"/>
|
||||
<constraint firstAttribute="bottom" secondItem="DSa-vR-ySS" secondAttribute="bottom" id="oDL-Qh-0Ei"/>
|
||||
<constraint firstItem="Za4-u7-8h1" firstAttribute="top" secondItem="e0f-bI-AGV" secondAttribute="top" id="zKR-dO-8wP"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar" statusBarStyle="blackOpaque"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="vXZ-lx-hvc">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="ufC-wZ-h7g">
|
||||
<objects>
|
||||
<viewController id="vXZ-lx-hvc" customClass="FFTViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="SDG-bW-D9N"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="Ghx-UD-SsY"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0IN-AU-L5p" customClass="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="284"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="284" id="evV-xs-Een"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tRL-re-aMl" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="284" width="320" height="284"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="lessThanOrEqual" priority="86" constant="284" id="G4S-hR-Wmj"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="tRL-re-aMl" secondAttribute="bottom" id="6Xx-qX-MTy"/>
|
||||
<constraint firstItem="0IN-AU-L5p" firstAttribute="top" secondItem="kh9-bI-dsS" secondAttribute="top" id="83g-qr-GsR"/>
|
||||
<constraint firstAttribute="trailing" secondItem="tRL-re-aMl" secondAttribute="trailing" id="eTI-rb-OrM"/>
|
||||
<constraint firstAttribute="trailing" secondItem="0IN-AU-L5p" secondAttribute="trailing" id="iL0-3u-CeX"/>
|
||||
<constraint firstItem="0IN-AU-L5p" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leading" id="j4O-TP-2Vf"/>
|
||||
<constraint firstItem="tRL-re-aMl" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leading" id="jtj-vj-fPm"/>
|
||||
<constraint firstItem="tRL-re-aMl" firstAttribute="top" secondItem="0IN-AU-L5p" secondAttribute="bottom" id="pZY-xg-Sb9"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="audioPlotFreq" destination="tRL-re-aMl" id="s8q-c6-u9E"/>
|
||||
<outlet property="audioPlotTime" destination="0IN-AU-L5p" id="tej-Kb-ycI"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination" type="retina4"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.sha.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main_iPhone</string>
|
||||
<key>UIMainStoryboardFile~ipad</key>
|
||||
<string>Main_iPad</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#import <Availability.h>
|
||||
|
||||
#ifndef __IPHONE_5_0
|
||||
#warning "This project uses features only available in iOS SDK 5.0 and later."
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// FFTViewController.h
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 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 <UIKit/UIKit.h>
|
||||
|
||||
/**
|
||||
EZAudio
|
||||
*/
|
||||
#import "EZAudio.h"
|
||||
|
||||
/**
|
||||
Accelerate
|
||||
*/
|
||||
#import <Accelerate/Accelerate.h>
|
||||
|
||||
/**
|
||||
The FFTViewController demonstrates how to use the Accelerate framework to calculate the real-time FFT of audio data provided by an EZAudioMicrophone.
|
||||
*/
|
||||
@interface FFTViewController : UIViewController <EZMicrophoneDelegate>
|
||||
|
||||
#pragma mark - Components
|
||||
/**
|
||||
EZAudioPlot for frequency plot
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlot *audioPlotFreq;
|
||||
|
||||
/**
|
||||
EZAudioPlot for time plot
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlotGL *audioPlotTime;
|
||||
|
||||
/**
|
||||
Microphone
|
||||
*/
|
||||
@property (nonatomic,strong) EZMicrophone *microphone;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,156 @@
|
||||
//
|
||||
// FFTViewController.m
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 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 "FFTViewController.h"
|
||||
|
||||
@interface FFTViewController (){
|
||||
COMPLEX_SPLIT _A;
|
||||
FFTSetup _FFTSetup;
|
||||
BOOL _isFFTSetup;
|
||||
vDSP_Length _log2n;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation FFTViewController
|
||||
@synthesize audioPlotFreq;
|
||||
@synthesize audioPlotTime;
|
||||
@synthesize microphone;
|
||||
|
||||
#pragma mark - Customize the Audio Plot
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
/*
|
||||
Customizing the audio plot's look
|
||||
*/
|
||||
// Setup time domain audio plot
|
||||
self.audioPlotTime.backgroundColor = [UIColor colorWithRed: 0.569 green: 0.82 blue: 0.478 alpha: 1];
|
||||
self.audioPlotTime.color = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
self.audioPlotTime.shouldFill = YES;
|
||||
self.audioPlotTime.shouldMirror = YES;
|
||||
self.audioPlotTime.plotType = EZPlotTypeRolling;
|
||||
|
||||
// Setup frequency domain audio plot
|
||||
self.audioPlotFreq.backgroundColor = [UIColor colorWithRed: 0.984 green: 0.471 blue: 0.525 alpha: 1];
|
||||
self.audioPlotFreq.color = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
self.audioPlotFreq.shouldFill = YES;
|
||||
self.audioPlotFreq.plotType = EZPlotTypeBuffer;
|
||||
|
||||
/*
|
||||
Start the microphone
|
||||
*/
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self
|
||||
startsImmediately:YES];
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - FFT
|
||||
/**
|
||||
Adapted from http://batmobile.blogs.ilrt.org/fourier-transforms-on-an-iphone/
|
||||
*/
|
||||
-(void)createFFTWithBufferSize:(float)bufferSize withAudioData:(float*)data {
|
||||
|
||||
// Setup the length
|
||||
_log2n = log2f(bufferSize);
|
||||
|
||||
// Calculate the weights array. This is a one-off operation.
|
||||
_FFTSetup = vDSP_create_fftsetup(_log2n, FFT_RADIX2);
|
||||
|
||||
// For an FFT, numSamples must be a power of 2, i.e. is always even
|
||||
int nOver2 = bufferSize/2;
|
||||
|
||||
// Populate *window with the values for a hamming window function
|
||||
float *window = (float *)malloc(sizeof(float)*bufferSize);
|
||||
vDSP_hamm_window(window, bufferSize, 0);
|
||||
// Window the samples
|
||||
vDSP_vmul(data, 1, window, 1, data, 1, bufferSize);
|
||||
free(window);
|
||||
|
||||
// Define complex buffer
|
||||
_A.realp = (float *) malloc(nOver2*sizeof(float));
|
||||
_A.imagp = (float *) malloc(nOver2*sizeof(float));
|
||||
|
||||
}
|
||||
|
||||
-(void)updateFFTWithBufferSize:(float)bufferSize withAudioData:(float*)data {
|
||||
|
||||
// For an FFT, numSamples must be a power of 2, i.e. is always even
|
||||
int nOver2 = bufferSize/2;
|
||||
|
||||
// Pack samples:
|
||||
// C(re) -> A[n], C(im) -> A[n+1]
|
||||
vDSP_ctoz((COMPLEX*)data, 2, &_A, 1, nOver2);
|
||||
|
||||
// Perform a forward FFT using fftSetup and A
|
||||
// Results are returned in A
|
||||
vDSP_fft_zrip(_FFTSetup, &_A, 1, _log2n, FFT_FORWARD);
|
||||
|
||||
// Convert COMPLEX_SPLIT A result to magnitudes
|
||||
float amp[nOver2];
|
||||
float maxMag = 0;
|
||||
|
||||
for(int i=0; i<nOver2; i++) {
|
||||
// Calculate the magnitude
|
||||
float mag = _A.realp[i]*_A.realp[i]+_A.imagp[i]*_A.imagp[i];
|
||||
maxMag = mag > maxMag ? mag : maxMag;
|
||||
}
|
||||
for(int i=0; i<nOver2; i++) {
|
||||
// Calculate the magnitude
|
||||
float mag = _A.realp[i]*_A.realp[i]+_A.imagp[i]*_A.imagp[i];
|
||||
// Bind the value to be less than 1.0 to fit in the graph
|
||||
amp[i] = [EZAudio MAP:mag leftMin:0.0 leftMax:maxMag rightMin:0.0 rightMax:1.0];
|
||||
}
|
||||
|
||||
// Update the frequency domain plot
|
||||
[self.audioPlotFreq updateBuffer:amp
|
||||
withBufferSize:nOver2];
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
-(void) microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
// Update time domain plot
|
||||
[self.audioPlotTime updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
|
||||
// Setup the FFT if it's not already setup
|
||||
if( !_isFFTSetup ){
|
||||
[self createFFTWithBufferSize:bufferSize withAudioData:buffer[0]];
|
||||
_isFFTSetup = YES;
|
||||
}
|
||||
|
||||
// Get the FFT data
|
||||
[self updateFFTWithBufferSize:bufferSize withAudioData:buffer[0]];
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "iphone",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "retina4",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"orientation" : "landscape",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "landscape",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// main.m
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.sha.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// EZAudioFFTExampleTests.m
|
||||
// EZAudioFFTExampleTests
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface EZAudioFFTExampleTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation EZAudioFFTExampleTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testExample
|
||||
{
|
||||
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@end
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -5,6 +5,23 @@
|
||||
// Created by Syed Haris Ali on 12/20/13.
|
||||
// Copyright (c) 2013 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 <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@@ -5,6 +5,23 @@
|
||||
// Created by Syed Haris Ali on 12/20/13.
|
||||
// Copyright (c) 2013 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 "AppDelegate.h"
|
||||
|
||||
|
||||
+17
@@ -5,6 +5,23 @@
|
||||
// Created by Syed Haris Ali on 12/20/13.
|
||||
// Copyright (c) 2013 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 <UIKit/UIKit.h>
|
||||
|
||||
|
||||
+17
@@ -5,6 +5,23 @@
|
||||
// Created by Syed Haris Ali on 12/20/13.
|
||||
// Copyright (c) 2013 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 "PassThroughViewController.h"
|
||||
|
||||
|
||||
+7
-4
@@ -132,11 +132,14 @@
|
||||
// Stop playback
|
||||
[[EZOutput sharedOutput] stopPlayback];
|
||||
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL];
|
||||
self.audioFile.audioFileDelegate = self;
|
||||
self.eof = NO;
|
||||
self.filePathLabel.text = filePathURL.lastPathComponent;
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL];
|
||||
self.audioFile.audioFileDelegate = self;
|
||||
self.eof = NO;
|
||||
self.filePathLabel.text = filePathURL.lastPathComponent;
|
||||
self.framePositionSlider.maximumValue = (float)self.audioFile.totalFrames;
|
||||
|
||||
// Set the client format from the EZAudioFile on the output
|
||||
[[EZOutput sharedOutput] setAudioStreamBasicDescription:self.audioFile.clientFormat];
|
||||
|
||||
// Plot the whole waveform
|
||||
self.audioPlot.plotType = EZPlotTypeBuffer;
|
||||
|
||||
@@ -43,7 +43,9 @@ An OpenGL-based, GPU-accelerated audio waveform plot capable of visualizing any
|
||||
|
||||
##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. Documentation will be hosted very soon on Cocoadocs!
|
||||
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.
|
||||
|
||||
### Example Projects
|
||||
|
||||
**_EZAudioCoreGraphicsWaveformExample_**
|
||||
|
||||
@@ -69,6 +71,16 @@ Shows how to use the `EZAudioFile` and `EZAudioPlot` to display the audio wavefo
|
||||
|
||||
Shows how to use the `EZMicrophone`, `EZOutput`, and the `EZAudioPlotGL` to pass the microphone input to the output for playback while displaying the audio waveform (as a buffer or rolling plot) in real-time.
|
||||
|
||||
**_EZAudioFFTExample_**
|
||||
|
||||
Shows how to calculate the real-time FFT of the audio data coming from the `EZMicrophone` and the Accelerate framework. The audio data is plotted using the `EZAudioPlotGL` for the time domain plot and the `EZAudioPlot` for the frequency domain plot.
|
||||
|
||||

|
||||
|
||||
### Documentation
|
||||
The official documentation for EZAudio can be found here: http://cocoadocs.org/docsets/EZAudio/0.0.2/
|
||||
<br>You can also generate the docset yourself using appledocs by running the appledocs on the EZAudio source folder.
|
||||
|
||||
##Getting Started
|
||||
*To see the full project page, interactive Getting Started guide, and Documentation go here:*
|
||||
http://syedharisali.com/projects/EZAudio/getting-started
|
||||
@@ -98,7 +110,16 @@ To begin using `EZAudio` you must first make sure you have the proper build requ
|
||||
- GLKit
|
||||
|
||||
###Adding To Project
|
||||
See full Getting Started guide: http://syedharisali.com/projects/EZAudio/getting-started
|
||||
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.0.2'
|
||||
`
|
||||
|
||||
2.) Alternatively, you could clone or fork this repo and just drag and drop the source into your project.
|
||||
|
||||
*For more information see main project page:*
|
||||
http://syedharisali.com/projects/EZAudio/getting-started
|
||||
|
||||
##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).
|
||||
@@ -530,7 +551,7 @@ Provides an audio waveform plot that uses OpenGL to perform the drawing. The API
|
||||
|
||||
####Creating An OpenGL Audio Plot
|
||||
|
||||
You can create an audio plot in the interface builder by dragging in a UIView on iOS or an NSOpenGLView on OSX onto your content area. Then change the custom class of the UIView/NSView to `EZAudioPlot`.
|
||||
You can create an audio plot in the interface builder by dragging in a UIView on iOS or an NSOpenGLView on OSX onto your content area. Then change the custom class of the UIView/NSView to `EZAudioPlotGL`.
|
||||
See full Getting Started page for how to: http://syedharisali.com/projects/EZAudio/getting-started
|
||||
|
||||
Alternatively, you can could create the `EZAudioPlotGL` programmatically
|
||||
@@ -591,3 +612,8 @@ EZAudio is available under the MIT license. See the LICENSE file for more info.
|
||||
Syed Haris Ali<br>
|
||||
www.syedharisali.com<br>
|
||||
syedhali07[at]gmail.com
|
||||
|
||||
##Acknowledgements
|
||||
EZAudio could not have been created without the invaluable help of:
|
||||
- <a href="http://atastypixel.com/blog/">Michael Tyson</a> for creating the <a href="http://atastypixel.com/blog/a-simple-fast-circular-buffer-implementation-for-audio-processing/">TPCircularBuffer</a> and the <a href="http://theamazingaudioengine.com/">Amazing Audio Engine</a>'s `AEFloatConverter`.
|
||||
- Chris Adamson and Kevin Avila for writing the amazing book <a href="http://www.amazon.com/Learning-Core-Audio-Hands-On-Programming/dp/0321636848">Learning Core Audio</a>
|
||||
|
||||
Reference in New Issue
Block a user