Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 34dc468f16 |
+5
-3
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "EZAudio"
|
||||
s.version = "1.1.2"
|
||||
s.version = "0.9.1"
|
||||
s.summary = "A simple, intuitive audio framework for iOS and OSX useful for anyone doing audio processing and/or audio-based visualizations."
|
||||
s.homepage = "https://github.com/syedhali/EZAudio"
|
||||
s.screenshots = "https://s3-us-west-1.amazonaws.com/ezaudio-media/EZAudioSummary.png"
|
||||
@@ -10,10 +10,11 @@ Pod::Spec.new do |s|
|
||||
s.osx.deployment_target = '10.8'
|
||||
s.source = { :git => "https://github.com/syedhali/EZAudio.git", :tag => s.version }
|
||||
s.exclude_files = [ 'EZAudio/VERSION', 'EZAudio/TPCircularBuffer.{h,c}' ]
|
||||
s.ios.frameworks = 'AudioToolbox','AVFoundation','GLKit', 'Accelerate'
|
||||
s.osx.frameworks = 'AudioToolbox','AudioUnit','CoreAudio','QuartzCore','OpenGL','GLKit', 'Accelerate'
|
||||
s.ios.frameworks = 'AudioToolbox','AVFoundation','GLKit'
|
||||
s.osx.frameworks = 'AudioToolbox','AudioUnit','CoreAudio','QuartzCore','OpenGL','GLKit'
|
||||
s.requires_arc = true;
|
||||
s.default_subspec = 'Full'
|
||||
|
||||
s.subspec 'Core' do |core|
|
||||
core.source_files = 'EZAudio/*.{h,m,c}'
|
||||
end
|
||||
@@ -22,4 +23,5 @@ Pod::Spec.new do |s|
|
||||
full.dependency 'TPCircularBuffer', '~> 0.0'
|
||||
full.dependency 'EZAudio/Core'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
#pragma mark - Utility Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#import "EZAudioFFT.h"
|
||||
#import "EZAudioFloatConverter.h"
|
||||
#import "EZAudioFloatData.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
+3
-20
@@ -1,27 +1,10 @@
|
||||
//
|
||||
// EZAudioDevice.h
|
||||
// EZAudio
|
||||
// MicrophoneTest
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/25/15.
|
||||
// Created by Syed Haris Ali on 4/3/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
@@ -184,4 +167,4 @@
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
@end
|
||||
+2
-19
@@ -1,27 +1,10 @@
|
||||
//
|
||||
// EZAudioDevice.m
|
||||
// EZAudio
|
||||
// MicrophoneTest
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/25/15.
|
||||
// Created by Syed Haris Ali on 4/3/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "EZAudioDevice.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
@@ -1,392 +0,0 @@
|
||||
//
|
||||
// EZAudioFFT.h
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 7/10/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Accelerate/Accelerate.h>
|
||||
|
||||
@class EZAudioFFT;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFFTDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioFFTDelegate provides event callbacks for the EZAudioFFT (and subclasses such as the EZAudioFFTRolling) whenvever the FFT is computed.
|
||||
*/
|
||||
@protocol EZAudioFFTDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Getting FFT Output Data
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Triggered when the EZAudioFFT computes an FFT from a buffer of input data. Provides an array of float data representing the computed FFT.
|
||||
@param fft The EZAudioFFT instance that triggered the event.
|
||||
@param fftData A float pointer representing the float array of FFT data.
|
||||
@param bufferSize A vDSP_Length (unsigned long) representing the length of the float array.
|
||||
*/
|
||||
- (void) fft:(EZAudioFFT *)fft
|
||||
updatedWithFFTData:(float *)fftData
|
||||
bufferSize:(vDSP_Length)bufferSize;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFFT
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioFFT provides a base class to quickly calculate the FFT of incoming audio data using the Accelerate framework. In addition, the EZAudioFFT contains an EZAudioFFTDelegate to receive an event anytime an FFT is computed.
|
||||
*/
|
||||
@interface EZAudioFFT : NSObject
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes an EZAudioFFT (or subclass) instance with a maximum buffer size and sample rate. The sample rate is used specifically to calculate the `maxFrequency` property. If you don't care about the `maxFrequency` property then you can set the sample rate to 0.
|
||||
@param maximumBufferSize A vDSP_Length (unsigned long) representing the maximum length of the incoming audio data.
|
||||
@param sampleRate A float representing the sample rate of the incoming audio data.
|
||||
|
||||
@return A newly created EZAudioFFT (or subclass) instance.
|
||||
*/
|
||||
- (instancetype)initWithMaximumBufferSize:(vDSP_Length)maximumBufferSize
|
||||
sampleRate:(float)sampleRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes an EZAudioFFT (or subclass) instance with a maximum buffer size, sample rate, and EZAudioFFTDelegate. The sample rate is used specifically to calculate the `maxFrequency` property. If you don't care about the `maxFrequency` property then you can set the sample rate to 0. The EZAudioFFTDelegate will act as a receive to get an event whenever the FFT is calculated.
|
||||
@param maximumBufferSize A vDSP_Length (unsigned long) representing the maximum length of the incoming audio data.
|
||||
@param sampleRate A float representing the sample rate of the incoming audio data.
|
||||
@param delegate An EZAudioFFTDelegate to receive an event whenever the FFT is calculated.
|
||||
@return A newly created EZAudioFFT (or subclass) instance.
|
||||
*/
|
||||
- (instancetype)initWithMaximumBufferSize:(vDSP_Length)maximumBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to initialize an EZAudioFFT (or subclass) instance with a maximum buffer size and sample rate. The sample rate is used specifically to calculate the `maxFrequency` property. If you don't care about the `maxFrequency` property then you can set the sample rate to 0.
|
||||
@param maximumBufferSize A vDSP_Length (unsigned long) representing the maximum length of the incoming audio data.
|
||||
@param sampleRate A float representing the sample rate of the incoming audio data.
|
||||
@return A newly created EZAudioFFT (or subclass) instance.
|
||||
*/
|
||||
+ (instancetype)fftWithMaximumBufferSize:(vDSP_Length)maximumBufferSize
|
||||
sampleRate:(float)sampleRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to initialize an EZAudioFFT (or subclass) instance with a maximum buffer size, sample rate, and EZAudioFFTDelegate. The sample rate is used specifically to calculate the `maxFrequency` property. If you don't care about the `maxFrequency` property then you can set the sample rate to 0. The EZAudioFFTDelegate will act as a receive to get an event whenever the FFT is calculated.
|
||||
@param maximumBufferSize A vDSP_Length (unsigned long) representing the maximum length of the incoming audio data.
|
||||
@param sampleRate A float representing the sample rate of the incoming audio data.
|
||||
@param delegate An EZAudioFFTDelegate to receive an event whenever the FFT is calculated.
|
||||
@return A newly created EZAudioFFT (or subclass) instance.
|
||||
*/
|
||||
+ (instancetype)fftWithMaximumBufferSize:(vDSP_Length)maximumBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Properties
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
An EZAudioFFTDelegate to receive an event whenever the FFT is calculated.
|
||||
*/
|
||||
@property (weak, nonatomic) id<EZAudioFFTDelegate> delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A COMPLEX_SPLIT data structure used to hold the FFT's imaginary and real components.
|
||||
*/
|
||||
@property (readonly, nonatomic) COMPLEX_SPLIT complexSplit;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A float array containing the last calculated FFT data.
|
||||
*/
|
||||
@property (readonly, nonatomic) float *fftData;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
An FFTSetup data structure used to internally calculate the FFT using Accelerate.
|
||||
*/
|
||||
@property (readonly, nonatomic) FFTSetup fftSetup;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A float array containing the last calculated inverse FFT data (the time domain signal).
|
||||
*/
|
||||
@property (readonly, nonatomic) float *inversedFFTData;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A float representing the frequency with the highest energy is the last FFT calculation.
|
||||
*/
|
||||
@property (readonly, nonatomic) float maxFrequency;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A vDSP_Length (unsigned long) representing the index of the frequency with the highest energy is the last FFT calculation.
|
||||
*/
|
||||
@property (readonly, nonatomic) vDSP_Length maxFrequencyIndex;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A float representing the magnitude of the frequency with the highest energy is the last FFT calculation.
|
||||
*/
|
||||
@property (readonly, nonatomic) float maxFrequencyMagnitude;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A vDSP_Length (unsigned long) representing the maximum buffer size. This is the maximum length the incoming audio data in the `computeFFTWithBuffer:withBufferSize` method can be.
|
||||
*/
|
||||
@property (readonly, nonatomic) vDSP_Length maximumBufferSize;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A float representing the sample rate of the incoming audio data.
|
||||
*/
|
||||
@property (readwrite, nonatomic) float sampleRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Computing The FFT
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Computes the FFT for a float array representing an incoming audio signal. This will trigger the EZAudioFFTDelegate method `fft:updatedWithFFTData:bufferSize:`.
|
||||
@param buffer A float array representing the audio data.
|
||||
@param bufferSize The length of the float array of audio data.
|
||||
@return A float array containing the computed FFT data. The length of the output will be half the incoming buffer (half the `bufferSize` argument).
|
||||
*/
|
||||
- (float *)computeFFTWithBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the frequency corresponding to an index in the last computed FFT data.
|
||||
@param index A vDSP_Length (unsigned integer) representing the index of the frequency bin value you'd like to get
|
||||
@return A float representing the frequency value at that index.
|
||||
*/
|
||||
- (float)frequencyAtIndex:(vDSP_Length)index;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the magnitude of the frequenecy corresponding to an index in the last computed FFT data.
|
||||
@param index A vDSP_Length (unsigned integer) representing the index of the frequency bin value you'd like to get
|
||||
@return A float representing the frequency magnitude value at that index.
|
||||
*/
|
||||
- (float)frequencyMagnitudeAtIndex:(vDSP_Length)index;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFFTRolling
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioFFTRolling, a subclass of EZAudioFFT, provides a class to calculate an FFT for an incoming audio signal while maintaining a history of audio data to allow much higher resolution FFTs. For instance, the EZMicrophone typically provides 512 frames at a time, but you would probably want to provide 2048 or 4096 frames for a decent looking FFT if you're trying to extract precise frequency components. You will typically be using this class for variable length FFTs instead of the EZAudioFFT base class.
|
||||
*/
|
||||
@interface EZAudioFFTRolling : EZAudioFFT
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes an EZAudioFFTRolling instance with a window size and a sample rate. The EZAudioFFTRolling has an internal EZPlotHistoryInfo data structure that writes audio data to a circular buffer and manages sliding windows of audio data to support efficient, large FFT calculations. Here you provide a window size that represents how many audio sample will be used to calculate the FFT and a float representing the sample rate of the incoming audio (can be 0 if you don't care about the `maxFrequency` property). The history buffer size in this case is the `windowSize` * 8, which is pretty good for most cases.
|
||||
@param windowSize A vDSP_Length (unsigned long) representing the size of the window (i.e. the resolution) of data that should be used to calculate the FFT. A typical value for this would be something like 1024 - 4096 (or higher for an even higher resolution FFT).
|
||||
@param sampleRate A float representing the sample rate of the incoming audio signal.
|
||||
@return A newly created EZAudioFFTRolling instance.
|
||||
*/
|
||||
- (instancetype)initWithWindowSize:(vDSP_Length)windowSize
|
||||
sampleRate:(float)sampleRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes an EZAudioFFTRolling instance with a window size, a sample rate, and an EZAudioFFTDelegate. The EZAudioFFTRolling has an internal EZPlotHistoryInfo data structure that writes audio data to a circular buffer and manages sliding windows of audio data to support efficient, large FFT calculations. Here you provide a window size that represents how many audio sample will be used to calculate the FFT, a float representing the sample rate of the incoming audio (can be 0 if you don't care about the `maxFrequency` property), and an EZAudioFFTDelegate to receive a callback anytime the FFT is calculated. The history buffer size in this case is the `windowSize` * 8, which is pretty good for most cases.
|
||||
@param windowSize A vDSP_Length (unsigned long) representing the size of the window (i.e. the resolution) of data that should be used to calculate the FFT. A typical value for this would be something like 1024 - 4096 (or higher for an even higher resolution FFT).
|
||||
@param sampleRate A float representing the sample rate of the incoming audio signal.
|
||||
@param delegate An EZAudioFFTDelegate to receive an event whenever the FFT is calculated.
|
||||
@return A newly created EZAudioFFTRolling instance.
|
||||
*/
|
||||
- (instancetype)initWithWindowSize:(vDSP_Length)windowSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes an EZAudioFFTRolling instance with a window size, a history buffer size, and a sample rate. The EZAudioFFTRolling has an internal EZPlotHistoryInfo data structure that writes audio data to a circular buffer and manages sliding windows of audio data to support efficient, large FFT calculations. Here you provide a window size that represents how many audio sample will be used to calculate the FFT, a history buffer size representing the maximum length of the sliding window's underlying circular buffer, and a float representing the sample rate of the incoming audio (can be 0 if you don't care about the `maxFrequency` property).
|
||||
@param windowSize A vDSP_Length (unsigned long) representing the size of the window (i.e. the resolution) of data that should be used to calculate the FFT. A typical value for this would be something like 1024 - 4096 (or higher for an even higher resolution FFT).
|
||||
@param historyBufferSize A vDSP_Length (unsigned long) representing the length of the history buffer. This should be AT LEAST the size of the window. A recommended value for this would be at least 8x greater than the `windowSize` argument.
|
||||
@param sampleRate A float representing the sample rate of the incoming audio signal.
|
||||
@return A newly created EZAudioFFTRolling instance.
|
||||
*/
|
||||
- (instancetype)initWithWindowSize:(vDSP_Length)windowSize
|
||||
historyBufferSize:(vDSP_Length)historyBufferSize
|
||||
sampleRate:(float)sampleRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes an EZAudioFFTRolling instance with a window size, a history buffer size, a sample rate, and an EZAudioFFTDelegate. The EZAudioFFTRolling has an internal EZPlotHistoryInfo data structure that writes audio data to a circular buffer and manages sliding windows of audio data to support efficient, large FFT calculations. Here you provide a window size that represents how many audio sample will be used to calculate the FFT, a history buffer size representing the maximum length of the sliding window's underlying circular buffer, a float representing the sample rate of the incoming audio (can be 0 if you don't care about the `maxFrequency` property), and an EZAudioFFTDelegate to receive a callback anytime the FFT is calculated.
|
||||
@param windowSize A vDSP_Length (unsigned long) representing the size of the window (i.e. the resolution) of data that should be used to calculate the FFT. A typical value for this would be something like 1024 - 4096 (or higher for an even higher resolution FFT).
|
||||
@param historyBufferSize A vDSP_Length (unsigned long) representing the length of the history buffer. This should be AT LEAST the size of the window. A recommended value for this would be at least 8x greater than the `windowSize` argument.
|
||||
@param sampleRate A float representing the sample rate of the incoming audio signal.
|
||||
@param delegate An EZAudioFFTDelegate to receive an event whenever the FFT is calculated.
|
||||
@return A newly created EZAudioFFTRolling instance.
|
||||
*/
|
||||
- (instancetype)initWithWindowSize:(vDSP_Length)windowSize
|
||||
historyBufferSize:(vDSP_Length)historyBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to initialize an EZAudioFFTRolling instance with a window size and a sample rate. The EZAudioFFTRolling has an internal EZPlotHistoryInfo data structure that writes audio data to a circular buffer and manages sliding windows of audio data to support efficient, large FFT calculations. Here you provide a window size that represents how many audio sample will be used to calculate the FFT and a float representing the sample rate of the incoming audio (can be 0 if you don't care about the `maxFrequency` property). The history buffer size in this case is the `windowSize` * 8, which is pretty good for most cases.
|
||||
@param windowSize A vDSP_Length (unsigned long) representing the size of the window (i.e. the resolution) of data that should be used to calculate the FFT. A typical value for this would be something like 1024 - 4096 (or higher for an even higher resolution FFT).
|
||||
@param sampleRate A float representing the sample rate of the incoming audio signal.
|
||||
@return A newly created EZAudioFFTRolling instance.
|
||||
*/
|
||||
+ (instancetype)fftWithWindowSize:(vDSP_Length)windowSize
|
||||
sampleRate:(float)sampleRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to initialize an EZAudioFFTRolling instance with a window size, a sample rate, and an EZAudioFFTDelegate. The EZAudioFFTRolling has an internal EZPlotHistoryInfo data structure that writes audio data to a circular buffer and manages sliding windows of audio data to support efficient, large FFT calculations. Here you provide a window size that represents how many audio sample will be used to calculate the FFT, a float representing the sample rate of the incoming audio (can be 0 if you don't care about the `maxFrequency` property), and an EZAudioFFTDelegate to receive a callback anytime the FFT is calculated. The history buffer size in this case is the `windowSize` * 8, which is pretty good for most cases.
|
||||
@param windowSize A vDSP_Length (unsigned long) representing the size of the window (i.e. the resolution) of data that should be used to calculate the FFT. A typical value for this would be something like 1024 - 4096 (or higher for an even higher resolution FFT).
|
||||
@param sampleRate A float representing the sample rate of the incoming audio signal.
|
||||
@param delegate An EZAudioFFTDelegate to receive an event whenever the FFT is calculated.
|
||||
@return A newly created EZAudioFFTRolling instance.
|
||||
*/
|
||||
+ (instancetype)fftWithWindowSize:(vDSP_Length)windowSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to initialize an EZAudioFFTRolling instance with a window size, a history buffer size, and a sample rate. The EZAudioFFTRolling has an internal EZPlotHistoryInfo data structure that writes audio data to a circular buffer and manages sliding windows of audio data to support efficient, large FFT calculations. Here you provide a window size that represents how many audio sample will be used to calculate the FFT, a history buffer size representing the maximum length of the sliding window's underlying circular buffer, and a float representing the sample rate of the incoming audio (can be 0 if you don't care about the `maxFrequency` property).
|
||||
@param windowSize A vDSP_Length (unsigned long) representing the size of the window (i.e. the resolution) of data that should be used to calculate the FFT. A typical value for this would be something like 1024 - 4096 (or higher for an even higher resolution FFT).
|
||||
@param historyBufferSize A vDSP_Length (unsigned long) representing the length of the history buffer. This should be AT LEAST the size of the window. A recommended value for this would be at least 8x greater than the `windowSize` argument.
|
||||
@param sampleRate A float representing the sample rate of the incoming audio signal.
|
||||
@return A newly created EZAudioFFTRolling instance.
|
||||
*/
|
||||
+ (instancetype)fftWithWindowSize:(vDSP_Length)windowSize
|
||||
historyBufferSize:(vDSP_Length)historyBufferSize
|
||||
sampleRate:(float)sampleRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to initialize an EZAudioFFTRolling instance with a window size, a history buffer size, a sample rate, and an EZAudioFFTDelegate. The EZAudioFFTRolling has an internal EZPlotHistoryInfo data structure that writes audio data to a circular buffer and manages sliding windows of audio data to support efficient, large FFT calculations. Here you provide a window size that represents how many audio sample will be used to calculate the FFT, a history buffer size representing the maximum length of the sliding window's underlying circular buffer, a float representing the sample rate of the incoming audio (can be 0 if you don't care about the `maxFrequency` property), and an EZAudioFFTDelegate to receive a callback anytime the FFT is calculated.
|
||||
@param windowSize A vDSP_Length (unsigned long) representing the size of the window (i.e. the resolution) of data that should be used to calculate the FFT. A typical value for this would be something like 1024 - 4096 (or higher for an even higher resolution FFT).
|
||||
@param historyBufferSize A vDSP_Length (unsigned long) representing the length of the history buffer. This should be AT LEAST the size of the window. A recommended value for this would be at least 8x greater than the `windowSize` argument.
|
||||
@param sampleRate A float representing the sample rate of the incoming audio signal.
|
||||
@param delegate An EZAudioFFTDelegate to receive an event whenever the FFT is calculated.
|
||||
@return A newly created EZAudioFFTRolling instance.
|
||||
*/
|
||||
+ (instancetype)fftWithWindowSize:(vDSP_Length)windowSize
|
||||
historyBufferSize:(vDSP_Length)historyBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Properties
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
A vDSP_Length (unsigned long) representing the length of the FFT window.
|
||||
*/
|
||||
@property (readonly, nonatomic) vDSP_Length windowSize;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A float array representing the audio data in the internal circular buffer used to perform the FFT. This will increase as more data is appended to the internal circular buffer via the `computeFFTWithBuffer:withBufferSize:` method. The length of this array is the `timeDomainBufferSize` property.
|
||||
*/
|
||||
@property (readonly, nonatomic) float *timeDomainData;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A UInt32 representing the length of the audio data used to perform the FFT.
|
||||
*/
|
||||
@property (readonly, nonatomic) UInt32 timeDomainBufferSize;
|
||||
|
||||
@end
|
||||
@@ -1,444 +0,0 @@
|
||||
//
|
||||
// EZAudioFFT.m
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 7/10/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "EZAudioFFT.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Data Structures
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
typedef struct EZAudioFFTInfo
|
||||
{
|
||||
FFTSetup fftSetup;
|
||||
COMPLEX_SPLIT complexA;
|
||||
float *outFFTData;
|
||||
vDSP_Length outFFTDataLength;
|
||||
float *inversedFFTData;
|
||||
vDSP_Length maxFrequencyIndex;
|
||||
float maxFrequencyMangitude;
|
||||
float maxFrequency;
|
||||
} EZAudioFFTInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFFT (Interface Extension)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@interface EZAudioFFT ()
|
||||
@property (assign, nonatomic) EZAudioFFTInfo *info;
|
||||
@property (readwrite, nonatomic) vDSP_Length maximumBufferSize;
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFFT (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation EZAudioFFT
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
vDSP_destroy_fftsetup(self.info->fftSetup);
|
||||
free(self.info->complexA.realp);
|
||||
free(self.info->complexA.imagp);
|
||||
free(self.info->outFFTData);
|
||||
free(self.info->inversedFFTData);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithMaximumBufferSize:(vDSP_Length)maximumBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
{
|
||||
return [self initWithMaximumBufferSize:maximumBufferSize
|
||||
sampleRate:sampleRate
|
||||
delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithMaximumBufferSize:(vDSP_Length)maximumBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
self.maximumBufferSize = (vDSP_Length)maximumBufferSize;
|
||||
self.sampleRate = sampleRate;
|
||||
self.delegate = delegate;
|
||||
[self setup];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)fftWithMaximumBufferSize:(vDSP_Length)maximumBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
{
|
||||
return [[self alloc] initWithMaximumBufferSize:maximumBufferSize
|
||||
sampleRate:sampleRate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)fftWithMaximumBufferSize:(vDSP_Length)maximumBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithMaximumBufferSize:maximumBufferSize
|
||||
sampleRate:sampleRate
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setup
|
||||
{
|
||||
NSAssert(self.maximumBufferSize > 0, @"Expected FFT buffer size to be greater than 0!");
|
||||
|
||||
//
|
||||
// Initialize FFT
|
||||
//
|
||||
float maximumBufferSizeBytes = self.maximumBufferSize * sizeof(float);
|
||||
self.info = (EZAudioFFTInfo *)calloc(1, sizeof(EZAudioFFTInfo));
|
||||
vDSP_Length log2n = log2f(self.maximumBufferSize);
|
||||
self.info->fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
|
||||
long nOver2 = maximumBufferSizeBytes / 2;
|
||||
size_t maximumSizePerComponentBytes = nOver2 * sizeof(float);
|
||||
self.info->complexA.realp = (float *)malloc(maximumSizePerComponentBytes);
|
||||
self.info->complexA.imagp = (float *)malloc(maximumSizePerComponentBytes);
|
||||
self.info->outFFTData = (float *)malloc(maximumSizePerComponentBytes);
|
||||
memset(self.info->outFFTData, 0, maximumSizePerComponentBytes);
|
||||
self.info->inversedFFTData = (float *)malloc(maximumSizePerComponentBytes);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float *)computeFFTWithBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize
|
||||
{
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate real + imaginary components and normalize
|
||||
//
|
||||
vDSP_Length log2n = log2f(bufferSize);
|
||||
long nOver2 = bufferSize / 2;
|
||||
float mFFTNormFactor = 10.0 / (2 * bufferSize);
|
||||
vDSP_ctoz((COMPLEX*)buffer, 2, &(self.info->complexA), 1, nOver2);
|
||||
vDSP_fft_zrip(self.info->fftSetup, &(self.info->complexA), 1, log2n, FFT_FORWARD);
|
||||
vDSP_vsmul(self.info->complexA.realp, 1, &mFFTNormFactor, self.info->complexA.realp, 1, nOver2);
|
||||
vDSP_vsmul(self.info->complexA.imagp, 1, &mFFTNormFactor, self.info->complexA.imagp, 1, nOver2);
|
||||
vDSP_zvmags(&(self.info->complexA), 1, self.info->outFFTData, 1, nOver2);
|
||||
vDSP_fft_zrip(self.info->fftSetup, &(self.info->complexA), 1, log2n, FFT_INVERSE);
|
||||
vDSP_ztoc(&(self.info->complexA), 1, (COMPLEX *) self.info->inversedFFTData , 2, nOver2);
|
||||
self.info->outFFTDataLength = nOver2;
|
||||
|
||||
//
|
||||
// Calculate max freq
|
||||
//
|
||||
if (self.sampleRate > 0.0f)
|
||||
{
|
||||
vDSP_maxvi(self.info->outFFTData, 1, &self.info->maxFrequencyMangitude, &self.info->maxFrequencyIndex, nOver2);
|
||||
self.info->maxFrequency = [self frequencyAtIndex:self.info->maxFrequencyIndex];
|
||||
}
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(fft:updatedWithFFTData:bufferSize:)])
|
||||
{
|
||||
[self.delegate fft:self
|
||||
updatedWithFFTData:self.info->outFFTData
|
||||
bufferSize:nOver2];
|
||||
}
|
||||
|
||||
//
|
||||
// Return the FFT
|
||||
//
|
||||
return self.info->outFFTData;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float)frequencyAtIndex:(vDSP_Length)index
|
||||
{
|
||||
if (!(self.info->outFFTData == NULL || self.sampleRate == 0.0f))
|
||||
{
|
||||
float nyquistMaxFreq = self.sampleRate / 2.0;
|
||||
return ((float)index / (float)self.info->outFFTDataLength) * nyquistMaxFreq;
|
||||
}
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float)frequencyMagnitudeAtIndex:(vDSP_Length)index
|
||||
{
|
||||
if (self.info->outFFTData != NULL)
|
||||
{
|
||||
return self.info->outFFTData[index];
|
||||
}
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Getters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (COMPLEX_SPLIT)complexSplit
|
||||
{
|
||||
return self.info->complexA;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float *)fftData
|
||||
{
|
||||
return self.info->outFFTData;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (FFTSetup)fftSetup
|
||||
{
|
||||
return self.info->fftSetup;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float *)inversedFFTData
|
||||
{
|
||||
return self.info->inversedFFTData;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (vDSP_Length)maxFrequencyIndex
|
||||
{
|
||||
return self.info->maxFrequencyIndex;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float)maxFrequencyMagnitude
|
||||
{
|
||||
return self.info->maxFrequencyMangitude;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float)maxFrequency
|
||||
{
|
||||
return self.info->maxFrequency;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFFTRolling
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@interface EZAudioFFTRolling ()
|
||||
@property (assign, nonatomic) EZPlotHistoryInfo *historyInfo;
|
||||
@property (readwrite, nonatomic) vDSP_Length windowSize;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EZAudioFFTRolling
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[EZAudioUtilities freeHistoryInfo:self.historyInfo];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initialization
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithWindowSize:(vDSP_Length)windowSize
|
||||
sampleRate:(float)sampleRate
|
||||
{
|
||||
return [self initWithWindowSize:windowSize
|
||||
historyBufferSize:windowSize * 8
|
||||
sampleRate:sampleRate
|
||||
delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithWindowSize:(vDSP_Length)windowSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate
|
||||
{
|
||||
return [self initWithWindowSize:windowSize
|
||||
historyBufferSize:windowSize * 8
|
||||
sampleRate:sampleRate
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithWindowSize:(vDSP_Length)windowSize
|
||||
historyBufferSize:(vDSP_Length)historyBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
{
|
||||
return [self initWithWindowSize:windowSize
|
||||
historyBufferSize:historyBufferSize
|
||||
sampleRate:sampleRate
|
||||
delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithWindowSize:(vDSP_Length)windowSize
|
||||
historyBufferSize:(vDSP_Length)historyBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate
|
||||
{
|
||||
self = [super initWithMaximumBufferSize:historyBufferSize
|
||||
sampleRate:sampleRate];
|
||||
if (self)
|
||||
{
|
||||
self.delegate = delegate;
|
||||
self.windowSize = windowSize;
|
||||
|
||||
//
|
||||
// Allocate an appropriately sized history buffer in bytes
|
||||
//
|
||||
self.historyInfo = [EZAudioUtilities historyInfoWithDefaultLength:(UInt32)windowSize
|
||||
maximumLength:(UInt32)historyBufferSize];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)fftWithWindowSize:(vDSP_Length)windowSize
|
||||
sampleRate:(float)sampleRate
|
||||
{
|
||||
return [[self alloc] initWithWindowSize:windowSize
|
||||
sampleRate:sampleRate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)fftWithWindowSize:(vDSP_Length)windowSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithWindowSize:windowSize
|
||||
sampleRate:sampleRate
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)fftWithWindowSize:(vDSP_Length)windowSize
|
||||
historyBufferSize:(vDSP_Length)historyBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
{
|
||||
return [[self alloc] initWithWindowSize:windowSize
|
||||
historyBufferSize:historyBufferSize
|
||||
sampleRate:sampleRate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)fftWithWindowSize:(vDSP_Length)windowSize
|
||||
historyBufferSize:(vDSP_Length)historyBufferSize
|
||||
sampleRate:(float)sampleRate
|
||||
delegate:(id<EZAudioFFTDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithWindowSize:windowSize
|
||||
historyBufferSize:historyBufferSize
|
||||
sampleRate:sampleRate
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float *)computeFFTWithBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
{
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Append buffer to history window
|
||||
//
|
||||
[EZAudioUtilities appendBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
toHistoryInfo:self.historyInfo];
|
||||
|
||||
//
|
||||
// Call super to calculate the FFT of the window
|
||||
//
|
||||
return [super computeFFTWithBuffer:self.historyInfo->buffer
|
||||
withBufferSize:self.historyInfo->bufferSize];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Getters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (UInt32)timeDomainBufferSize
|
||||
{
|
||||
return self.historyInfo->bufferSize;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float *)timeDomainData
|
||||
{
|
||||
return self.historyInfo->buffer;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -328,9 +328,9 @@ UInt32 const EZAudioPlotDefaultMaxHistoryBufferLength = 8192;
|
||||
- (void)updateBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize
|
||||
{
|
||||
// append the buffer to the history
|
||||
[EZAudioUtilities appendBufferRMS:buffer
|
||||
withBufferSize:bufferSize
|
||||
toHistoryInfo:self.historyInfo];
|
||||
[EZAudioUtilities appendBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
toHistoryInfo:self.historyInfo];
|
||||
|
||||
// copy samples
|
||||
switch (self.plotType)
|
||||
|
||||
@@ -273,9 +273,9 @@ typedef struct
|
||||
//
|
||||
// Update history
|
||||
//
|
||||
[EZAudioUtilities appendBufferRMS:buffer
|
||||
withBufferSize:bufferSize
|
||||
toHistoryInfo:self.info->historyInfo];
|
||||
[EZAudioUtilities appendBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
toHistoryInfo:self.info->historyInfo];
|
||||
|
||||
//
|
||||
// Convert this data to point data
|
||||
|
||||
@@ -380,13 +380,6 @@ typedef NSRect EZRect;
|
||||
*/
|
||||
+ (float)SGN:(float)value;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Music Utilities
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (NSString *)noteNameStringForFrequency:(float)frequency
|
||||
includeOctave:(BOOL)includeOctave;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - OSStatus Utility
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -501,18 +494,6 @@ typedef NSRect EZRect;
|
||||
@param bufferSize A UInt32 representing the length of the incoming audio buffer
|
||||
@param historyInfo A pointer to a EZPlotHistoryInfo structure to use for managing the history buffers
|
||||
*/
|
||||
+ (void)appendBufferRMS:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
toHistoryInfo:(EZPlotHistoryInfo *)historyInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Appends a buffer of audio data to the tail of a EZPlotHistoryInfo data structure. Thread-safe.
|
||||
@param buffer A float array containing the incoming audio buffer to append to the history buffer
|
||||
@param bufferSize A UInt32 representing the length of the incoming audio buffer
|
||||
@param historyInfo A pointer to a EZPlotHistoryInfo structure to use for managing the history buffers
|
||||
*/
|
||||
+ (void)appendBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
toHistoryInfo:(EZPlotHistoryInfo *)historyInfo;
|
||||
|
||||
+21
-98
@@ -25,22 +25,6 @@
|
||||
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
static float const EZAudioUtilitiesFixedNoteA = 440.0f;
|
||||
static int const EZAudioUtilitiesFixedNoteAIndex = 9;
|
||||
static int const EZAudioUtilitiesFixedNoteAOctave = 4;
|
||||
static float const EZAudioUtilitiesEQFrequencyRatio = 1.059463094359f;
|
||||
static int const EZAudioUtilitiesNotesLength = 12;
|
||||
static NSString * const EZAudioUtilitiesNotes[EZAudioUtilitiesNotesLength] =
|
||||
{
|
||||
@"C", @"C#",
|
||||
@"D", @"D#",
|
||||
@"E",
|
||||
@"F", @"F#",
|
||||
@"G", @"G#",
|
||||
@"A", @"A#",
|
||||
@"B"
|
||||
};
|
||||
|
||||
BOOL __shouldExitOnCheckResultFail = YES;
|
||||
|
||||
@implementation EZAudioUtilities
|
||||
@@ -69,29 +53,15 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
numberOfChannels:(UInt32)channels
|
||||
interleaved:(BOOL)interleaved
|
||||
{
|
||||
unsigned nBuffers;
|
||||
unsigned bufferSize;
|
||||
unsigned channelsPerBuffer;
|
||||
if (interleaved)
|
||||
AudioBufferList *audioBufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer) * (channels-1));
|
||||
UInt32 outputBufferSize = 32 * frames; // 32 KB
|
||||
audioBufferList->mNumberBuffers = interleaved ? 1 : channels;
|
||||
for(int i = 0; i < audioBufferList->mNumberBuffers; i++)
|
||||
{
|
||||
nBuffers = 1;
|
||||
bufferSize = sizeof(float) * frames * channels;
|
||||
channelsPerBuffer = channels;
|
||||
}
|
||||
else
|
||||
{
|
||||
nBuffers = channels;
|
||||
bufferSize = sizeof(float) * frames;
|
||||
channelsPerBuffer = 1;
|
||||
}
|
||||
|
||||
AudioBufferList *audioBufferList = (AudioBufferList *)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer) * (channels-1));
|
||||
audioBufferList->mNumberBuffers = nBuffers;
|
||||
for(unsigned i = 0; i < nBuffers; i++)
|
||||
{
|
||||
audioBufferList->mBuffers[i].mNumberChannels = channelsPerBuffer;
|
||||
audioBufferList->mBuffers[i].mDataByteSize = bufferSize;
|
||||
audioBufferList->mBuffers[i].mData = calloc(bufferSize, 1);
|
||||
audioBufferList->mBuffers[i].mNumberChannels = channels;
|
||||
audioBufferList->mBuffers[i].mDataByteSize = channels * outputBufferSize;
|
||||
audioBufferList->mBuffers[i].mData = (float *)malloc(channels * sizeof(float) *outputBufferSize);
|
||||
memset(audioBufferList->mBuffers[i].mData, 0, frames);
|
||||
}
|
||||
return audioBufferList;
|
||||
}
|
||||
@@ -136,11 +106,6 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
|
||||
+ (void)freeFloatBuffers:(float **)buffers numberOfChannels:(UInt32)channels
|
||||
{
|
||||
if (!buffers || !*buffers)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < channels; i++)
|
||||
{
|
||||
free(buffers[i]);
|
||||
@@ -459,11 +424,11 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (float)MAP:(float)value
|
||||
leftMin:(float)leftMin
|
||||
leftMax:(float)leftMax
|
||||
rightMin:(float)rightMin
|
||||
rightMax:(float)rightMax
|
||||
+(float)MAP:(float)value
|
||||
leftMin:(float)leftMin
|
||||
leftMax:(float)leftMax
|
||||
rightMin:(float)rightMin
|
||||
rightMax:(float)rightMax
|
||||
{
|
||||
float leftSpan = leftMax - leftMin;
|
||||
float rightSpan = rightMax - rightMin;
|
||||
@@ -473,7 +438,8 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (float)RMS:(float *)buffer length:(int)bufferSize
|
||||
+(float)RMS:(float *)buffer
|
||||
length:(int)bufferSize
|
||||
{
|
||||
float sum = 0.0;
|
||||
for(int i = 0; i < bufferSize; i++)
|
||||
@@ -483,42 +449,11 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (float)SGN:(float)value
|
||||
+(float)SGN:(float)value
|
||||
{
|
||||
return value < 0 ? -1.0f : ( value > 0 ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Music Utilities
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (NSString *)noteNameStringForFrequency:(float)frequency
|
||||
includeOctave:(BOOL)includeOctave
|
||||
{
|
||||
NSMutableString *noteName = [NSMutableString string];
|
||||
int halfStepsFromFixedNote = roundf(log(frequency / EZAudioUtilitiesFixedNoteA) / log(EZAudioUtilitiesEQFrequencyRatio));
|
||||
int halfStepsModOctaves = halfStepsFromFixedNote % EZAudioUtilitiesNotesLength;
|
||||
int indexOfNote = EZAudioUtilitiesFixedNoteAIndex + halfStepsModOctaves;
|
||||
float octaves = halfStepsFromFixedNote / EZAudioUtilitiesNotesLength;
|
||||
if (indexOfNote >= EZAudioUtilitiesNotesLength)
|
||||
{
|
||||
indexOfNote -= EZAudioUtilitiesNotesLength;
|
||||
octaves += 1;
|
||||
}
|
||||
else if (indexOfNote < 0)
|
||||
{
|
||||
indexOfNote += EZAudioUtilitiesNotesLength;
|
||||
octaves = -1;
|
||||
}
|
||||
[noteName appendString:EZAudioUtilitiesNotes[indexOfNote]];
|
||||
if (includeOctave)
|
||||
{
|
||||
int noteOctave = EZAudioUtilitiesFixedNoteAOctave + octaves;
|
||||
[noteName appendFormat:@"%i", noteOctave];
|
||||
}
|
||||
return noteName;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - OSStatus Utility
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -655,21 +590,6 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
#pragma mark - EZPlotHistoryInfo Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (void)appendBufferRMS:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
toHistoryInfo:(EZPlotHistoryInfo *)historyInfo
|
||||
{
|
||||
//
|
||||
// Calculate RMS and append to buffer
|
||||
//
|
||||
float rms = [EZAudioUtilities RMS:buffer length:bufferSize];
|
||||
float src[1];
|
||||
src[0] = isnan(rms) ? 0.0 : rms;
|
||||
[self appendBuffer:src withBufferSize:1 toHistoryInfo:historyInfo];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (void)appendBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
toHistoryInfo:(EZPlotHistoryInfo *)historyInfo
|
||||
@@ -685,7 +605,10 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
//
|
||||
// Update the scroll history datasource
|
||||
//
|
||||
TPCircularBufferProduceBytes(&historyInfo->circularBuffer, buffer, bufferSize * sizeof(float));
|
||||
float rms = [EZAudioUtilities RMS:buffer length:bufferSize];
|
||||
float src[1];
|
||||
src[0] = isnan(rms) ? 0.0 : rms;
|
||||
TPCircularBufferProduceBytes(&historyInfo->circularBuffer, src, sizeof(src));
|
||||
int32_t targetBytes = historyInfo->bufferSize * sizeof(float);
|
||||
int32_t availableBytes = 0;
|
||||
float *historyBuffer = TPCircularBufferTail(&historyInfo->circularBuffer, &availableBytes);
|
||||
@@ -741,4 +664,4 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
@end
|
||||
-10
@@ -38,8 +38,6 @@
|
||||
66755A401B3B790D0013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 66755A2B1B3B790D0013E67E /* TPCircularBuffer.c */; };
|
||||
66755A411B3B790D0013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 66755A2E1B3B790D0013E67E /* CHANGELOG */; };
|
||||
66755A421B3B790D0013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 66755A2F1B3B790D0013E67E /* VERSION */; };
|
||||
667EEA541B51EF9400D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA531B51EF9400D57FB2 /* EZAudioFFT.m */; };
|
||||
667EEA681B51F0C000D57FB2 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 667EEA671B51F0C000D57FB2 /* Accelerate.framework */; };
|
||||
94056D88185B97E300EB94BA /* CoreGraphicsWaveformViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 94056D86185B97E300EB94BA /* CoreGraphicsWaveformViewController.m */; };
|
||||
94056D89185B97E300EB94BA /* CoreGraphicsWaveformViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 94056D87185B97E300EB94BA /* CoreGraphicsWaveformViewController.xib */; };
|
||||
94373025185B931C00F315F0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94373024185B931C00F315F0 /* Cocoa.framework */; };
|
||||
@@ -104,9 +102,6 @@
|
||||
66755A2C1B3B790D0013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
66755A2E1B3B790D0013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
66755A2F1B3B790D0013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA521B51EF9400D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA531B51EF9400D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
667EEA671B51F0C000D57FB2 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
94056D85185B97E300EB94BA /* CoreGraphicsWaveformViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CoreGraphicsWaveformViewController.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
94056D86185B97E300EB94BA /* CoreGraphicsWaveformViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CoreGraphicsWaveformViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
94056D87185B97E300EB94BA /* CoreGraphicsWaveformViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CoreGraphicsWaveformViewController.xib; sourceTree = "<group>"; };
|
||||
@@ -142,7 +137,6 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
667EEA681B51F0C000D57FB2 /* Accelerate.framework in Frameworks */,
|
||||
94373088185B937E00F315F0 /* QuartzCore.framework in Frameworks */,
|
||||
94373086185B937100F315F0 /* OpenGL.framework in Frameworks */,
|
||||
94373084185B936B00F315F0 /* GLKit.framework in Frameworks */,
|
||||
@@ -174,8 +168,6 @@
|
||||
66755A101B3B790D0013E67E /* EZAudioDevice.m */,
|
||||
66755A111B3B790D0013E67E /* EZAudioDisplayLink.h */,
|
||||
66755A121B3B790D0013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA521B51EF9400D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA531B51EF9400D57FB2 /* EZAudioFFT.m */,
|
||||
66755A131B3B790D0013E67E /* EZAudioFile.h */,
|
||||
66755A141B3B790D0013E67E /* EZAudioFile.m */,
|
||||
66755A151B3B790D0013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -237,7 +229,6 @@
|
||||
94373023185B931C00F315F0 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
667EEA671B51F0C000D57FB2 /* Accelerate.framework */,
|
||||
94373087185B937E00F315F0 /* QuartzCore.framework */,
|
||||
94373085185B937100F315F0 /* OpenGL.framework */,
|
||||
94373083185B936B00F315F0 /* GLKit.framework */,
|
||||
@@ -429,7 +420,6 @@
|
||||
66755A371B3B790D0013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056D88185B97E300EB94BA /* CoreGraphicsWaveformViewController.m in Sources */,
|
||||
66755A391B3B790D0013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA541B51EF9400D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
66755A341B3B790D0013E67E /* EZAudioFile.m in Sources */,
|
||||
66755A3D1B3B790D0013E67E /* EZOutput.m in Sources */,
|
||||
66755A3B1B3B790D0013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
66755B961B3B79380013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 66755B811B3B79380013E67E /* TPCircularBuffer.c */; };
|
||||
66755B971B3B79380013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 66755B841B3B79380013E67E /* CHANGELOG */; };
|
||||
66755B981B3B79380013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 66755B851B3B79380013E67E /* VERSION */; };
|
||||
667EEA661B51EFDB00D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA651B51EFDB00D57FB2 /* EZAudioFFT.m */; };
|
||||
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 */; };
|
||||
@@ -90,8 +89,6 @@
|
||||
66755B821B3B79380013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
66755B841B3B79380013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
66755B851B3B79380013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA641B51EFDB00D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA651B51EFDB00D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
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; };
|
||||
@@ -160,8 +157,6 @@
|
||||
66755B661B3B79380013E67E /* EZAudioDevice.m */,
|
||||
66755B671B3B79380013E67E /* EZAudioDisplayLink.h */,
|
||||
66755B681B3B79380013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA641B51EFDB00D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA651B51EFDB00D57FB2 /* EZAudioFFT.m */,
|
||||
66755B691B3B79380013E67E /* EZAudioFile.h */,
|
||||
66755B6A1B3B79380013E67E /* EZAudioFile.m */,
|
||||
66755B6B1B3B79380013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -398,7 +393,6 @@
|
||||
66755B8D1B3B79380013E67E /* EZAudioPlayer.m in Sources */,
|
||||
9417A9D61872130200D9D37B /* FFTViewController.m in Sources */,
|
||||
66755B8F1B3B79380013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA661B51EFDB00D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
66755B8A1B3B79380013E67E /* EZAudioFile.m in Sources */,
|
||||
66755B931B3B79380013E67E /* EZOutput.m in Sources */,
|
||||
66755B911B3B79380013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
@@ -30,35 +30,30 @@
|
||||
*/
|
||||
#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, EZAudioFFTDelegate>
|
||||
@interface FFTViewController : NSViewController <EZMicrophoneDelegate>
|
||||
|
||||
#pragma mark - Components
|
||||
/**
|
||||
EZAudioPlot for frequency plot
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlot *audioPlotFreq;
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlot *audioPlotFreq;
|
||||
|
||||
/**
|
||||
EZAudioPlot for time plot
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlot *audioPlotTime;
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlot *audioPlotTime;
|
||||
|
||||
/**
|
||||
A label used to display the maximum frequency (i.e. the frequency with the highest energy) calculated from the FFT.
|
||||
Microphone
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSTextField *maxFrequencyLabel;
|
||||
|
||||
/**
|
||||
The microphone used to get input.
|
||||
*/
|
||||
@property (nonatomic, strong) EZMicrophone *microphone;
|
||||
|
||||
/**
|
||||
Used to calculate a rolling FFT of the incoming audio data.
|
||||
*/
|
||||
@property (nonatomic, strong) EZAudioFFTRolling *fft;
|
||||
@property (nonatomic,strong) EZMicrophone *microphone;
|
||||
|
||||
@end
|
||||
|
||||
@@ -25,13 +25,25 @@
|
||||
|
||||
#import "FFTViewController.h"
|
||||
|
||||
static vDSP_Length const FFTViewControllerFFTWindowSize = 4096;
|
||||
|
||||
@interface FFTViewController ()
|
||||
@property (nonatomic, assign) COMPLEX_SPLIT *A;
|
||||
@property (nonatomic, assign) FFTSetup FFTSetup;
|
||||
@property (nonatomic, assign) vDSP_Length log2n;
|
||||
@property (nonatomic, assign) BOOL isFFTSetup;
|
||||
@end
|
||||
|
||||
@implementation FFTViewController
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
vDSP_destroy_fftsetup(self.FFTSetup);
|
||||
free(self.A);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Customize the Audio Plot
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -41,31 +53,117 @@ static vDSP_Length const FFTViewControllerFFTWindowSize = 4096;
|
||||
//
|
||||
// Setup time domain audio plot
|
||||
//
|
||||
self.audioPlotTime.plotType = EZPlotTypeBuffer;
|
||||
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.shouldFill = YES;
|
||||
self.audioPlotFreq.plotType = EZPlotTypeBuffer;
|
||||
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;
|
||||
self.audioPlotFreq.shouldCenterYAxis = NO;
|
||||
|
||||
//
|
||||
// Create an instance of the microphone and tell it to use this view controller instance as the delegate
|
||||
//
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self];
|
||||
|
||||
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
|
||||
{
|
||||
//
|
||||
// Create an instance of the EZAudioFFTRolling to keep a history of the incoming audio data and calculate the FFT.
|
||||
// Setup the length
|
||||
//
|
||||
self.fft = [EZAudioFFTRolling fftWithWindowSize:FFTViewControllerFFTWindowSize
|
||||
sampleRate:self.microphone.audioStreamBasicDescription.mSampleRate
|
||||
delegate:self];
|
||||
|
||||
self.log2n = log2f(bufferSize);
|
||||
|
||||
//
|
||||
// Start the mic
|
||||
// Calculate the weights array. This is a one-off operation.
|
||||
//
|
||||
[self.microphone startFetchingAudio];
|
||||
_FFTSetup = vDSP_create_fftsetup(self.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
|
||||
//
|
||||
self.A = malloc(sizeof(COMPLEX_SPLIT));
|
||||
self.A->realp = (float *) malloc(nOver2 * sizeof(float));
|
||||
self.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, self.A, 1, nOver2);
|
||||
|
||||
//
|
||||
// Perform a forward FFT using fftSetup and A
|
||||
// Results are returned in A
|
||||
//
|
||||
vDSP_fft_zrip(_FFTSetup, self.A, 1, self.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 = self.A->realp[i]*self.A->realp[i]+self.A->imagp[i]*self.A->imagp[i];
|
||||
maxMag = mag > maxMag ? mag : maxMag;
|
||||
}
|
||||
for(int i=0; i < nOver2; i++)
|
||||
{
|
||||
// Calculate the magnitude
|
||||
float mag = self.A->realp[i]*self.A->realp[i]+self.A->imagp[i]*self.A->imagp[i];
|
||||
// Bind the value to be less than 1.0 to fit in the graph
|
||||
amp[i] = [EZAudioUtilities MAP:mag leftMin:0.0 leftMax:maxMag rightMin:0.0 rightMax:1.0];
|
||||
}
|
||||
|
||||
//
|
||||
// Update the frequency domain plot
|
||||
//
|
||||
[self.audioPlotFreq updateBuffer:amp withBufferSize:nOver2];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -77,34 +175,28 @@ static vDSP_Length const FFTViewControllerFFTWindowSize = 4096;
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
//
|
||||
// Calculate the FFT, will trigger EZAudioFFTDelegate
|
||||
//
|
||||
[self.fft computeFFTWithBuffer:buffer[0] withBufferSize:bufferSize];
|
||||
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
//
|
||||
// Update time domain plot
|
||||
//
|
||||
[weakSelf.audioPlotTime updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFFTDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) fft:(EZAudioFFT *)fft
|
||||
updatedWithFFTData:(float *)fftData
|
||||
bufferSize:(vDSP_Length)bufferSize
|
||||
{
|
||||
float maxFrequency = [fft maxFrequency];
|
||||
NSString *noteName = [EZAudioUtilities noteNameStringForFrequency:maxFrequency
|
||||
includeOctave:YES];
|
||||
|
||||
//
|
||||
// Lazily perform the FFT setup
|
||||
//
|
||||
if (!weakSelf.isFFTSetup)
|
||||
{
|
||||
[weakSelf createFFTWithBufferSize:bufferSize withAudioData:buffer[0]];
|
||||
weakSelf.isFFTSetup = YES;
|
||||
}
|
||||
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
weakSelf.maxFrequencyLabel.stringValue = [NSString stringWithFormat:@"Highest Note: %@,\nFrequency: %.2f", noteName, maxFrequency];
|
||||
[weakSelf.audioPlotFreq updateBuffer:fftData withBufferSize:(UInt32)bufferSize];
|
||||
//
|
||||
// Perform FFT and update FFT graph
|
||||
//
|
||||
[weakSelf updateFFTWithBufferSize:bufferSize
|
||||
withAudioData:buffer[0]];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,60 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="FFTViewController">
|
||||
<connections>
|
||||
<outlet property="audioPlotFreq" destination="1" id="9lp-OU-kM3"/>
|
||||
<outlet property="audioPlotTime" destination="aUO-zv-aqE" id="0TL-T2-imj"/>
|
||||
<outlet property="maxFrequencyLabel" destination="dlx-e6-5CC" id="3QV-3c-qki"/>
|
||||
<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" customClass="NSObject"/>
|
||||
<customView id="1" customClass="EZAudioPlot">
|
||||
<customView id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="aUO-zv-aqE" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="18" y="190" width="444" height="64"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="64" id="oiN-dY-Vey"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="color">
|
||||
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</customView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dlx-e6-5CC">
|
||||
<rect key="frame" x="16" y="159" width="4" height="22"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="IFE-um-tWr">
|
||||
<font key="font" size="18" name="HelveticaNeue-Light"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<splitView dividerStyle="thin" translatesAutoresizingMaskIntoConstraints="NO" id="78b-rz-Bpl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<subviews>
|
||||
<customView fixedFrame="YES" id="Zcc-CT-67u" customClass="EZAudioPlot">
|
||||
<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 firstItem="aUO-zv-aqE" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="18" id="9RE-pT-LZj"/>
|
||||
<constraint firstItem="dlx-e6-5CC" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="18" id="MGj-LS-3mw"/>
|
||||
<constraint firstAttribute="trailing" secondItem="aUO-zv-aqE" secondAttribute="trailing" constant="18" id="XiD-Ij-Mxf"/>
|
||||
<constraint firstItem="dlx-e6-5CC" firstAttribute="top" secondItem="aUO-zv-aqE" secondAttribute="bottom" constant="9" id="Z3k-6W-KAH"/>
|
||||
<constraint firstItem="aUO-zv-aqE" firstAttribute="top" secondItem="1" secondAttribute="top" constant="18" id="jk5-aa-dMV"/>
|
||||
<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>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
|
||||
<color key="value" red="0.0078431372550000003" green="0.72156862749999995" blue="0.96078431369999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="color">
|
||||
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<point key="canvasLocation" x="156" y="183"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
-10
@@ -24,8 +24,6 @@
|
||||
66755A791B3B79130013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 66755A641B3B79130013E67E /* TPCircularBuffer.c */; };
|
||||
66755A7A1B3B79130013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 66755A671B3B79130013E67E /* CHANGELOG */; };
|
||||
66755A7B1B3B79130013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 66755A681B3B79130013E67E /* VERSION */; };
|
||||
667EEA571B51EF9F00D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA561B51EF9F00D57FB2 /* EZAudioFFT.m */; };
|
||||
667EEA6A1B51F0D900D57FB2 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 667EEA691B51F0D900D57FB2 /* Accelerate.framework */; };
|
||||
94056D97185BB0BC00EB94BA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056D96185BB0BC00EB94BA /* Cocoa.framework */; };
|
||||
94056DA1185BB0BC00EB94BA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 94056D9F185BB0BC00EB94BA /* InfoPlist.strings */; };
|
||||
94056DA3185BB0BC00EB94BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 94056DA2185BB0BC00EB94BA /* main.m */; };
|
||||
@@ -90,9 +88,6 @@
|
||||
66755A651B3B79130013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
66755A671B3B79130013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
66755A681B3B79130013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA551B51EF9F00D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA561B51EF9F00D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
667EEA691B51F0D900D57FB2 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
94056D93185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioOpenGLWaveformExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94056D96185BB0BC00EB94BA /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
94056D99185BB0BC00EB94BA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
@@ -128,7 +123,6 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
667EEA6A1B51F0D900D57FB2 /* Accelerate.framework in Frameworks */,
|
||||
94056DD8185BB0F400EB94BA /* AudioToolbox.framework in Frameworks */,
|
||||
94056DD9185BB0F400EB94BA /* AudioUnit.framework in Frameworks */,
|
||||
94056DDA185BB0F400EB94BA /* CoreAudio.framework in Frameworks */,
|
||||
@@ -160,8 +154,6 @@
|
||||
66755A491B3B79130013E67E /* EZAudioDevice.m */,
|
||||
66755A4A1B3B79130013E67E /* EZAudioDisplayLink.h */,
|
||||
66755A4B1B3B79130013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA551B51EF9F00D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA561B51EF9F00D57FB2 /* EZAudioFFT.m */,
|
||||
66755A4C1B3B79130013E67E /* EZAudioFile.h */,
|
||||
66755A4D1B3B79130013E67E /* EZAudioFile.m */,
|
||||
66755A4E1B3B79130013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -223,7 +215,6 @@
|
||||
94056D95185BB0BC00EB94BA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
667EEA691B51F0D900D57FB2 /* Accelerate.framework */,
|
||||
94056DD5185BB0F400EB94BA /* AudioToolbox.framework */,
|
||||
94056DD6185BB0F400EB94BA /* AudioUnit.framework */,
|
||||
94056DD7185BB0F400EB94BA /* CoreAudio.framework */,
|
||||
@@ -398,7 +389,6 @@
|
||||
66755A701B3B79130013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056DAA185BB0BC00EB94BA /* AppDelegate.m in Sources */,
|
||||
66755A721B3B79130013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA571B51EF9F00D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
66755A6D1B3B79130013E67E /* EZAudioFile.m in Sources */,
|
||||
66755A761B3B79130013E67E /* EZOutput.m in Sources */,
|
||||
66755A741B3B79130013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-10
@@ -24,8 +24,6 @@
|
||||
66755B5D1B3B79310013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 66755B481B3B79310013E67E /* TPCircularBuffer.c */; };
|
||||
66755B5E1B3B79310013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 66755B4B1B3B79310013E67E /* CHANGELOG */; };
|
||||
66755B5F1B3B79310013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 66755B4C1B3B79310013E67E /* VERSION */; };
|
||||
667EEA631B51EFCF00D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA621B51EFCF00D57FB2 /* EZAudioFFT.m */; };
|
||||
667EEA721B51F0F200D57FB2 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 667EEA711B51F0F200D57FB2 /* Accelerate.framework */; };
|
||||
941D71B81864C457007D52D8 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 941D71B71864C457007D52D8 /* Cocoa.framework */; };
|
||||
941D71C21864C457007D52D8 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 941D71C01864C457007D52D8 /* InfoPlist.strings */; };
|
||||
941D71C41864C457007D52D8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 941D71C31864C457007D52D8 /* main.m */; };
|
||||
@@ -90,9 +88,6 @@
|
||||
66755B491B3B79310013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
66755B4B1B3B79310013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
66755B4C1B3B79310013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA611B51EFCF00D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA621B51EFCF00D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
667EEA711B51F0F200D57FB2 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
941D71B41864C457007D52D8 /* EZAudioPassThroughExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioPassThroughExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
941D71B71864C457007D52D8 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
941D71BA1864C457007D52D8 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
@@ -128,7 +123,6 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
667EEA721B51F0F200D57FB2 /* Accelerate.framework in Frameworks */,
|
||||
941D721D1864C4C0007D52D8 /* QuartzCore.framework in Frameworks */,
|
||||
941D721A1864C4AD007D52D8 /* GLKit.framework in Frameworks */,
|
||||
941D721B1864C4AD007D52D8 /* OpenGL.framework in Frameworks */,
|
||||
@@ -160,8 +154,6 @@
|
||||
66755B2D1B3B79310013E67E /* EZAudioDevice.m */,
|
||||
66755B2E1B3B79310013E67E /* EZAudioDisplayLink.h */,
|
||||
66755B2F1B3B79310013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA611B51EFCF00D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA621B51EFCF00D57FB2 /* EZAudioFFT.m */,
|
||||
66755B301B3B79310013E67E /* EZAudioFile.h */,
|
||||
66755B311B3B79310013E67E /* EZAudioFile.m */,
|
||||
66755B321B3B79310013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -223,7 +215,6 @@
|
||||
941D71B61864C457007D52D8 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
667EEA711B51F0F200D57FB2 /* Accelerate.framework */,
|
||||
941D721C1864C4C0007D52D8 /* QuartzCore.framework */,
|
||||
941D72181864C4AD007D52D8 /* GLKit.framework */,
|
||||
941D72191864C4AD007D52D8 /* OpenGL.framework */,
|
||||
@@ -398,7 +389,6 @@
|
||||
66755B541B3B79310013E67E /* EZAudioPlayer.m in Sources */,
|
||||
941D72211864C4D7007D52D8 /* PassThroughViewController.m in Sources */,
|
||||
66755B561B3B79310013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA631B51EFCF00D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
66755B511B3B79310013E67E /* EZAudioFile.m in Sources */,
|
||||
66755B5A1B3B79310013E67E /* EZOutput.m in Sources */,
|
||||
66755B581B3B79310013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-10
@@ -25,8 +25,6 @@
|
||||
66755AB21B3B791C0013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 66755A9D1B3B791C0013E67E /* TPCircularBuffer.c */; };
|
||||
66755AB31B3B791C0013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 66755AA01B3B791C0013E67E /* CHANGELOG */; };
|
||||
66755AB41B3B791C0013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 66755AA11B3B791C0013E67E /* VERSION */; };
|
||||
667EEA5A1B51EFAA00D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA591B51EFAA00D57FB2 /* EZAudioFFT.m */; };
|
||||
667EEA6C1B51F0E000D57FB2 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 667EEA6B1B51F0E000D57FB2 /* Accelerate.framework */; };
|
||||
94056EFB185BD83400EB94BA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056EFA185BD83400EB94BA /* Cocoa.framework */; };
|
||||
94056F05185BD83400EB94BA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 94056F03185BD83400EB94BA /* InfoPlist.strings */; };
|
||||
94056F07185BD83400EB94BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 94056F06185BD83400EB94BA /* main.m */; };
|
||||
@@ -92,9 +90,6 @@
|
||||
66755A9E1B3B791C0013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
66755AA01B3B791C0013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
66755AA11B3B791C0013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA581B51EFAA00D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA591B51EFAA00D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
667EEA6B1B51F0E000D57FB2 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
94056EF7185BD83400EB94BA /* EZAudioPlayFileExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioPlayFileExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94056EFA185BD83400EB94BA /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
94056EFD185BD83400EB94BA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
@@ -130,7 +125,6 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
667EEA6C1B51F0E000D57FB2 /* Accelerate.framework in Frameworks */,
|
||||
94056F65185BDB4700EB94BA /* AudioToolbox.framework in Frameworks */,
|
||||
94056F66185BDB4700EB94BA /* AudioUnit.framework in Frameworks */,
|
||||
94056F67185BDB4700EB94BA /* CoreAudio.framework in Frameworks */,
|
||||
@@ -162,8 +156,6 @@
|
||||
66755A821B3B791C0013E67E /* EZAudioDevice.m */,
|
||||
66755A831B3B791C0013E67E /* EZAudioDisplayLink.h */,
|
||||
66755A841B3B791C0013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA581B51EFAA00D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA591B51EFAA00D57FB2 /* EZAudioFFT.m */,
|
||||
66755A851B3B791C0013E67E /* EZAudioFile.h */,
|
||||
66755A861B3B791C0013E67E /* EZAudioFile.m */,
|
||||
66755A871B3B791C0013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -225,7 +217,6 @@
|
||||
94056EF9185BD83400EB94BA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
667EEA6B1B51F0E000D57FB2 /* Accelerate.framework */,
|
||||
94056F62185BDB4700EB94BA /* AudioToolbox.framework */,
|
||||
94056F63185BDB4700EB94BA /* AudioUnit.framework */,
|
||||
94056F64185BDB4700EB94BA /* CoreAudio.framework */,
|
||||
@@ -402,7 +393,6 @@
|
||||
66755AA91B3B791C0013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056F31185BD86D00EB94BA /* PlayFileViewController.m in Sources */,
|
||||
66755AAB1B3B791C0013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA5A1B51EFAA00D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
66755AA61B3B791C0013E67E /* EZAudioFile.m in Sources */,
|
||||
66755AAF1B3B791C0013E67E /* EZOutput.m in Sources */,
|
||||
66755AAD1B3B791C0013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-10
@@ -24,8 +24,6 @@
|
||||
66755AEB1B3B79230013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 66755AD61B3B79230013E67E /* TPCircularBuffer.c */; };
|
||||
66755AEC1B3B79230013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 66755AD91B3B79230013E67E /* CHANGELOG */; };
|
||||
66755AED1B3B79230013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 66755ADA1B3B79230013E67E /* VERSION */; };
|
||||
667EEA5D1B51EFB400D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA5C1B51EFB400D57FB2 /* EZAudioFFT.m */; };
|
||||
667EEA6E1B51F0E600D57FB2 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 667EEA6D1B51F0E600D57FB2 /* Accelerate.framework */; };
|
||||
94056E0D185BB3D800EB94BA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056E0C185BB3D800EB94BA /* Cocoa.framework */; };
|
||||
94056E17185BB3D800EB94BA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 94056E15185BB3D800EB94BA /* InfoPlist.strings */; };
|
||||
94056E19185BB3D800EB94BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 94056E18185BB3D800EB94BA /* main.m */; };
|
||||
@@ -91,9 +89,6 @@
|
||||
66755AD71B3B79230013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
66755AD91B3B79230013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
66755ADA1B3B79230013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA5B1B51EFB400D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA5C1B51EFB400D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
667EEA6D1B51F0E600D57FB2 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
94056E09185BB3D800EB94BA /* EZAudioRecordExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioRecordExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94056E0C185BB3D800EB94BA /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
94056E0F185BB3D800EB94BA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
@@ -130,7 +125,6 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
667EEA6E1B51F0E600D57FB2 /* Accelerate.framework in Frameworks */,
|
||||
941D71AA186298AA007D52D8 /* AVFoundation.framework in Frameworks */,
|
||||
94056E70185BB42100EB94BA /* QuartzCore.framework in Frameworks */,
|
||||
94056E6E185BB41900EB94BA /* CoreAudio.framework in Frameworks */,
|
||||
@@ -163,8 +157,6 @@
|
||||
66755ABB1B3B79220013E67E /* EZAudioDevice.m */,
|
||||
66755ABC1B3B79220013E67E /* EZAudioDisplayLink.h */,
|
||||
66755ABD1B3B79220013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA5B1B51EFB400D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA5C1B51EFB400D57FB2 /* EZAudioFFT.m */,
|
||||
66755ABE1B3B79220013E67E /* EZAudioFile.h */,
|
||||
66755ABF1B3B79220013E67E /* EZAudioFile.m */,
|
||||
66755AC01B3B79220013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -226,7 +218,6 @@
|
||||
94056E0B185BB3D800EB94BA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
667EEA6D1B51F0E600D57FB2 /* Accelerate.framework */,
|
||||
941D71A9186298AA007D52D8 /* AVFoundation.framework */,
|
||||
94056E6F185BB42100EB94BA /* QuartzCore.framework */,
|
||||
94056E6D185BB41900EB94BA /* CoreAudio.framework */,
|
||||
@@ -402,7 +393,6 @@
|
||||
66755AE21B3B79230013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056E74185BB44200EB94BA /* RecordViewController.m in Sources */,
|
||||
66755AE41B3B79230013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA5D1B51EFB400D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
66755ADF1B3B79230013E67E /* EZAudioFile.m in Sources */,
|
||||
66755AE81B3B79230013E67E /* EZOutput.m in Sources */,
|
||||
66755AE61B3B79230013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-10
@@ -24,8 +24,6 @@
|
||||
66755B241B3B792A0013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 66755B0F1B3B792A0013E67E /* TPCircularBuffer.c */; };
|
||||
66755B251B3B792A0013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 66755B121B3B792A0013E67E /* CHANGELOG */; };
|
||||
66755B261B3B792A0013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 66755B131B3B792A0013E67E /* VERSION */; };
|
||||
667EEA601B51EFC400D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA5F1B51EFC400D57FB2 /* EZAudioFFT.m */; };
|
||||
667EEA701B51F0EC00D57FB2 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 667EEA6F1B51F0EC00D57FB2 /* Accelerate.framework */; };
|
||||
94056E83185BCBC000EB94BA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056E82185BCBC000EB94BA /* Cocoa.framework */; };
|
||||
94056E8D185BCBC000EB94BA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 94056E8B185BCBC000EB94BA /* InfoPlist.strings */; };
|
||||
94056E8F185BCBC000EB94BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 94056E8E185BCBC000EB94BA /* main.m */; };
|
||||
@@ -91,9 +89,6 @@
|
||||
66755B101B3B792A0013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
66755B121B3B792A0013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
66755B131B3B792A0013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA5E1B51EFC400D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA5F1B51EFC400D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
667EEA6F1B51F0EC00D57FB2 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
94056E7F185BCBC000EB94BA /* EZAudioWaveformFromFileExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioWaveformFromFileExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94056E82185BCBC000EB94BA /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
94056E85185BCBC000EB94BA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
@@ -130,7 +125,6 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
667EEA701B51F0EC00D57FB2 /* Accelerate.framework in Frameworks */,
|
||||
94056EEB185BCDC500EB94BA /* QuartzCore.framework in Frameworks */,
|
||||
94056EE7185BCDBF00EB94BA /* AudioToolbox.framework in Frameworks */,
|
||||
94056EE8185BCDBF00EB94BA /* AudioUnit.framework in Frameworks */,
|
||||
@@ -162,8 +156,6 @@
|
||||
66755AF41B3B792A0013E67E /* EZAudioDevice.m */,
|
||||
66755AF51B3B792A0013E67E /* EZAudioDisplayLink.h */,
|
||||
66755AF61B3B792A0013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA5E1B51EFC400D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA5F1B51EFC400D57FB2 /* EZAudioFFT.m */,
|
||||
66755AF71B3B792A0013E67E /* EZAudioFile.h */,
|
||||
66755AF81B3B792A0013E67E /* EZAudioFile.m */,
|
||||
66755AF91B3B792A0013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -225,7 +217,6 @@
|
||||
94056E81185BCBC000EB94BA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
667EEA6F1B51F0EC00D57FB2 /* Accelerate.framework */,
|
||||
94056EEA185BCDC500EB94BA /* QuartzCore.framework */,
|
||||
94056EE4185BCDBF00EB94BA /* AudioToolbox.framework */,
|
||||
94056EE5185BCDBF00EB94BA /* AudioUnit.framework */,
|
||||
@@ -402,7 +393,6 @@
|
||||
66755B1B1B3B792A0013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056E96185BCBC000EB94BA /* AppDelegate.m in Sources */,
|
||||
66755B1D1B3B792A0013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA601B51EFC400D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
66755B181B3B792A0013E67E /* EZAudioFile.m in Sources */,
|
||||
66755B211B3B792A0013E67E /* EZOutput.m in Sources */,
|
||||
66755B1F1B3B792A0013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-6
@@ -24,7 +24,6 @@
|
||||
667558B11B3B604B0013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 6675589C1B3B604B0013E67E /* TPCircularBuffer.c */; };
|
||||
667558B21B3B604B0013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 6675589F1B3B604B0013E67E /* CHANGELOG */; };
|
||||
667558B31B3B604B0013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 667558A01B3B604B0013E67E /* VERSION */; };
|
||||
667EEA451B51EF4E00D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA441B51EF4E00D57FB2 /* EZAudioFFT.m */; };
|
||||
66DB85831B0430E70018EFC5 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 66DB85821B0430E70018EFC5 /* MainStoryboard.storyboard */; };
|
||||
94056F7E185E593500EB94BA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056F7D185E593500EB94BA /* Foundation.framework */; };
|
||||
94056F80185E593500EB94BA /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056F7F185E593500EB94BA /* CoreGraphics.framework */; };
|
||||
@@ -87,8 +86,6 @@
|
||||
6675589D1B3B604B0013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
6675589F1B3B604B0013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
667558A01B3B604B0013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA431B51EF4E00D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA441B51EF4E00D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
66DB85821B0430E70018EFC5 /* MainStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainStoryboard.storyboard; sourceTree = "<group>"; };
|
||||
94056F7A185E593500EB94BA /* EZAudioCoreGraphicsWaveformExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioCoreGraphicsWaveformExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94056F7D185E593500EB94BA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
@@ -149,8 +146,6 @@
|
||||
667558811B3B604B0013E67E /* EZAudioDevice.m */,
|
||||
667558821B3B604B0013E67E /* EZAudioDisplayLink.h */,
|
||||
667558831B3B604B0013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA431B51EF4E00D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA441B51EF4E00D57FB2 /* EZAudioFFT.m */,
|
||||
667558841B3B604B0013E67E /* EZAudioFile.h */,
|
||||
667558851B3B604B0013E67E /* EZAudioFile.m */,
|
||||
667558861B3B604B0013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -370,7 +365,6 @@
|
||||
667558A81B3B604B0013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94056FDE185E59D900EB94BA /* CoreGraphicsWaveformViewController.m in Sources */,
|
||||
667558AA1B3B604B0013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA451B51EF4E00D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
667558A51B3B604B0013E67E /* EZAudioFile.m in Sources */,
|
||||
667558AE1B3B604B0013E67E /* EZOutput.m in Sources */,
|
||||
667558AC1B3B604B0013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
667559231B3B78720013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 6675590E1B3B78720013E67E /* TPCircularBuffer.c */; };
|
||||
667559241B3B78720013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 667559111B3B78720013E67E /* CHANGELOG */; };
|
||||
667559251B3B78720013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 667559121B3B78720013E67E /* VERSION */; };
|
||||
667EEA511B51EF7F00D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA501B51EF7F00D57FB2 /* EZAudioFFT.m */; };
|
||||
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 */; };
|
||||
@@ -89,8 +88,6 @@
|
||||
6675590F1B3B78720013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
667559111B3B78720013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
667559121B3B78720013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA4F1B51EF7F00D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA501B51EF7F00D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
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; };
|
||||
@@ -152,8 +149,6 @@
|
||||
667558F31B3B78720013E67E /* EZAudioDevice.m */,
|
||||
667558F41B3B78720013E67E /* EZAudioDisplayLink.h */,
|
||||
667558F51B3B78720013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA4F1B51EF7F00D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA501B51EF7F00D57FB2 /* EZAudioFFT.m */,
|
||||
667558F61B3B78720013E67E /* EZAudioFile.h */,
|
||||
667558F71B3B78720013E67E /* EZAudioFile.m */,
|
||||
667558F81B3B78720013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -374,7 +369,6 @@
|
||||
6675591A1B3B78720013E67E /* EZAudioPlayer.m in Sources */,
|
||||
9417A97C1871E88300D9D37B /* AppDelegate.m in Sources */,
|
||||
6675591C1B3B78720013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA511B51EF7F00D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
667559171B3B78720013E67E /* EZAudioFile.m in Sources */,
|
||||
667559201B3B78720013E67E /* EZOutput.m in Sources */,
|
||||
6675591E1B3B78720013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -30,10 +30,15 @@
|
||||
*/
|
||||
#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, EZAudioFFTDelegate>
|
||||
@interface FFTViewController : UIViewController <EZMicrophoneDelegate>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Components
|
||||
@@ -50,18 +55,8 @@
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlot *audioPlotTime;
|
||||
|
||||
/**
|
||||
A label used to display the maximum frequency (i.e. the frequency with the highest energy) calculated from the FFT.
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet UILabel *maxFrequencyLabel;
|
||||
|
||||
/**
|
||||
The microphone used to get input.
|
||||
Microphone
|
||||
*/
|
||||
@property (nonatomic,strong) EZMicrophone *microphone;
|
||||
|
||||
/**
|
||||
Used to calculate a rolling FFT of the incoming audio data.
|
||||
*/
|
||||
@property (nonatomic, strong) EZAudioFFTRolling *fft;
|
||||
|
||||
@end
|
||||
|
||||
@@ -25,27 +25,30 @@
|
||||
|
||||
#import "FFTViewController.h"
|
||||
|
||||
static vDSP_Length const FFTViewControllerFFTWindowSize = 4096;
|
||||
@interface FFTViewController (){
|
||||
COMPLEX_SPLIT _A;
|
||||
FFTSetup _FFTSetup;
|
||||
BOOL _isFFTSetup;
|
||||
vDSP_Length _log2n;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation FFTViewController
|
||||
@synthesize audioPlotFreq;
|
||||
@synthesize audioPlotTime;
|
||||
@synthesize microphone;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Status Bar Style
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
return UIStatusBarStyleLightContent;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - View Lifecycle
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - Customize the Audio Plot
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
|
||||
//
|
||||
// Setup the AVAudioSession. EZMicrophone will not work properly on iOS
|
||||
// if you don't do this!
|
||||
@@ -63,77 +66,115 @@ static vDSP_Length const FFTViewControllerFFTWindowSize = 4096;
|
||||
NSLog(@"Error setting up audio session active: %@", error.localizedDescription);
|
||||
}
|
||||
|
||||
//
|
||||
/*
|
||||
Customizing the audio plot's look
|
||||
*/
|
||||
// Setup time domain audio plot
|
||||
//
|
||||
self.audioPlotTime.plotType = EZPlotTypeBuffer;
|
||||
self.maxFrequencyLabel.numberOfLines = 0;
|
||||
|
||||
//
|
||||
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.shouldFill = YES;
|
||||
self.audioPlotFreq.plotType = EZPlotTypeBuffer;
|
||||
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;
|
||||
self.audioPlotFreq.shouldCenterYAxis = NO;
|
||||
|
||||
//
|
||||
// Create an instance of the microphone and tell it to use this view controller instance as the delegate
|
||||
//
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self];
|
||||
|
||||
//
|
||||
// Create an instance of the EZAudioFFTRolling to keep a history of the incoming audio data and calculate the FFT.
|
||||
//
|
||||
self.fft = [EZAudioFFTRolling fftWithWindowSize:FFTViewControllerFFTWindowSize
|
||||
sampleRate:self.microphone.audioStreamBasicDescription.mSampleRate
|
||||
delegate:self];
|
||||
|
||||
//
|
||||
// Start the mic
|
||||
//
|
||||
[self.microphone startFetchingAudio];
|
||||
|
||||
/*
|
||||
Start the microphone
|
||||
*/
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self
|
||||
startsImmediately:YES];
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
#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] = [EZAudioUtilities 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
|
||||
{
|
||||
//
|
||||
// Calculate the FFT, will trigger EZAudioFFTDelegate
|
||||
//
|
||||
[self.fft computeFFTWithBuffer:buffer[0] withBufferSize:bufferSize];
|
||||
withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSelf.audioPlotTime updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFFTDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) fft:(EZAudioFFT *)fft
|
||||
updatedWithFFTData:(float *)fftData
|
||||
bufferSize:(vDSP_Length)bufferSize
|
||||
{
|
||||
float maxFrequency = [fft maxFrequency];
|
||||
NSString *noteName = [EZAudioUtilities noteNameStringForFrequency:maxFrequency
|
||||
includeOctave:YES];
|
||||
// Update time domain plot
|
||||
[self.audioPlotTime updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
weakSelf.maxFrequencyLabel.text = [NSString stringWithFormat:@"Highest Note: %@,\nFrequency: %.2f", noteName, maxFrequency];
|
||||
[weakSelf.audioPlotFreq updateBuffer:fftData withBufferSize:(UInt32)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
|
||||
|
||||
@@ -13,53 +13,39 @@
|
||||
<viewControllerLayoutGuide type="top" id="Gb6-mY-qlI"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="YgU-XB-3Wp"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="qdz-w1-Fnd" customClass="EZAudioPlot">
|
||||
<view key="view" contentMode="scaleToFill" id="qdz-w1-Fnd">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2rO-IY-dvl" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="18" y="18" width="564" height="64"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="64" id="V1K-Jj-DhO"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
|
||||
<color key="value" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="color">
|
||||
<color key="value" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rTC-r5-1nY" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="300" width="600" height="300"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OQU-xT-TSP" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="300"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Jcb-nb-Ibd">
|
||||
<rect key="frame" x="18" y="100" width="0.0" height="0.0"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="light" pointSize="18"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="2rO-IY-dvl" firstAttribute="leading" secondItem="qdz-w1-Fnd" secondAttribute="leading" constant="18" id="8Ww-vp-FX4"/>
|
||||
<constraint firstAttribute="trailing" secondItem="2rO-IY-dvl" secondAttribute="trailing" constant="18" id="AJT-fs-rh8"/>
|
||||
<constraint firstItem="Jcb-nb-Ibd" firstAttribute="top" secondItem="2rO-IY-dvl" secondAttribute="bottom" constant="18" id="LrN-Wx-JIp"/>
|
||||
<constraint firstItem="Jcb-nb-Ibd" firstAttribute="leading" secondItem="2rO-IY-dvl" secondAttribute="leading" id="QHW-YQ-Jh0"/>
|
||||
<constraint firstItem="2rO-IY-dvl" firstAttribute="top" secondItem="qdz-w1-Fnd" secondAttribute="top" constant="18" id="Thl-Cl-cSH"/>
|
||||
<constraint firstItem="rTC-r5-1nY" firstAttribute="top" secondItem="OQU-xT-TSP" secondAttribute="bottom" id="Gvx-p5-QUo"/>
|
||||
<constraint firstAttribute="trailing" secondItem="OQU-xT-TSP" secondAttribute="trailing" id="Jas-mw-vJx"/>
|
||||
<constraint firstItem="rTC-r5-1nY" firstAttribute="leading" secondItem="qdz-w1-Fnd" secondAttribute="leading" id="L4g-Ae-9tj"/>
|
||||
<constraint firstItem="rTC-r5-1nY" firstAttribute="leading" secondItem="qdz-w1-Fnd" secondAttribute="leading" id="R76-NA-7Bd"/>
|
||||
<constraint firstAttribute="trailing" secondItem="rTC-r5-1nY" secondAttribute="trailing" id="SD1-rQ-K9f"/>
|
||||
<constraint firstItem="OQU-xT-TSP" firstAttribute="leading" secondItem="qdz-w1-Fnd" secondAttribute="leading" id="Ylv-YL-VNN"/>
|
||||
<constraint firstItem="rTC-r5-1nY" firstAttribute="height" secondItem="OQU-xT-TSP" secondAttribute="height" id="c8v-Wf-j6b"/>
|
||||
<constraint firstItem="OQU-xT-TSP" firstAttribute="leading" secondItem="qdz-w1-Fnd" secondAttribute="leading" id="cky-9G-OUa"/>
|
||||
<constraint firstItem="YgU-XB-3Wp" firstAttribute="top" secondItem="rTC-r5-1nY" secondAttribute="bottom" id="diI-fy-02O"/>
|
||||
<constraint firstAttribute="trailing" secondItem="OQU-xT-TSP" secondAttribute="trailing" id="eU7-t0-VFY"/>
|
||||
<constraint firstItem="OQU-xT-TSP" firstAttribute="top" secondItem="qdz-w1-Fnd" secondAttribute="top" id="vV1-yG-7ff"/>
|
||||
<constraint firstAttribute="trailing" secondItem="rTC-r5-1nY" secondAttribute="trailing" id="whu-w2-7Ne"/>
|
||||
<constraint firstItem="OQU-xT-TSP" firstAttribute="top" secondItem="qdz-w1-Fnd" secondAttribute="top" id="zIe-GV-q0c"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
|
||||
<color key="value" red="0.0078431372550000003" green="0.72156862749999995" blue="0.96078431369999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="color">
|
||||
<color key="value" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="audioPlotFreq" destination="qdz-w1-Fnd" id="TKq-sR-dWl"/>
|
||||
<outlet property="audioPlotTime" destination="2rO-IY-dvl" id="14G-ei-FpB"/>
|
||||
<outlet property="maxFrequencyLabel" destination="Jcb-nb-Ibd" id="F5A-UP-Fik"/>
|
||||
<outlet property="audioPlotFreq" destination="rTC-r5-1nY" id="CRN-vl-avP"/>
|
||||
<outlet property="audioPlotTime" destination="OQU-xT-TSP" id="zfe-04-ywd"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="xe6-rr-s1W" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
|
||||
BIN
Binary file not shown.
-6
@@ -24,7 +24,6 @@
|
||||
66755A071B3B78940013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 667559F21B3B78940013E67E /* TPCircularBuffer.c */; };
|
||||
66755A081B3B78940013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 667559F51B3B78940013E67E /* CHANGELOG */; };
|
||||
66755A091B3B78940013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 667559F61B3B78940013E67E /* VERSION */; };
|
||||
667EEA421B51EF4200D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA411B51EF4200D57FB2 /* EZAudioFFT.m */; };
|
||||
66DB85B81B05714F0018EFC5 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 66DB85B71B05714F0018EFC5 /* MainStoryboard.storyboard */; };
|
||||
94056FEC185E5EAF00EB94BA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056FEB185E5EAF00EB94BA /* Foundation.framework */; };
|
||||
94056FEE185E5EAF00EB94BA /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056FED185E5EAF00EB94BA /* CoreGraphics.framework */; };
|
||||
@@ -87,8 +86,6 @@
|
||||
667559F31B3B78940013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
667559F51B3B78940013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
667559F61B3B78940013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA401B51EF4200D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA411B51EF4200D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
66DB85B71B05714F0018EFC5 /* MainStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainStoryboard.storyboard; sourceTree = "<group>"; };
|
||||
94056FE8185E5EAF00EB94BA /* EZAudioOpenGLWaveformExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioOpenGLWaveformExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94056FEB185E5EAF00EB94BA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
@@ -149,8 +146,6 @@
|
||||
667559D71B3B78940013E67E /* EZAudioDevice.m */,
|
||||
667559D81B3B78940013E67E /* EZAudioDisplayLink.h */,
|
||||
667559D91B3B78940013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA401B51EF4200D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA411B51EF4200D57FB2 /* EZAudioFFT.m */,
|
||||
667559DA1B3B78940013E67E /* EZAudioFile.h */,
|
||||
667559DB1B3B78940013E67E /* EZAudioFile.m */,
|
||||
667559DC1B3B78940013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -370,7 +365,6 @@
|
||||
667559FE1B3B78940013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94057050185E636100EB94BA /* OpenGLWaveformViewController.m in Sources */,
|
||||
66755A001B3B78940013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA421B51EF4200D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
667559FB1B3B78940013E67E /* EZAudioFile.m in Sources */,
|
||||
66755A041B3B78940013E67E /* EZOutput.m in Sources */,
|
||||
66755A021B3B78940013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-6
@@ -25,7 +25,6 @@
|
||||
6675595C1B3B78790013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 667559471B3B78790013E67E /* TPCircularBuffer.c */; };
|
||||
6675595D1B3B78790013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 6675594A1B3B78790013E67E /* CHANGELOG */; };
|
||||
6675595E1B3B78790013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 6675594B1B3B78790013E67E /* VERSION */; };
|
||||
667EEA4E1B51EF7200D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA4D1B51EF7200D57FB2 /* EZAudioFFT.m */; };
|
||||
9417A60E1864D4DC00D9D37B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A60D1864D4DC00D9D37B /* Foundation.framework */; };
|
||||
9417A6101864D4DC00D9D37B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A60F1864D4DC00D9D37B /* CoreGraphics.framework */; };
|
||||
9417A6121864D4DC00D9D37B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A6111864D4DC00D9D37B /* UIKit.framework */; };
|
||||
@@ -88,8 +87,6 @@
|
||||
667559481B3B78790013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
6675594A1B3B78790013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
6675594B1B3B78790013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA4C1B51EF7200D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA4D1B51EF7200D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
9417A60A1864D4DC00D9D37B /* EZAudioPassThroughExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioPassThroughExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9417A60D1864D4DC00D9D37B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
9417A60F1864D4DC00D9D37B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
@@ -149,8 +146,6 @@
|
||||
6675592C1B3B78790013E67E /* EZAudioDevice.m */,
|
||||
6675592D1B3B78790013E67E /* EZAudioDisplayLink.h */,
|
||||
6675592E1B3B78790013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA4C1B51EF7200D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA4D1B51EF7200D57FB2 /* EZAudioFFT.m */,
|
||||
6675592F1B3B78790013E67E /* EZAudioFile.h */,
|
||||
667559301B3B78790013E67E /* EZAudioFile.m */,
|
||||
667559311B3B78790013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -370,7 +365,6 @@
|
||||
667559531B3B78790013E67E /* EZAudioPlayer.m in Sources */,
|
||||
9417A61E1864D4DC00D9D37B /* AppDelegate.m in Sources */,
|
||||
667559551B3B78790013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA4E1B51EF7200D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
667559501B3B78790013E67E /* EZAudioFile.m in Sources */,
|
||||
667559591B3B78790013E67E /* EZOutput.m in Sources */,
|
||||
667559571B3B78790013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-6
@@ -25,7 +25,6 @@
|
||||
667558EA1B3B60B80013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 667558D51B3B60B80013E67E /* TPCircularBuffer.c */; };
|
||||
667558EB1B3B60B80013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 667558D81B3B60B80013E67E /* CHANGELOG */; };
|
||||
667558EC1B3B60B80013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 667558D91B3B60B80013E67E /* VERSION */; };
|
||||
667EEA3F1B51EF2D00D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA3E1B51EF2D00D57FB2 /* EZAudioFFT.m */; };
|
||||
9417A6C718658FB500D9D37B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A6C618658FB500D9D37B /* AudioToolbox.framework */; };
|
||||
9417A6C918658FC000D9D37B /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A6C818658FC000D9D37B /* GLKit.framework */; };
|
||||
9417A6D1186591CA00D9D37B /* simple-drum-beat.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9417A6D0186591CA00D9D37B /* simple-drum-beat.wav */; };
|
||||
@@ -89,8 +88,6 @@
|
||||
667558D61B3B60B80013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
667558D81B3B60B80013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
667558D91B3B60B80013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA3D1B51EF2D00D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA3E1B51EF2D00D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
9417A6C618658FB500D9D37B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
9417A6C818658FC000D9D37B /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
|
||||
9417A6D0186591CA00D9D37B /* simple-drum-beat.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = "simple-drum-beat.wav"; path = "../../../simple-drum-beat.wav"; sourceTree = "<group>"; };
|
||||
@@ -151,8 +148,6 @@
|
||||
667558BA1B3B60B80013E67E /* EZAudioDevice.m */,
|
||||
667558BB1B3B60B80013E67E /* EZAudioDisplayLink.h */,
|
||||
667558BC1B3B60B80013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA3D1B51EF2D00D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA3E1B51EF2D00D57FB2 /* EZAudioFFT.m */,
|
||||
667558BD1B3B60B80013E67E /* EZAudioFile.h */,
|
||||
667558BE1B3B60B80013E67E /* EZAudioFile.m */,
|
||||
667558BF1B3B60B80013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -374,7 +369,6 @@
|
||||
667558E11B3B60B80013E67E /* EZAudioPlayer.m in Sources */,
|
||||
944D03ED186038A60076EF7A /* AppDelegate.m in Sources */,
|
||||
667558E31B3B60B80013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA3F1B51EF2D00D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
667558DE1B3B60B80013E67E /* EZAudioFile.m in Sources */,
|
||||
667558E71B3B60B80013E67E /* EZOutput.m in Sources */,
|
||||
667558E51B3B60B80013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-6
@@ -25,7 +25,6 @@
|
||||
667559CE1B3B78890013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 667559B91B3B78890013E67E /* TPCircularBuffer.c */; };
|
||||
667559CF1B3B78890013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 667559BC1B3B78890013E67E /* CHANGELOG */; };
|
||||
667559D01B3B78890013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 667559BD1B3B78890013E67E /* VERSION */; };
|
||||
667EEA481B51EF5C00D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA471B51EF5C00D57FB2 /* EZAudioFFT.m */; };
|
||||
940570CC185E7F8300EB94BA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 940570CB185E7F8300EB94BA /* Foundation.framework */; };
|
||||
940570CE185E7F8300EB94BA /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 940570CD185E7F8300EB94BA /* CoreGraphics.framework */; };
|
||||
940570D0185E7F8300EB94BA /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 940570CF185E7F8300EB94BA /* UIKit.framework */; };
|
||||
@@ -88,8 +87,6 @@
|
||||
667559BA1B3B78890013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
667559BC1B3B78890013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
667559BD1B3B78890013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA461B51EF5C00D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA471B51EF5C00D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
940570C8185E7F8300EB94BA /* EZAudioRecordExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioRecordExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
940570CB185E7F8300EB94BA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
940570CD185E7F8300EB94BA /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
@@ -149,8 +146,6 @@
|
||||
6675599E1B3B78890013E67E /* EZAudioDevice.m */,
|
||||
6675599F1B3B78890013E67E /* EZAudioDisplayLink.h */,
|
||||
667559A01B3B78890013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA461B51EF5C00D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA471B51EF5C00D57FB2 /* EZAudioFFT.m */,
|
||||
667559A11B3B78890013E67E /* EZAudioFile.h */,
|
||||
667559A21B3B78890013E67E /* EZAudioFile.m */,
|
||||
667559A31B3B78890013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -370,7 +365,6 @@
|
||||
667559C51B3B78890013E67E /* EZAudioPlayer.m in Sources */,
|
||||
94057105185E805900EB94BA /* RecordViewController.m in Sources */,
|
||||
667559C71B3B78890013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA481B51EF5C00D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
667559C21B3B78890013E67E /* EZAudioFile.m in Sources */,
|
||||
667559CB1B3B78890013E67E /* EZOutput.m in Sources */,
|
||||
667559C91B3B78890013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
-6
@@ -25,7 +25,6 @@
|
||||
667559951B3B78820013E67E /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 667559801B3B78820013E67E /* TPCircularBuffer.c */; };
|
||||
667559961B3B78820013E67E /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 667559831B3B78820013E67E /* CHANGELOG */; };
|
||||
667559971B3B78820013E67E /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 667559841B3B78820013E67E /* VERSION */; };
|
||||
667EEA4B1B51EF6600D57FB2 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 667EEA4A1B51EF6600D57FB2 /* EZAudioFFT.m */; };
|
||||
9405705E185E69D400EB94BA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9405705D185E69D400EB94BA /* Foundation.framework */; };
|
||||
94057060185E69D400EB94BA /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9405705F185E69D400EB94BA /* CoreGraphics.framework */; };
|
||||
94057062185E69D400EB94BA /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94057061185E69D400EB94BA /* UIKit.framework */; };
|
||||
@@ -89,8 +88,6 @@
|
||||
667559811B3B78820013E67E /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
667559831B3B78820013E67E /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
667559841B3B78820013E67E /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
667EEA491B51EF6600D57FB2 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
667EEA4A1B51EF6600D57FB2 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
9405705A185E69D400EB94BA /* EZAudioWaveformFromFileExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioWaveformFromFileExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9405705D185E69D400EB94BA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
9405705F185E69D400EB94BA /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
@@ -151,8 +148,6 @@
|
||||
667559651B3B78820013E67E /* EZAudioDevice.m */,
|
||||
667559661B3B78820013E67E /* EZAudioDisplayLink.h */,
|
||||
667559671B3B78820013E67E /* EZAudioDisplayLink.m */,
|
||||
667EEA491B51EF6600D57FB2 /* EZAudioFFT.h */,
|
||||
667EEA4A1B51EF6600D57FB2 /* EZAudioFFT.m */,
|
||||
667559681B3B78820013E67E /* EZAudioFile.h */,
|
||||
667559691B3B78820013E67E /* EZAudioFile.m */,
|
||||
6675596A1B3B78820013E67E /* EZAudioFloatConverter.h */,
|
||||
@@ -374,7 +369,6 @@
|
||||
6675598C1B3B78820013E67E /* EZAudioPlayer.m in Sources */,
|
||||
9405706E185E69D400EB94BA /* AppDelegate.m in Sources */,
|
||||
6675598E1B3B78820013E67E /* EZAudioPlotGL.m in Sources */,
|
||||
667EEA4B1B51EF6600D57FB2 /* EZAudioFFT.m in Sources */,
|
||||
667559891B3B78820013E67E /* EZAudioFile.m in Sources */,
|
||||
667559921B3B78820013E67E /* EZOutput.m in Sources */,
|
||||
667559901B3B78820013E67E /* EZAudioUtilities.m in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user