Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 80f4d92165 |
@@ -1,25 +1,17 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "EZAudio"
|
||||
s.version = "1.1.5"
|
||||
s.summary = "A simple, intuitive audio framework for iOS and OSX useful for anyone doing audio processing and/or audio-based visualizations."
|
||||
s.homepage = "https://github.com/syedhali/EZAudio"
|
||||
s.screenshots = "https://s3-us-west-1.amazonaws.com/ezaudio-media/EZAudioSummary.png"
|
||||
s.license = { :type => 'MIT', :file => 'LICENSE' }
|
||||
s.author = { "Syed Haris Ali" => "syedhali07@gmail.com" }
|
||||
s.ios.deployment_target = '8.0'
|
||||
s.osx.deployment_target = '10.8'
|
||||
s.source = { :git => "https://github.com/syedhali/EZAudio.git", :tag => s.version }
|
||||
s.exclude_files = [ 'EZAudio/TPCircularBuffer.{h,c}', 'EZAudio/EZAudioiOS.h', 'EZAudio/EZAudioOSX.h' ]
|
||||
s.ios.frameworks = 'AudioToolbox','AVFoundation','GLKit', 'Accelerate'
|
||||
s.osx.frameworks = 'AudioToolbox','AudioUnit','CoreAudio','QuartzCore','OpenGL','GLKit', 'Accelerate'
|
||||
s.requires_arc = true;
|
||||
s.default_subspec = 'Full'
|
||||
s.subspec 'Core' do |core|
|
||||
core.source_files = 'EZAudio/*.{h,m,c}'
|
||||
end
|
||||
|
||||
s.subspec 'Full' do |full|
|
||||
full.dependency 'TPCircularBuffer', '1.1'
|
||||
full.dependency 'EZAudio/Core'
|
||||
end
|
||||
s.name = "EZAudio"
|
||||
s.version = "0.1.0"
|
||||
s.summary = "A simple, intuitive audio framework for iOS and OSX useful for anyone doing audio processing and/or audio-based visualizations."
|
||||
s.homepage = "https://github.com/syedhali/EZAudio"
|
||||
s.screenshots = "https://s3-us-west-1.amazonaws.com/ezaudio-media/EZAudioSummary.png"
|
||||
s.license = { :type => 'MIT', :file => 'LICENSE' }
|
||||
s.author = { "Syed Haris Ali" => "syedhali07@gmail.com" }
|
||||
s.ios.deployment_target = '6.0'
|
||||
s.osx.deployment_target = '10.8'
|
||||
s.source = { :git => "https://github.com/syedhali/EZAudio.git", :tag => s.version }
|
||||
s.source_files = 'EZAudio/*.{h,m,c}'
|
||||
s.exclude_files = 'EZAudio/VERSION'
|
||||
s.ios.frameworks = 'AudioToolbox','AVFoundation','GLKit'
|
||||
s.osx.frameworks = 'AudioToolbox','AudioUnit','CoreAudio','QuartzCore','OpenGL','GLKit'
|
||||
s.requires_arc = true;
|
||||
end
|
||||
|
||||
@@ -1,587 +0,0 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
469F4D1E1B749FEC00666A46 /* EZAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4CFE1B749FEC00666A46 /* EZAudio.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D1F1B749FEC00666A46 /* EZAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4CFF1B749FEC00666A46 /* EZAudio.m */; };
|
||||
469F4D201B749FEC00666A46 /* EZAudioDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D001B749FEC00666A46 /* EZAudioDevice.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D211B749FEC00666A46 /* EZAudioDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D011B749FEC00666A46 /* EZAudioDevice.m */; };
|
||||
469F4D221B749FEC00666A46 /* EZAudioDisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D021B749FEC00666A46 /* EZAudioDisplayLink.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D231B749FEC00666A46 /* EZAudioDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D031B749FEC00666A46 /* EZAudioDisplayLink.m */; };
|
||||
469F4D241B749FEC00666A46 /* EZAudioFFT.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D041B749FEC00666A46 /* EZAudioFFT.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D251B749FEC00666A46 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D051B749FEC00666A46 /* EZAudioFFT.m */; };
|
||||
469F4D261B749FEC00666A46 /* EZAudioFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D061B749FEC00666A46 /* EZAudioFile.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D271B749FEC00666A46 /* EZAudioFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D071B749FEC00666A46 /* EZAudioFile.m */; };
|
||||
469F4D281B749FEC00666A46 /* EZAudioFloatConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D081B749FEC00666A46 /* EZAudioFloatConverter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D291B749FEC00666A46 /* EZAudioFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D091B749FEC00666A46 /* EZAudioFloatConverter.m */; };
|
||||
469F4D2A1B749FEC00666A46 /* EZAudioFloatData.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D0A1B749FEC00666A46 /* EZAudioFloatData.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D2B1B749FEC00666A46 /* EZAudioFloatData.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D0B1B749FEC00666A46 /* EZAudioFloatData.m */; };
|
||||
469F4D2C1B749FEC00666A46 /* EZAudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D0C1B749FEC00666A46 /* EZAudioPlayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D2D1B749FEC00666A46 /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D0D1B749FEC00666A46 /* EZAudioPlayer.m */; };
|
||||
469F4D2E1B749FEC00666A46 /* EZAudioPlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D0E1B749FEC00666A46 /* EZAudioPlot.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D2F1B749FEC00666A46 /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D0F1B749FEC00666A46 /* EZAudioPlot.m */; };
|
||||
469F4D301B749FEC00666A46 /* EZAudioPlotGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D101B749FEC00666A46 /* EZAudioPlotGL.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D311B749FEC00666A46 /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D111B749FEC00666A46 /* EZAudioPlotGL.m */; };
|
||||
469F4D321B749FEC00666A46 /* EZAudioUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D121B749FEC00666A46 /* EZAudioUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D331B749FEC00666A46 /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D131B749FEC00666A46 /* EZAudioUtilities.m */; };
|
||||
469F4D341B749FEC00666A46 /* EZMicrophone.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D141B749FEC00666A46 /* EZMicrophone.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D351B749FEC00666A46 /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D151B749FEC00666A46 /* EZMicrophone.m */; };
|
||||
469F4D361B749FEC00666A46 /* EZOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D161B749FEC00666A46 /* EZOutput.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D371B749FEC00666A46 /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D171B749FEC00666A46 /* EZOutput.m */; };
|
||||
469F4D381B749FEC00666A46 /* EZPlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D181B749FEC00666A46 /* EZPlot.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D391B749FEC00666A46 /* EZPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D191B749FEC00666A46 /* EZPlot.m */; };
|
||||
469F4D3A1B749FEC00666A46 /* EZRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D1A1B749FEC00666A46 /* EZRecorder.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
469F4D3B1B749FEC00666A46 /* EZRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D1B1B749FEC00666A46 /* EZRecorder.m */; };
|
||||
469F4D3C1B749FEC00666A46 /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D1C1B749FEC00666A46 /* TPCircularBuffer.c */; };
|
||||
469F4D3D1B749FEC00666A46 /* TPCircularBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D1D1B749FEC00666A46 /* TPCircularBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BB31BBBDD6D00A8A048 /* EZAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4CFE1B749FEC00666A46 /* EZAudio.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BB41BBBDD6D00A8A048 /* EZAudioDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D001B749FEC00666A46 /* EZAudioDevice.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BB51BBBDD6D00A8A048 /* EZAudioDisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D021B749FEC00666A46 /* EZAudioDisplayLink.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BB61BBBDD6D00A8A048 /* EZAudioFFT.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D041B749FEC00666A46 /* EZAudioFFT.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BB71BBBDD6D00A8A048 /* EZAudioFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D061B749FEC00666A46 /* EZAudioFile.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BB81BBBDD6D00A8A048 /* EZAudioFloatConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D081B749FEC00666A46 /* EZAudioFloatConverter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BB91BBBDD6D00A8A048 /* EZAudioFloatData.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D0A1B749FEC00666A46 /* EZAudioFloatData.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BBA1BBBDD6D00A8A048 /* EZAudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D0C1B749FEC00666A46 /* EZAudioPlayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BBB1BBBDD6D00A8A048 /* EZAudioPlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D0E1B749FEC00666A46 /* EZAudioPlot.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BBC1BBBDD6D00A8A048 /* EZAudioPlotGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D101B749FEC00666A46 /* EZAudioPlotGL.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BBD1BBBDD6D00A8A048 /* EZAudioUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D121B749FEC00666A46 /* EZAudioUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BBE1BBBDD6D00A8A048 /* EZMicrophone.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D141B749FEC00666A46 /* EZMicrophone.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BBF1BBBDD6D00A8A048 /* EZOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D161B749FEC00666A46 /* EZOutput.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BC01BBBDD6D00A8A048 /* EZPlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D181B749FEC00666A46 /* EZPlot.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BC11BBBDD6D00A8A048 /* EZRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D1A1B749FEC00666A46 /* EZRecorder.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BC21BBBDD6E00A8A048 /* TPCircularBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 469F4D1D1B749FEC00666A46 /* TPCircularBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BC31BBBDD7E00A8A048 /* EZAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4CFF1B749FEC00666A46 /* EZAudio.m */; };
|
||||
8A5A4BC41BBBDD7E00A8A048 /* EZAudioDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D011B749FEC00666A46 /* EZAudioDevice.m */; };
|
||||
8A5A4BC51BBBDD7E00A8A048 /* EZAudioDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D031B749FEC00666A46 /* EZAudioDisplayLink.m */; };
|
||||
8A5A4BC61BBBDD7E00A8A048 /* EZAudioFFT.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D051B749FEC00666A46 /* EZAudioFFT.m */; };
|
||||
8A5A4BC71BBBDD7E00A8A048 /* EZAudioFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D071B749FEC00666A46 /* EZAudioFile.m */; };
|
||||
8A5A4BC81BBBDD7E00A8A048 /* EZAudioFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D091B749FEC00666A46 /* EZAudioFloatConverter.m */; };
|
||||
8A5A4BC91BBBDD7E00A8A048 /* EZAudioFloatData.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D0B1B749FEC00666A46 /* EZAudioFloatData.m */; };
|
||||
8A5A4BCA1BBBDD7E00A8A048 /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D0D1B749FEC00666A46 /* EZAudioPlayer.m */; };
|
||||
8A5A4BCB1BBBDD7E00A8A048 /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D0F1B749FEC00666A46 /* EZAudioPlot.m */; };
|
||||
8A5A4BCC1BBBDD7E00A8A048 /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D111B749FEC00666A46 /* EZAudioPlotGL.m */; };
|
||||
8A5A4BCD1BBBDD7E00A8A048 /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D131B749FEC00666A46 /* EZAudioUtilities.m */; };
|
||||
8A5A4BCE1BBBDD7E00A8A048 /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D151B749FEC00666A46 /* EZMicrophone.m */; };
|
||||
8A5A4BCF1BBBDD7E00A8A048 /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D171B749FEC00666A46 /* EZOutput.m */; };
|
||||
8A5A4BD01BBBDD7E00A8A048 /* EZPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D191B749FEC00666A46 /* EZPlot.m */; };
|
||||
8A5A4BD11BBBDD7E00A8A048 /* EZRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D1B1B749FEC00666A46 /* EZRecorder.m */; };
|
||||
8A5A4BD21BBBDE2800A8A048 /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 469F4D1C1B749FEC00666A46 /* TPCircularBuffer.c */; };
|
||||
8A5A4BF31BBBFFA000A8A048 /* EZAudioOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A5A4BF11BBBFF5600A8A048 /* EZAudioOSX.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8A5A4BF41BBC025600A8A048 /* EZAudioiOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A5A4BEF1BBBFF0A00A8A048 /* EZAudioiOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
469F4CF31B749F7800666A46 /* EZAudioiOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = EZAudioiOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
469F4CF81B749F7800666A46 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
469F4CFE1B749FEC00666A46 /* EZAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudio.h; sourceTree = "<group>"; };
|
||||
469F4CFF1B749FEC00666A46 /* EZAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudio.m; sourceTree = "<group>"; };
|
||||
469F4D001B749FEC00666A46 /* EZAudioDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioDevice.h; sourceTree = "<group>"; };
|
||||
469F4D011B749FEC00666A46 /* EZAudioDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioDevice.m; sourceTree = "<group>"; };
|
||||
469F4D021B749FEC00666A46 /* EZAudioDisplayLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioDisplayLink.h; sourceTree = "<group>"; };
|
||||
469F4D031B749FEC00666A46 /* EZAudioDisplayLink.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioDisplayLink.m; sourceTree = "<group>"; };
|
||||
469F4D041B749FEC00666A46 /* EZAudioFFT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFFT.h; sourceTree = "<group>"; };
|
||||
469F4D051B749FEC00666A46 /* EZAudioFFT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFT.m; sourceTree = "<group>"; };
|
||||
469F4D061B749FEC00666A46 /* EZAudioFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFile.h; sourceTree = "<group>"; };
|
||||
469F4D071B749FEC00666A46 /* EZAudioFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFile.m; sourceTree = "<group>"; };
|
||||
469F4D081B749FEC00666A46 /* EZAudioFloatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFloatConverter.h; sourceTree = "<group>"; };
|
||||
469F4D091B749FEC00666A46 /* EZAudioFloatConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFloatConverter.m; sourceTree = "<group>"; };
|
||||
469F4D0A1B749FEC00666A46 /* EZAudioFloatData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFloatData.h; sourceTree = "<group>"; };
|
||||
469F4D0B1B749FEC00666A46 /* EZAudioFloatData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFloatData.m; sourceTree = "<group>"; };
|
||||
469F4D0C1B749FEC00666A46 /* EZAudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlayer.h; sourceTree = "<group>"; };
|
||||
469F4D0D1B749FEC00666A46 /* EZAudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlayer.m; sourceTree = "<group>"; };
|
||||
469F4D0E1B749FEC00666A46 /* EZAudioPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlot.h; sourceTree = "<group>"; };
|
||||
469F4D0F1B749FEC00666A46 /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
469F4D101B749FEC00666A46 /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
469F4D111B749FEC00666A46 /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
469F4D121B749FEC00666A46 /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
469F4D131B749FEC00666A46 /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
469F4D141B749FEC00666A46 /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
469F4D151B749FEC00666A46 /* EZMicrophone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZMicrophone.m; sourceTree = "<group>"; };
|
||||
469F4D161B749FEC00666A46 /* EZOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZOutput.h; sourceTree = "<group>"; };
|
||||
469F4D171B749FEC00666A46 /* EZOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZOutput.m; sourceTree = "<group>"; };
|
||||
469F4D181B749FEC00666A46 /* EZPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZPlot.h; sourceTree = "<group>"; };
|
||||
469F4D191B749FEC00666A46 /* EZPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZPlot.m; sourceTree = "<group>"; };
|
||||
469F4D1A1B749FEC00666A46 /* EZRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZRecorder.h; sourceTree = "<group>"; };
|
||||
469F4D1B1B749FEC00666A46 /* EZRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZRecorder.m; sourceTree = "<group>"; };
|
||||
469F4D1C1B749FEC00666A46 /* TPCircularBuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = TPCircularBuffer.c; sourceTree = "<group>"; };
|
||||
469F4D1D1B749FEC00666A46 /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
8A5A4B9C1BBBDCB200A8A048 /* EZAudioOSX.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = EZAudioOSX.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8A5A4BEF1BBBFF0A00A8A048 /* EZAudioiOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioiOS.h; sourceTree = "<group>"; };
|
||||
8A5A4BF11BBBFF5600A8A048 /* EZAudioOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioOSX.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
469F4CEF1B749F7800666A46 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8A5A4B981BBBDCB200A8A048 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
469F4CE91B749F7800666A46 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
469F4CF51B749F7800666A46 /* EZAudio */,
|
||||
469F4CF41B749F7800666A46 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
469F4CF41B749F7800666A46 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
469F4CF31B749F7800666A46 /* EZAudioiOS.framework */,
|
||||
8A5A4B9C1BBBDCB200A8A048 /* EZAudioOSX.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
469F4CF51B749F7800666A46 /* EZAudio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
469F4CFE1B749FEC00666A46 /* EZAudio.h */,
|
||||
469F4CFF1B749FEC00666A46 /* EZAudio.m */,
|
||||
469F4D001B749FEC00666A46 /* EZAudioDevice.h */,
|
||||
469F4D011B749FEC00666A46 /* EZAudioDevice.m */,
|
||||
469F4D021B749FEC00666A46 /* EZAudioDisplayLink.h */,
|
||||
469F4D031B749FEC00666A46 /* EZAudioDisplayLink.m */,
|
||||
469F4D041B749FEC00666A46 /* EZAudioFFT.h */,
|
||||
469F4D051B749FEC00666A46 /* EZAudioFFT.m */,
|
||||
469F4D061B749FEC00666A46 /* EZAudioFile.h */,
|
||||
469F4D071B749FEC00666A46 /* EZAudioFile.m */,
|
||||
469F4D081B749FEC00666A46 /* EZAudioFloatConverter.h */,
|
||||
469F4D091B749FEC00666A46 /* EZAudioFloatConverter.m */,
|
||||
469F4D0A1B749FEC00666A46 /* EZAudioFloatData.h */,
|
||||
469F4D0B1B749FEC00666A46 /* EZAudioFloatData.m */,
|
||||
469F4D0C1B749FEC00666A46 /* EZAudioPlayer.h */,
|
||||
469F4D0D1B749FEC00666A46 /* EZAudioPlayer.m */,
|
||||
469F4D0E1B749FEC00666A46 /* EZAudioPlot.h */,
|
||||
469F4D0F1B749FEC00666A46 /* EZAudioPlot.m */,
|
||||
469F4D101B749FEC00666A46 /* EZAudioPlotGL.h */,
|
||||
469F4D111B749FEC00666A46 /* EZAudioPlotGL.m */,
|
||||
469F4D121B749FEC00666A46 /* EZAudioUtilities.h */,
|
||||
469F4D131B749FEC00666A46 /* EZAudioUtilities.m */,
|
||||
469F4D141B749FEC00666A46 /* EZMicrophone.h */,
|
||||
469F4D151B749FEC00666A46 /* EZMicrophone.m */,
|
||||
469F4D161B749FEC00666A46 /* EZOutput.h */,
|
||||
469F4D171B749FEC00666A46 /* EZOutput.m */,
|
||||
469F4D181B749FEC00666A46 /* EZPlot.h */,
|
||||
469F4D191B749FEC00666A46 /* EZPlot.m */,
|
||||
469F4D1A1B749FEC00666A46 /* EZRecorder.h */,
|
||||
469F4D1B1B749FEC00666A46 /* EZRecorder.m */,
|
||||
469F4D1C1B749FEC00666A46 /* TPCircularBuffer.c */,
|
||||
469F4D1D1B749FEC00666A46 /* TPCircularBuffer.h */,
|
||||
8A5A4BEF1BBBFF0A00A8A048 /* EZAudioiOS.h */,
|
||||
8A5A4BF11BBBFF5600A8A048 /* EZAudioOSX.h */,
|
||||
469F4D3E1B749FF000666A46 /* Supporting Files */,
|
||||
);
|
||||
path = EZAudio;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
469F4D3E1B749FF000666A46 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
469F4CF81B749F7800666A46 /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
469F4CF01B749F7800666A46 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8A5A4BF41BBC025600A8A048 /* EZAudioiOS.h in Headers */,
|
||||
469F4D301B749FEC00666A46 /* EZAudioPlotGL.h in Headers */,
|
||||
469F4D2A1B749FEC00666A46 /* EZAudioFloatData.h in Headers */,
|
||||
469F4D221B749FEC00666A46 /* EZAudioDisplayLink.h in Headers */,
|
||||
469F4D201B749FEC00666A46 /* EZAudioDevice.h in Headers */,
|
||||
469F4D2E1B749FEC00666A46 /* EZAudioPlot.h in Headers */,
|
||||
469F4D2C1B749FEC00666A46 /* EZAudioPlayer.h in Headers */,
|
||||
469F4D381B749FEC00666A46 /* EZPlot.h in Headers */,
|
||||
469F4D261B749FEC00666A46 /* EZAudioFile.h in Headers */,
|
||||
469F4D341B749FEC00666A46 /* EZMicrophone.h in Headers */,
|
||||
469F4D361B749FEC00666A46 /* EZOutput.h in Headers */,
|
||||
469F4D1E1B749FEC00666A46 /* EZAudio.h in Headers */,
|
||||
469F4D3D1B749FEC00666A46 /* TPCircularBuffer.h in Headers */,
|
||||
469F4D3A1B749FEC00666A46 /* EZRecorder.h in Headers */,
|
||||
469F4D321B749FEC00666A46 /* EZAudioUtilities.h in Headers */,
|
||||
469F4D281B749FEC00666A46 /* EZAudioFloatConverter.h in Headers */,
|
||||
469F4D241B749FEC00666A46 /* EZAudioFFT.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8A5A4B991BBBDCB200A8A048 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8A5A4BF31BBBFFA000A8A048 /* EZAudioOSX.h in Headers */,
|
||||
8A5A4BB31BBBDD6D00A8A048 /* EZAudio.h in Headers */,
|
||||
8A5A4BB41BBBDD6D00A8A048 /* EZAudioDevice.h in Headers */,
|
||||
8A5A4BB51BBBDD6D00A8A048 /* EZAudioDisplayLink.h in Headers */,
|
||||
8A5A4BB61BBBDD6D00A8A048 /* EZAudioFFT.h in Headers */,
|
||||
8A5A4BB71BBBDD6D00A8A048 /* EZAudioFile.h in Headers */,
|
||||
8A5A4BB81BBBDD6D00A8A048 /* EZAudioFloatConverter.h in Headers */,
|
||||
8A5A4BB91BBBDD6D00A8A048 /* EZAudioFloatData.h in Headers */,
|
||||
8A5A4BBA1BBBDD6D00A8A048 /* EZAudioPlayer.h in Headers */,
|
||||
8A5A4BBB1BBBDD6D00A8A048 /* EZAudioPlot.h in Headers */,
|
||||
8A5A4BBC1BBBDD6D00A8A048 /* EZAudioPlotGL.h in Headers */,
|
||||
8A5A4BBD1BBBDD6D00A8A048 /* EZAudioUtilities.h in Headers */,
|
||||
8A5A4BBE1BBBDD6D00A8A048 /* EZMicrophone.h in Headers */,
|
||||
8A5A4BBF1BBBDD6D00A8A048 /* EZOutput.h in Headers */,
|
||||
8A5A4BC01BBBDD6D00A8A048 /* EZPlot.h in Headers */,
|
||||
8A5A4BC11BBBDD6D00A8A048 /* EZRecorder.h in Headers */,
|
||||
8A5A4BC21BBBDD6E00A8A048 /* TPCircularBuffer.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
469F4CF21B749F7800666A46 /* EZAudioiOS */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 469F4CFB1B749F7800666A46 /* Build configuration list for PBXNativeTarget "EZAudioiOS" */;
|
||||
buildPhases = (
|
||||
469F4CEE1B749F7800666A46 /* Sources */,
|
||||
469F4CEF1B749F7800666A46 /* Frameworks */,
|
||||
469F4CF01B749F7800666A46 /* Headers */,
|
||||
469F4CF11B749F7800666A46 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = EZAudioiOS;
|
||||
productName = EZAudio;
|
||||
productReference = 469F4CF31B749F7800666A46 /* EZAudioiOS.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
8A5A4B9B1BBBDCB200A8A048 /* EZAudioOSX */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 8A5A4BAD1BBBDCB200A8A048 /* Build configuration list for PBXNativeTarget "EZAudioOSX" */;
|
||||
buildPhases = (
|
||||
8A5A4B971BBBDCB200A8A048 /* Sources */,
|
||||
8A5A4B981BBBDCB200A8A048 /* Frameworks */,
|
||||
8A5A4B991BBBDCB200A8A048 /* Headers */,
|
||||
8A5A4B9A1BBBDCB200A8A048 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = EZAudioOSX;
|
||||
productName = EZAudioOSX;
|
||||
productReference = 8A5A4B9C1BBBDCB200A8A048 /* EZAudioOSX.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
469F4CEA1B749F7800666A46 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0700;
|
||||
ORGANIZATIONNAME = "Andrew Breckenridge";
|
||||
TargetAttributes = {
|
||||
469F4CF21B749F7800666A46 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
};
|
||||
8A5A4B9B1BBBDCB200A8A048 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 469F4CED1B749F7800666A46 /* Build configuration list for PBXProject "EZAudio" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 469F4CE91B749F7800666A46;
|
||||
productRefGroup = 469F4CF41B749F7800666A46 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
469F4CF21B749F7800666A46 /* EZAudioiOS */,
|
||||
8A5A4B9B1BBBDCB200A8A048 /* EZAudioOSX */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
469F4CF11B749F7800666A46 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8A5A4B9A1BBBDCB200A8A048 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
469F4CEE1B749F7800666A46 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
469F4D2F1B749FEC00666A46 /* EZAudioPlot.m in Sources */,
|
||||
469F4D2D1B749FEC00666A46 /* EZAudioPlayer.m in Sources */,
|
||||
469F4D251B749FEC00666A46 /* EZAudioFFT.m in Sources */,
|
||||
469F4D391B749FEC00666A46 /* EZPlot.m in Sources */,
|
||||
469F4D291B749FEC00666A46 /* EZAudioFloatConverter.m in Sources */,
|
||||
469F4D1F1B749FEC00666A46 /* EZAudio.m in Sources */,
|
||||
469F4D3C1B749FEC00666A46 /* TPCircularBuffer.c in Sources */,
|
||||
469F4D3B1B749FEC00666A46 /* EZRecorder.m in Sources */,
|
||||
469F4D311B749FEC00666A46 /* EZAudioPlotGL.m in Sources */,
|
||||
469F4D331B749FEC00666A46 /* EZAudioUtilities.m in Sources */,
|
||||
469F4D2B1B749FEC00666A46 /* EZAudioFloatData.m in Sources */,
|
||||
469F4D351B749FEC00666A46 /* EZMicrophone.m in Sources */,
|
||||
469F4D271B749FEC00666A46 /* EZAudioFile.m in Sources */,
|
||||
469F4D231B749FEC00666A46 /* EZAudioDisplayLink.m in Sources */,
|
||||
469F4D371B749FEC00666A46 /* EZOutput.m in Sources */,
|
||||
469F4D211B749FEC00666A46 /* EZAudioDevice.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8A5A4B971BBBDCB200A8A048 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8A5A4BD21BBBDE2800A8A048 /* TPCircularBuffer.c in Sources */,
|
||||
8A5A4BC31BBBDD7E00A8A048 /* EZAudio.m in Sources */,
|
||||
8A5A4BC41BBBDD7E00A8A048 /* EZAudioDevice.m in Sources */,
|
||||
8A5A4BC51BBBDD7E00A8A048 /* EZAudioDisplayLink.m in Sources */,
|
||||
8A5A4BC61BBBDD7E00A8A048 /* EZAudioFFT.m in Sources */,
|
||||
8A5A4BC71BBBDD7E00A8A048 /* EZAudioFile.m in Sources */,
|
||||
8A5A4BC81BBBDD7E00A8A048 /* EZAudioFloatConverter.m in Sources */,
|
||||
8A5A4BC91BBBDD7E00A8A048 /* EZAudioFloatData.m in Sources */,
|
||||
8A5A4BCA1BBBDD7E00A8A048 /* EZAudioPlayer.m in Sources */,
|
||||
8A5A4BCB1BBBDD7E00A8A048 /* EZAudioPlot.m in Sources */,
|
||||
8A5A4BCC1BBBDD7E00A8A048 /* EZAudioPlotGL.m in Sources */,
|
||||
8A5A4BCD1BBBDD7E00A8A048 /* EZAudioUtilities.m in Sources */,
|
||||
8A5A4BCE1BBBDD7E00A8A048 /* EZMicrophone.m in Sources */,
|
||||
8A5A4BCF1BBBDD7E00A8A048 /* EZOutput.m in Sources */,
|
||||
8A5A4BD01BBBDD7E00A8A048 /* EZPlot.m in Sources */,
|
||||
8A5A4BD11BBBDD7E00A8A048 /* EZRecorder.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
469F4CF91B749F7800666A46 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
469F4CFA1B749F7800666A46 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
469F4CFC1B749F7800666A46 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = EZAudio/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ezaudio.EZAudioiOS;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
469F4CFD1B749F7800666A46 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = EZAudio/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ezaudio.EZAudioiOS;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
8A5A4BAE1BBBDCB200A8A048 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_VERSION = A;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/EZAudio/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ezaudio.EZAudioOSX;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
8A5A4BAF1BBBDCB200A8A048 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_VERSION = A;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/EZAudio/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ezaudio.EZAudioOSX;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
469F4CED1B749F7800666A46 /* Build configuration list for PBXProject "EZAudio" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
469F4CF91B749F7800666A46 /* Debug */,
|
||||
469F4CFA1B749F7800666A46 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
469F4CFB1B749F7800666A46 /* Build configuration list for PBXNativeTarget "EZAudioiOS" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
469F4CFC1B749F7800666A46 /* Debug */,
|
||||
469F4CFD1B749F7800666A46 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
8A5A4BAD1BBBDCB200A8A048 /* Build configuration list for PBXNativeTarget "EZAudioOSX" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
8A5A4BAE1BBBDCB200A8A048 /* Debug */,
|
||||
8A5A4BAF1BBBDCB200A8A048 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 469F4CEA1B749F7800666A46 /* Project object */;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8A5A4B9B1BBBDCB200A8A048"
|
||||
BuildableName = "EZAudioOSX.framework"
|
||||
BlueprintName = "EZAudioOSX"
|
||||
ReferencedContainer = "container:EZAudio.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8A5A4BA41BBBDCB200A8A048"
|
||||
BuildableName = "EZAudioOSXTests.xctest"
|
||||
BlueprintName = "EZAudioOSXTests"
|
||||
ReferencedContainer = "container:EZAudio.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8A5A4B9B1BBBDCB200A8A048"
|
||||
BuildableName = "EZAudioOSX.framework"
|
||||
BlueprintName = "EZAudioOSX"
|
||||
ReferencedContainer = "container:EZAudio.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8A5A4B9B1BBBDCB200A8A048"
|
||||
BuildableName = "EZAudioOSX.framework"
|
||||
BlueprintName = "EZAudioOSX"
|
||||
ReferencedContainer = "container:EZAudio.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8A5A4B9B1BBBDCB200A8A048"
|
||||
BuildableName = "EZAudioOSX.framework"
|
||||
BlueprintName = "EZAudioOSX"
|
||||
ReferencedContainer = "container:EZAudio.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,80 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "469F4CF21B749F7800666A46"
|
||||
BuildableName = "EZAudioiOS.framework"
|
||||
BlueprintName = "EZAudioiOS"
|
||||
ReferencedContainer = "container:EZAudio.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "469F4CF21B749F7800666A46"
|
||||
BuildableName = "EZAudioiOS.framework"
|
||||
BlueprintName = "EZAudioiOS"
|
||||
ReferencedContainer = "container:EZAudio.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "469F4CF21B749F7800666A46"
|
||||
BuildableName = "EZAudioiOS.framework"
|
||||
BlueprintName = "EZAudioiOS"
|
||||
ReferencedContainer = "container:EZAudio.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,124 @@
|
||||
//
|
||||
// AEFloatConverter.h
|
||||
// The Amazing Audio Engine
|
||||
//
|
||||
// Created by Michael Tyson on 25/10/2012.
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
/*!
|
||||
* Universal converter to float format
|
||||
*
|
||||
* Use this class to easily convert arbitrary audio formats to floating point
|
||||
* for use with utilities like the Accelerate framework.
|
||||
*/
|
||||
@interface AEFloatConverter : NSObject
|
||||
|
||||
/*!
|
||||
* Initialize
|
||||
*
|
||||
* @param sourceFormat The audio format to use
|
||||
*/
|
||||
- (id)initWithSourceFormat:(AudioStreamBasicDescription)sourceFormat;
|
||||
|
||||
/*!
|
||||
* Convert audio to floating-point
|
||||
*
|
||||
* This C function, safe to use in a Core Audio realtime thread context, will take
|
||||
* an audio buffer list of audio in the format you provided at initialisation, and
|
||||
* convert it into a noninterleaved float array.
|
||||
*
|
||||
* @param converter Pointer to the converter object.
|
||||
* @param sourceBuffer An audio buffer list containing the source audio.
|
||||
* @param targetBuffers An array of floating-point arrays to store the converted float audio into.
|
||||
* Note that you must provide the correct number of arrays, to match the number of channels.
|
||||
* @param frames The number of frames to convert.
|
||||
* @return YES on success; NO on failure
|
||||
*/
|
||||
BOOL AEFloatConverterToFloat(AEFloatConverter* converter, AudioBufferList *sourceBuffer, float * const * targetBuffers, UInt32 frames);
|
||||
|
||||
/*!
|
||||
* Convert audio to floating-point, in a buffer list
|
||||
*
|
||||
* This C function, safe to use in a Core Audio realtime thread context, will take
|
||||
* an audio buffer list of audio in the format you provided at initialisation, and
|
||||
* convert it into a noninterleaved float format.
|
||||
*
|
||||
* @param converter Pointer to the converter object.
|
||||
* @param sourceBuffer An audio buffer list containing the source audio.
|
||||
* @param targetBuffer An audio buffer list to store the converted floating-point audio.
|
||||
* @param frames The number of frames to convert.
|
||||
* @return YES on success; NO on failure
|
||||
*/
|
||||
BOOL AEFloatConverterToFloatBufferList(AEFloatConverter* converter, AudioBufferList *sourceBuffer, AudioBufferList *targetBuffer, UInt32 frames);
|
||||
|
||||
/*!
|
||||
* Convert audio from floating-point
|
||||
*
|
||||
* This C function, safe to use in a Core Audio realtime thread context, will take
|
||||
* an audio buffer list of audio in the format you provided at initialisation, and
|
||||
* convert it into a float array.
|
||||
*
|
||||
* @param converter Pointer to the converter object.
|
||||
* @param sourceBuffers An array of floating-point arrays containing the floating-point audio to convert.
|
||||
* Note that you must provide the correct number of arrays, to match the number of channels.
|
||||
* @param targetBuffer An audio buffer list to store the converted audio into.
|
||||
* @param frames The number of frames to convert.
|
||||
* @return YES on success; NO on failure
|
||||
*/
|
||||
BOOL AEFloatConverterFromFloat(AEFloatConverter* converter, float * const * sourceBuffers, AudioBufferList *targetBuffer, UInt32 frames);
|
||||
|
||||
/*!
|
||||
* Convert audio from floating-point, in a buffer list
|
||||
*
|
||||
* This C function, safe to use in a Core Audio realtime thread context, will take
|
||||
* an audio buffer list of audio in the format you provided at initialisation, and
|
||||
* convert it into a float array.
|
||||
*
|
||||
* @param converter Pointer to the converter object.
|
||||
* @param sourceBuffer An audio buffer list containing the source audio.
|
||||
* @param targetBuffer An audio buffer list to store the converted audio into.
|
||||
* @param frames The number of frames to convert.
|
||||
* @return YES on success; NO on failure
|
||||
*/
|
||||
BOOL AEFloatConverterFromFloatBufferList(AEFloatConverter* converter, AudioBufferList *sourceBuffer, AudioBufferList *targetBuffer, UInt32 frames);
|
||||
|
||||
/*!
|
||||
* The AudioStreamBasicDescription representing the converted floating-point format
|
||||
*/
|
||||
@property (nonatomic, readonly) AudioStreamBasicDescription floatingPointAudioDescription;
|
||||
|
||||
/*!
|
||||
* The source audio format set at initialization
|
||||
*/
|
||||
@property (nonatomic, readonly) AudioStreamBasicDescription sourceFormat;
|
||||
|
||||
@end
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,211 @@
|
||||
//
|
||||
// AEFloatConverter.m
|
||||
// The Amazing Audio Engine
|
||||
//
|
||||
// Created by Michael Tyson on 25/10/2012.
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#import "AEFloatConverter.h"
|
||||
|
||||
#define checkResult(result,operation) (_checkResult((result),(operation),strrchr(__FILE__, '/')+1,__LINE__))
|
||||
static inline BOOL _checkResult(OSStatus result, const char *operation, const char* file, int line) {
|
||||
if (result != noErr) {
|
||||
NSLog(@"%s:%d: %s result %d %08X %4.4s", file, line, operation, (int)result, (int)result, (char*)&result);
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
#define kNoMoreDataErr -2222
|
||||
|
||||
struct complexInputDataProc_t {
|
||||
AudioBufferList *sourceBuffer;
|
||||
};
|
||||
|
||||
@interface AEFloatConverter () {
|
||||
AudioStreamBasicDescription _sourceAudioDescription;
|
||||
AudioStreamBasicDescription _floatAudioDescription;
|
||||
AudioConverterRef _toFloatConverter;
|
||||
AudioConverterRef _fromFloatConverter;
|
||||
AudioBufferList *_scratchFloatBufferList;
|
||||
}
|
||||
|
||||
static OSStatus complexInputDataProc(AudioConverterRef inAudioConverter,
|
||||
UInt32 *ioNumberDataPackets,
|
||||
AudioBufferList *ioData,
|
||||
AudioStreamPacketDescription **outDataPacketDescription,
|
||||
void *inUserData);
|
||||
@end
|
||||
|
||||
@implementation AEFloatConverter
|
||||
@synthesize sourceFormat = _sourceAudioDescription;
|
||||
|
||||
-(id)initWithSourceFormat:(AudioStreamBasicDescription)sourceFormat {
|
||||
if (!(self = [super init])) return nil;
|
||||
|
||||
_floatAudioDescription.mFormatID = kAudioFormatLinearPCM;
|
||||
_floatAudioDescription.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
|
||||
_floatAudioDescription.mChannelsPerFrame = sourceFormat.mChannelsPerFrame;
|
||||
_floatAudioDescription.mBytesPerPacket = sizeof(float);
|
||||
_floatAudioDescription.mFramesPerPacket = 1;
|
||||
_floatAudioDescription.mBytesPerFrame = sizeof(float);
|
||||
_floatAudioDescription.mBitsPerChannel = 8 * sizeof(float);
|
||||
_floatAudioDescription.mSampleRate = sourceFormat.mSampleRate;
|
||||
|
||||
_sourceAudioDescription = sourceFormat;
|
||||
|
||||
if (memcmp(&sourceFormat, &_floatAudioDescription, sizeof(AudioStreamBasicDescription)) != 0) {
|
||||
checkResult(AudioConverterNew(&sourceFormat, &_floatAudioDescription, &_toFloatConverter), "AudioConverterNew");
|
||||
checkResult(AudioConverterNew(&_floatAudioDescription, &sourceFormat, &_fromFloatConverter), "AudioConverterNew");
|
||||
_scratchFloatBufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList) + (_floatAudioDescription.mChannelsPerFrame-1)*sizeof(AudioBuffer));
|
||||
_scratchFloatBufferList->mNumberBuffers = _floatAudioDescription.mChannelsPerFrame;
|
||||
for ( int i=0; i<_scratchFloatBufferList->mNumberBuffers; i++) {
|
||||
_scratchFloatBufferList->mBuffers[i].mNumberChannels = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
if (_toFloatConverter) AudioConverterDispose(_toFloatConverter);
|
||||
if (_fromFloatConverter) AudioConverterDispose(_fromFloatConverter);
|
||||
if (_scratchFloatBufferList) free(_scratchFloatBufferList);
|
||||
// [super dealloc];
|
||||
}
|
||||
|
||||
|
||||
BOOL AEFloatConverterToFloat(AEFloatConverter* THIS, AudioBufferList *sourceBuffer, float * const * targetBuffers, UInt32 frames) {
|
||||
if (frames == 0) return YES;
|
||||
|
||||
if (THIS->_toFloatConverter) {
|
||||
UInt32 priorDataByteSize = sourceBuffer->mBuffers[0].mDataByteSize;
|
||||
for ( int i=0; i<sourceBuffer->mNumberBuffers; i++) {
|
||||
sourceBuffer->mBuffers[i].mDataByteSize = frames * THIS->_sourceAudioDescription.mBytesPerFrame;
|
||||
}
|
||||
|
||||
for ( int i=0; i<THIS->_scratchFloatBufferList->mNumberBuffers; i++) {
|
||||
THIS->_scratchFloatBufferList->mBuffers[i].mData = targetBuffers[i];
|
||||
THIS->_scratchFloatBufferList->mBuffers[i].mDataByteSize = frames * sizeof(float);
|
||||
}
|
||||
|
||||
OSStatus result = AudioConverterFillComplexBuffer(THIS->_toFloatConverter,
|
||||
complexInputDataProc,
|
||||
&(struct complexInputDataProc_t) { .sourceBuffer = sourceBuffer },
|
||||
&frames,
|
||||
THIS->_scratchFloatBufferList,
|
||||
NULL);
|
||||
|
||||
for ( int i=0; i<sourceBuffer->mNumberBuffers; i++) {
|
||||
sourceBuffer->mBuffers[i].mDataByteSize = priorDataByteSize;
|
||||
}
|
||||
|
||||
if (!checkResult(result, "AudioConverterConvertComplexBuffer")) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
} else {
|
||||
for ( int i=0; i<sourceBuffer->mNumberBuffers; i++) {
|
||||
memcpy(targetBuffers[i], sourceBuffer->mBuffers[i].mData, frames * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
BOOL AEFloatConverterToFloatBufferList(AEFloatConverter* converter, AudioBufferList *sourceBuffer, AudioBufferList *targetBuffer, UInt32 frames) {
|
||||
assert(targetBuffer->mNumberBuffers == converter->_floatAudioDescription.mChannelsPerFrame);
|
||||
|
||||
float *targetBuffers[targetBuffer->mNumberBuffers];
|
||||
for ( int i=0; i<targetBuffer->mNumberBuffers; i++) {
|
||||
targetBuffers[i] = (float*)targetBuffer->mBuffers[i].mData;
|
||||
}
|
||||
return AEFloatConverterToFloat(converter, sourceBuffer, targetBuffers, frames);
|
||||
}
|
||||
|
||||
BOOL AEFloatConverterFromFloat(AEFloatConverter* THIS, float * const * sourceBuffers, AudioBufferList *targetBuffer, UInt32 frames) {
|
||||
if (frames == 0) return YES;
|
||||
|
||||
if (THIS->_fromFloatConverter) {
|
||||
for ( int i=0; i<THIS->_scratchFloatBufferList->mNumberBuffers; i++) {
|
||||
THIS->_scratchFloatBufferList->mBuffers[i].mData = sourceBuffers[i];
|
||||
THIS->_scratchFloatBufferList->mBuffers[i].mDataByteSize = frames * sizeof(float);
|
||||
}
|
||||
|
||||
UInt32 priorDataByteSize = targetBuffer->mBuffers[0].mDataByteSize;
|
||||
for ( int i=0; i<targetBuffer->mNumberBuffers; i++) {
|
||||
targetBuffer->mBuffers[i].mDataByteSize = frames * THIS->_sourceAudioDescription.mBytesPerFrame;
|
||||
}
|
||||
|
||||
OSStatus result = AudioConverterFillComplexBuffer(THIS->_fromFloatConverter,
|
||||
complexInputDataProc,
|
||||
&(struct complexInputDataProc_t) { .sourceBuffer = THIS->_scratchFloatBufferList },
|
||||
&frames,
|
||||
targetBuffer,
|
||||
NULL);
|
||||
|
||||
for ( int i=0; i<targetBuffer->mNumberBuffers; i++) {
|
||||
targetBuffer->mBuffers[i].mDataByteSize = priorDataByteSize;
|
||||
}
|
||||
|
||||
if (!checkResult(result, "AudioConverterConvertComplexBuffer")) {
|
||||
return NO;
|
||||
}
|
||||
} else {
|
||||
for ( int i=0; i<targetBuffer->mNumberBuffers; i++) {
|
||||
memcpy(targetBuffer->mBuffers[i].mData, sourceBuffers[i], frames * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
BOOL AEFloatConverterFromFloatBufferList(AEFloatConverter* converter, AudioBufferList *sourceBuffer, AudioBufferList *targetBuffer, UInt32 frames) {
|
||||
assert(sourceBuffer->mNumberBuffers == converter->_floatAudioDescription.mChannelsPerFrame);
|
||||
|
||||
float *sourceBuffers[sourceBuffer->mNumberBuffers];
|
||||
for ( int i=0; i<sourceBuffer->mNumberBuffers; i++) {
|
||||
sourceBuffers[i] = (float*)sourceBuffer->mBuffers[i].mData;
|
||||
}
|
||||
return AEFloatConverterFromFloat(converter, sourceBuffers, targetBuffer, frames);
|
||||
}
|
||||
|
||||
static OSStatus complexInputDataProc(AudioConverterRef inAudioConverter,
|
||||
UInt32 *ioNumberDataPackets,
|
||||
AudioBufferList *ioData,
|
||||
AudioStreamPacketDescription **outDataPacketDescription,
|
||||
void *inUserData) {
|
||||
struct complexInputDataProc_t *arg = (struct complexInputDataProc_t*)inUserData;
|
||||
if (!arg->sourceBuffer) {
|
||||
return kNoMoreDataErr;
|
||||
}
|
||||
|
||||
memcpy(ioData, arg->sourceBuffer, sizeof(AudioBufferList) + (arg->sourceBuffer->mNumberBuffers-1)*sizeof(AudioBuffer));
|
||||
arg->sourceBuffer = NULL;
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
-(AudioStreamBasicDescription)floatingPointAudioDescription {
|
||||
return _floatAudioDescription;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 11/21/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,40 +25,25 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for teat.
|
||||
FOUNDATION_EXPORT double EZAudioVersionNumber;
|
||||
#pragma mark - 3rd Party Utilties
|
||||
#import "TPCircularBuffer.h"
|
||||
|
||||
//! Project version string for teat.
|
||||
FOUNDATION_EXPORT const unsigned char EZAudioVersionString[];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Core Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#import "EZAudioDevice.h"
|
||||
#import "EZAudioFile.h"
|
||||
#import "EZAudioFloatData.h"
|
||||
#import "EZMicrophone.h"
|
||||
#import "EZOutput.h"
|
||||
#import "EZRecorder.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
#pragma mark - Extended Components
|
||||
#import "EZAudioPlayer.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Interface Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#import "EZPlot.h"
|
||||
#import "EZAudioDisplayLink.h"
|
||||
#import "EZAudioPlot.h"
|
||||
#import "EZAudioPlotGL.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Utility Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#import "EZAudioFFT.h"
|
||||
#import "EZAudioFloatConverter.h"
|
||||
#import "EZAudioFloatData.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
#import "EZAudioPlotGLKViewController.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -261,7 +246,7 @@ FOUNDATION_EXPORT const unsigned char EZAudioVersionString[];
|
||||
@note Please use same method in EZAudioUtilities class instead.
|
||||
@return A new AudioStreamBasicDescription with the specified format.
|
||||
*/
|
||||
+ (AudioStreamBasicDescription)stereoFloatNonInterleavedFormatWithSampleRate:(float)sampleRate __attribute__((deprecated));
|
||||
+ (AudioStreamBasicDescription)stereoFloatNonInterleavedFormatWithSampleRate:(float)sameRate __attribute__((deprecated));
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// @name AudioStreamBasicDescription Helper Functions
|
||||
@@ -505,8 +490,8 @@ FOUNDATION_EXPORT const unsigned char EZAudioVersionString[];
|
||||
|
||||
/**
|
||||
Initializes the circular buffer (just a wrapper around the C method)
|
||||
@param circularBuffer Pointer to an instance of the TPCircularBuffer
|
||||
@param size The length of the TPCircularBuffer (usually 1024)
|
||||
* @param circularBuffer Pointer to an instance of the TPCircularBuffer
|
||||
* @param size The length of the TPCircularBuffer (usually 1024)
|
||||
@deprecated This method is deprecated starting in version 0.1.0.
|
||||
@note Please use same method in EZAudioUtilities class instead.
|
||||
*/
|
||||
@@ -525,4 +510,4 @@ FOUNDATION_EXPORT const unsigned char EZAudioVersionString[];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
@end
|
||||
@@ -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>
|
||||
@@ -44,37 +27,20 @@
|
||||
// @name Getting The Devices
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current EZAudioDevice that is being used to pull input.
|
||||
@return An EZAudioDevice instance representing the currently selected input device.
|
||||
*/
|
||||
+ (EZAudioDevice *)currentInputDevice;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current EZAudioDevice that is being used to output audio.
|
||||
@return An EZAudioDevice instance representing the currently selected ouotput device.
|
||||
*/
|
||||
+ (EZAudioDevice *)currentOutputDevice;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Enumerates all the available input devices and returns the result in an NSArray of EZAudioDevice instances.
|
||||
@return An NSArray containing EZAudioDevice instances, one for each available input device.
|
||||
*/
|
||||
+ (NSArray *)inputDevices;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
/**
|
||||
Enumerates all the available output devices and returns the result in an NSArray of EZAudioDevice instances.
|
||||
@return An NSArray of output EZAudioDevice instances.
|
||||
Provides the current EZAudioDevice that is being used to pull input.
|
||||
- iOS only
|
||||
@return An EZAudioDevice instance representing the currently selected input device.
|
||||
*/
|
||||
+ (NSArray *)outputDevices;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
+ (EZAudioDevice *)currentInputDevice;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -86,16 +52,6 @@
|
||||
+ (void)enumerateInputDevicesUsingBlock:(void(^)(EZAudioDevice *device,
|
||||
BOOL *stop))block;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Enumerates all the available output devices.
|
||||
- iOS only
|
||||
@param block When enumerating this block executes repeatedly for each EZAudioDevice found. It contains two arguments - first, the EZAudioDevice found, then a pointer to a stop BOOL to allow breaking out of the enumeration)
|
||||
*/
|
||||
+ (void)enumerateOutputDevicesUsingBlock:(void (^)(EZAudioDevice *device,
|
||||
BOOL *stop))block;
|
||||
|
||||
#elif TARGET_OS_MAC
|
||||
|
||||
/**
|
||||
@@ -107,6 +63,15 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Enumerates all the available output devices and returns the result in an NSArray of EZAudioDevice instances.
|
||||
- OSX only
|
||||
@return An NSArray of output EZAudioDevice instances.
|
||||
*/
|
||||
+ (NSArray *)outputDevices;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Enumerates all the available devices.
|
||||
- OSX only
|
||||
@@ -184,4 +149,4 @@
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
@end
|
||||
@@ -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"
|
||||
@@ -66,19 +49,6 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (EZAudioDevice *)currentOutputDevice
|
||||
{
|
||||
AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
AVAudioSessionPortDescription *port = [[[session currentRoute] outputs] firstObject];
|
||||
AVAudioSessionDataSourceDescription *dataSource = [session outputDataSource];
|
||||
EZAudioDevice *device = [[EZAudioDevice alloc] init];
|
||||
device.port = port;
|
||||
device.dataSource = dataSource;
|
||||
return device;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (NSArray *)inputDevices
|
||||
{
|
||||
__block NSMutableArray *devices = [NSMutableArray array];
|
||||
@@ -91,18 +61,6 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (NSArray *)outputDevices
|
||||
{
|
||||
__block NSMutableArray *devices = [NSMutableArray array];
|
||||
[self enumerateOutputDevicesUsingBlock:^(EZAudioDevice *device, BOOL *stop)
|
||||
{
|
||||
[devices addObject:device];
|
||||
}];
|
||||
return devices;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (void)enumerateInputDevicesUsingBlock:(void (^)(EZAudioDevice *, BOOL *))block
|
||||
{
|
||||
if (!block)
|
||||
@@ -143,42 +101,6 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (void)enumerateOutputDevicesUsingBlock:(void (^)(EZAudioDevice *, BOOL *))block
|
||||
{
|
||||
if (!block)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AVAudioSessionRouteDescription *currentRoute = [[AVAudioSession sharedInstance] currentRoute];
|
||||
NSArray *portDescriptions = [currentRoute outputs];
|
||||
|
||||
BOOL stop;
|
||||
for (AVAudioSessionPortDescription *outputDevicePortDescription in portDescriptions)
|
||||
{
|
||||
// add any additional sub-devices
|
||||
NSArray *dataSources = [outputDevicePortDescription dataSources];
|
||||
if (dataSources.count)
|
||||
{
|
||||
for (AVAudioSessionDataSourceDescription *outputDeviceDataSourceDescription in dataSources)
|
||||
{
|
||||
EZAudioDevice *device = [[EZAudioDevice alloc] init];
|
||||
device.port = outputDevicePortDescription;
|
||||
device.dataSource = outputDeviceDataSourceDescription;
|
||||
block(device, &stop);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EZAudioDevice *device = [[EZAudioDevice alloc] init];
|
||||
device.port = outputDevicePortDescription;
|
||||
block(device, &stop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
NSMutableString *name = [NSMutableString string];
|
||||
@@ -234,11 +156,11 @@
|
||||
AudioObjectPropertyAddress address = [self addressForPropertySelector:kAudioHardwarePropertyDevices];
|
||||
UInt32 devicesDataSize;
|
||||
[EZAudioUtilities checkResult:AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
|
||||
&address,
|
||||
0,
|
||||
NULL,
|
||||
&devicesDataSize)
|
||||
operation:"Failed to get data size"];
|
||||
&address,
|
||||
0,
|
||||
NULL,
|
||||
&devicesDataSize)
|
||||
operation:"Failed to get data size"];
|
||||
|
||||
// enumerate devices
|
||||
NSInteger count = devicesDataSize / sizeof(AudioDeviceID);
|
||||
@@ -288,44 +210,6 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (EZAudioDevice *)deviceWithPropertySelector:(AudioObjectPropertySelector)propertySelector
|
||||
{
|
||||
AudioDeviceID deviceID;
|
||||
UInt32 propSize = sizeof(AudioDeviceID);
|
||||
AudioObjectPropertyAddress address = [self addressForPropertySelector:propertySelector];
|
||||
[EZAudioUtilities checkResult:AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
||||
&address,
|
||||
0,
|
||||
NULL,
|
||||
&propSize,
|
||||
&deviceID)
|
||||
operation:"Failed to get device device on OSX"];
|
||||
EZAudioDevice *device = [[EZAudioDevice alloc] init];
|
||||
device.deviceID = deviceID;
|
||||
device.manufacturer = [self manufacturerForDeviceID:deviceID];
|
||||
device.name = [self namePropertyForDeviceID:deviceID];
|
||||
device.UID = [self UIDPropertyForDeviceID:deviceID];
|
||||
device.inputChannelCount = [self channelCountForScope:kAudioObjectPropertyScopeInput forDeviceID:deviceID];
|
||||
device.outputChannelCount = [self channelCountForScope:kAudioObjectPropertyScopeOutput forDeviceID:deviceID];
|
||||
return device;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (EZAudioDevice *)currentInputDevice
|
||||
{
|
||||
return [self deviceWithPropertySelector:kAudioHardwarePropertyDefaultInputDevice];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (EZAudioDevice *)currentOutputDevice
|
||||
{
|
||||
return [self deviceWithPropertySelector:kAudioHardwarePropertyDefaultOutputDevice];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (NSArray *)inputDevices
|
||||
{
|
||||
__block NSMutableArray *devices = [NSMutableArray array];
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
//
|
||||
// EZAudioDisplayLink.h
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/25/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 <QuartzCore/QuartzCore.h>
|
||||
|
||||
@class EZAudioDisplayLink;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioDisplayLinkDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioDisplayLinkDelegate provides a means for an EZAudioDisplayLink instance to notify a receiver when it should redraw itself.
|
||||
*/
|
||||
@protocol EZAudioDisplayLinkDelegate <NSObject>
|
||||
|
||||
@required
|
||||
/**
|
||||
Required method for an EZAudioDisplayLinkDelegate to implement. This fires at the screen's display rate (typically 60 fps).
|
||||
@param displayLink An EZAudioDisplayLink instance used by a receiver to draw itself at the screen's refresh rate.
|
||||
*/
|
||||
- (void)displayLinkNeedsDisplay:(EZAudioDisplayLink *)displayLink;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioDisplayLink
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioDisplayLink provides a cross-platform (iOS and Mac) abstraction over the CADisplayLink for iOS and CVDisplayLink for Mac. The purpose of this class is to provide an accurate timer for views that need to redraw themselves at 60 fps. This class is used by the EZAudioPlot and, eventually, the EZAudioPlotGL to provide a timer mechanism to draw real-time plots.
|
||||
*/
|
||||
@interface EZAudioDisplayLink : NSObject
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Methods
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create an EZAudioDisplayLink. The caller should implement the EZAudioDisplayLinkDelegate protocol to receive the `displayLinkNeedsDisplay:` delegate method to know when to redraw itself.
|
||||
@param delegate An instance that implements the EZAudioDisplayLinkDelegate protocol.
|
||||
@return An instance of the EZAudioDisplayLink.
|
||||
*/
|
||||
+ (instancetype)displayLinkWithDelegate:(id<EZAudioDisplayLinkDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioDisplayLinkDelegate for which to receive the redraw calls.
|
||||
*/
|
||||
@property (nonatomic, weak) id<EZAudioDisplayLinkDelegate> delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Instance Methods
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Method to start the display link and provide the `displayLinkNeedsDisplay:` calls to the `delegate`
|
||||
*/
|
||||
- (void)start;
|
||||
|
||||
/**
|
||||
Method to stop the display link from providing the `displayLinkNeedsDisplay:` calls to the `delegate`
|
||||
*/
|
||||
- (void)stop;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
@@ -1,180 +0,0 @@
|
||||
//
|
||||
// EZAudioDisplayLink.m
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/25/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 "EZAudioDisplayLink.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - CVDisplayLink Callback (Declaration)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#elif TARGET_OS_MAC
|
||||
static CVReturn EZAudioDisplayLinkCallback(CVDisplayLinkRef displayLinkRef,
|
||||
const CVTimeStamp *now,
|
||||
const CVTimeStamp *outputTime,
|
||||
CVOptionFlags flagsIn,
|
||||
CVOptionFlags *flagsOut,
|
||||
void *displayLinkContext);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioDisplayLink (Interface Extension)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@interface EZAudioDisplayLink ()
|
||||
#if TARGET_OS_IPHONE
|
||||
@property (nonatomic, strong) CADisplayLink *displayLink;
|
||||
#elif TARGET_OS_MAC
|
||||
@property (nonatomic, assign) CVDisplayLinkRef displayLink;
|
||||
#endif
|
||||
@property (nonatomic, assign) BOOL stopped;
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioDisplayLink (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation EZAudioDisplayLink
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
[self.displayLink invalidate];
|
||||
#elif TARGET_OS_MAC
|
||||
CVDisplayLinkStop(self.displayLink);
|
||||
CVDisplayLinkRelease(self.displayLink);
|
||||
self.displayLink = nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initialization
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)displayLinkWithDelegate:(id<EZAudioDisplayLinkDelegate>)delegate
|
||||
{
|
||||
EZAudioDisplayLink *displayLink = [[self alloc] init];
|
||||
displayLink.delegate = delegate;
|
||||
return displayLink;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initialization
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
[self setup];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setup
|
||||
{
|
||||
self.stopped = YES;
|
||||
#if TARGET_OS_IPHONE
|
||||
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
|
||||
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
#elif TARGET_OS_MAC
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
|
||||
CVDisplayLinkSetOutputCallback(self.displayLink,
|
||||
EZAudioDisplayLinkCallback,
|
||||
(__bridge void *)(self));
|
||||
CVDisplayLinkStart(self.displayLink);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)start
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
self.displayLink.paused = NO;
|
||||
#elif TARGET_OS_MAC
|
||||
CVDisplayLinkStart(self.displayLink);
|
||||
#endif
|
||||
self.stopped = NO;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)stop
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
self.displayLink.paused = YES;
|
||||
#elif TARGET_OS_MAC
|
||||
CVDisplayLinkStop(self.displayLink);
|
||||
#endif
|
||||
self.stopped = YES;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)update
|
||||
{
|
||||
if (!self.stopped)
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(displayLinkNeedsDisplay:)])
|
||||
{
|
||||
[self.delegate displayLinkNeedsDisplay:self];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - CVDisplayLink Callback (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#elif TARGET_OS_MAC
|
||||
static CVReturn EZAudioDisplayLinkCallback(CVDisplayLinkRef displayLinkRef,
|
||||
const CVTimeStamp *now,
|
||||
const CVTimeStamp *outputTime,
|
||||
CVOptionFlags flagsIn,
|
||||
CVOptionFlags *flagsOut,
|
||||
void *displayLinkContext)
|
||||
{
|
||||
EZAudioDisplayLink *displayLink = (__bridge EZAudioDisplayLink*)displayLinkContext;
|
||||
[displayLink update];
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -25,26 +25,10 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import "EZAudioFloatData.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@class EZAudio;
|
||||
@class EZAudioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Blocks
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
A block used when returning back the waveform data. The waveform data itself will be an array of float arrays, one for each channel, and the length indicates the total length of each float array.
|
||||
@param waveformData An array of float arrays, each representing a channel of audio data from the file
|
||||
@param length An int representing the length of each channel of float audio data
|
||||
*/
|
||||
typedef void (^EZAudioWaveformDataCompletionBlock)(float **waveformData, int length);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFileDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
The EZAudioFileDelegate provides event callbacks for the EZAudioFile object. These type of events are triggered by reads and seeks on the file and gives feedback such as the audio data read as a float array for visualizations and the new seek position for UI updating.
|
||||
*/
|
||||
@@ -58,159 +42,102 @@ typedef void (^EZAudioWaveformDataCompletionBlock)(float **waveformData, int len
|
||||
@param bufferSize The length of the buffers float arrays
|
||||
@param numberOfChannels The number of channels. 2 for stereo, 1 for mono.
|
||||
*/
|
||||
- (void) audioFile:(EZAudioFile *)audioFile
|
||||
readAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Occurs when the audio file's internal seek position has been updated by the EZAudioFile functions `readFrames:audioBufferList:bufferSize:eof:` or `audioFile:updatedPosition:`. As of 0.8.0 this is the preferred method of listening for position updates on the audio file since a user may want the pull the currentTime, formattedCurrentTime, or the frame index from the EZAudioFile instance provided.
|
||||
@param audioFile The instance of the EZAudio in which the change occured.
|
||||
*/
|
||||
- (void)audioFileUpdatedPosition:(EZAudioFile *)audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(void) audioFile:(EZAudioFile*)audioFile
|
||||
readAudio:(float**)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels;
|
||||
|
||||
/**
|
||||
Occurs when the audio file's internal seek position has been updated by the EZAudioFile functions `readFrames:audioBufferList:bufferSize:eof:` or `audioFile:updatedPosition:`.
|
||||
@param audioFile The instance of the EZAudio in which the change occured
|
||||
@param framePosition The new frame index as a 64-bit signed integer
|
||||
@deprecated This property is deprecated starting in version 0.8.0.
|
||||
@note Please use `audioFileUpdatedPosition:` property instead.
|
||||
*/
|
||||
- (void)audioFile:(EZAudioFile *)audioFile
|
||||
updatedPosition:(SInt64)framePosition __attribute__((deprecated));
|
||||
-(void)audioFile:(EZAudioFile*)audioFile
|
||||
updatedPosition:(SInt64)framePosition;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFile
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
The EZAudioFile provides a lightweight and intuitive way to asynchronously interact with audio files. These interactions included reading audio data, seeking within an audio file, getting information about the file, and pulling the waveform data for visualizing the contents of the audio file. The EZAudioFileDelegate provides event callbacks for when reads, seeks, and various updates happen within the audio file to allow the caller to interact with the action in meaningful ways. Common use cases here could be to read the audio file's data as AudioBufferList structures for output (see EZOutput) and visualizing the audio file's data as a float array using an audio plot (see EZAudioPlot).
|
||||
*/
|
||||
@interface EZAudioFile : NSObject <NSCopying>
|
||||
@interface EZAudioFile : NSObject
|
||||
|
||||
#pragma mark - Blocks
|
||||
/**
|
||||
A block used when returning back the waveform data. The waveform data itself will be an array of float values and the length indicates the total length of the float array.
|
||||
@param waveformData An array of float values representing the amplitude data from the audio waveform
|
||||
@param length The length of the waveform data's float array
|
||||
*/
|
||||
typedef void (^WaveformDataCompletionBlock)(float *waveformData, UInt32 length);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A EZAudioFileDelegate for the audio file that is used to return events such as new seek positions within the file and the read audio data as a float array.
|
||||
*/
|
||||
@property (nonatomic, weak) id<EZAudioFileDelegate> delegate;
|
||||
@property (nonatomic,assign) id<EZAudioFileDelegate> audioFileDelegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initialization
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
@name Initialization
|
||||
*/
|
||||
The resolution of the waveform data. This value specifies how the recommendedDrawingFrameRate chooses itself. A low value like 128 will render a waveform containing 128 points representing a low resolution waveform while a high value like 4096 will render a high quality waveform. Higher resolutions provide more detail, but take more work to render in the audio waveform plots (EZAudioPlot or EZAudioPlotGL) while lower resolutions providel less detail, but work better for displaying many at a time (like in a UITableView)
|
||||
*/
|
||||
@property (nonatomic,assign) UInt32 waveformResolution;
|
||||
|
||||
#pragma mark - Initializers
|
||||
///-----------------------------------------------------------
|
||||
/// @name Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates a new instance of the EZAudioFile using a file path URL.
|
||||
@param url The file path reference of the audio file as an NSURL.
|
||||
@return The newly created EZAudioFile instance. nil if the file path does not exist.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url;
|
||||
|
||||
/**
|
||||
Creates a new instance of the EZAudioFile using a file path URL with a delegate conforming to the EZAudioFileDelegate protocol.
|
||||
@param delegate The audio file delegate that receives events specified by the EZAudioFileDelegate protocol
|
||||
@param url The file path reference of the audio file as an NSURL.
|
||||
@return The newly created EZAudioFile instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioFileDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(EZAudioFile*)initWithURL:(NSURL*)url;
|
||||
|
||||
/**
|
||||
Creates a new instance of the EZAudioFile using a file path URL with a delegate conforming to the EZAudioFileDelegate protocol and a client format.
|
||||
Creates a new instance of the EZAudioFile using a file path URL and allows specifying an EZAudioFileDelegate.
|
||||
@param url The file path reference of the audio file as an NSURL.
|
||||
@param delegate The audio file delegate that receives events specified by the EZAudioFileDelegate protocol
|
||||
@param clientFormat An AudioStreamBasicDescription that will be used as the client format on the audio file. For instance, the audio file might be in a 22.5 kHz sample rate format in its file format, but your app wants to read the samples at a sample rate of 44.1 kHz so it can iterate with other components (like a audio processing graph) without any weird playback effects. If this initializer is not used then a non-interleaved float format will be assumed.
|
||||
@return The newly created EZAudioFile instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioFileDelegate>)delegate
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat;
|
||||
-(EZAudioFile*)initWithURL:(NSURL*)url
|
||||
andDelegate:(id<EZAudioFileDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
@name Class Initializers
|
||||
*/
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method that creates a new instance of the EZAudioFile using a file path URL.
|
||||
@param url The file path reference of the audio file as an NSURL.
|
||||
@return The newly created EZAudioFile instance.
|
||||
*/
|
||||
+ (instancetype)audioFileWithURL:(NSURL *)url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
+(EZAudioFile*)audioFileWithURL:(NSURL*)url;
|
||||
|
||||
/**
|
||||
Class method that creates a new instance of the EZAudioFile using a file path URL with a delegate conforming to the EZAudioFileDelegate protocol.
|
||||
@param url The file path reference of the audio file as an NSURL.
|
||||
Class method that creates a new instance of the EZAudioFile using a file path URL and allows specifying an EZAudioFileDelegate.
|
||||
@param url The file path reference of the audio file as an NSURL.
|
||||
@param delegate The audio file delegate that receives events specified by the EZAudioFileDelegate protocol
|
||||
@return The newly created EZAudioFile instance.
|
||||
*/
|
||||
+ (instancetype)audioFileWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioFileDelegate>)delegate;
|
||||
+(EZAudioFile*)audioFileWithURL:(NSURL*)url
|
||||
andDelegate:(id<EZAudioFileDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method that creates a new instance of the EZAudioFile using a file path URL with a delegate conforming to the EZAudioFileDelegate protocol and a client format.
|
||||
@param url The file path reference of the audio file as an NSURL.
|
||||
@param delegate The audio file delegate that receives events specified by the EZAudioFileDelegate protocol
|
||||
@param clientFormat An AudioStreamBasicDescription that will be used as the client format on the audio file. For instance, the audio file might be in a 22.5 kHz sample rate, interleaved MP3 file format, but your app wants to read linear PCM samples at a sample rate of 44.1 kHz so it can be read in the context of other components sharing a common stream format (like a audio processing graph). If this initializer is not used then the `defaultClientFormat` will be used as teh default value for the client format.
|
||||
@return The newly created EZAudioFile instance.
|
||||
*/
|
||||
+ (instancetype)audioFileWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioFileDelegate>)delegate
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Methods
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
@name Class Methods
|
||||
*/
|
||||
|
||||
/**
|
||||
A class method that subclasses can override to specify the default client format that will be used to read audio data from this file. A client format is different from the file format in that it is the format of the other components interacting with this file. For instance, the file on disk could be a 22.5 kHz, float format, but we might have an audio processing graph that has a 44.1 kHz, signed integer format that we'd like to interact with. The client format lets us set that 44.1 kHz format on the audio file to properly read samples from it with any interpolation or format conversion that must take place done automatically within the EZAudioFile `readFrames:audioBufferList:bufferSize:eof:` method. Default is stereo, non-interleaved, 44.1 kHz.
|
||||
@return An AudioStreamBasicDescription that serves as the audio file's client format.
|
||||
*/
|
||||
+ (AudioStreamBasicDescription)defaultClientFormat;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A class method that subclasses can override to specify the default sample rate that will be used in the `defaultClientFormat` method. Default is 44100.0 (44.1 kHz).
|
||||
@return A Float64 representing the sample rate that should be used in the default client format.
|
||||
*/
|
||||
+ (Float64)defaultClientFormatSampleRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Methods
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides an array of the supported audio files types. Each audio file type is provided as a string, i.e. @"caf". Useful for filtering lists of files in an open panel to only the types allowed.
|
||||
@return An array of NSString objects representing the represented file types.
|
||||
*/
|
||||
+ (NSArray *)supportedAudioFileTypes;
|
||||
+(NSArray*)supportedAudioFileTypes;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Events
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
@name Reading From The Audio File
|
||||
*/
|
||||
///-----------------------------------------------------------
|
||||
/// @name Reading The Audio File
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Reads a specified number of frames from the audio file. In addition, this will notify the EZAudioFileDelegate (if specified) of the read data as a float array with the audioFile:readAudio:withBufferSize:withNumberOfChannels: event and the new seek position within the file with the audioFile:updatedPosition: event.
|
||||
@@ -219,162 +146,96 @@ typedef void (^EZAudioWaveformDataCompletionBlock)(float **waveformData, int len
|
||||
@param bufferSize A pointer to a UInt32 in which to store the read buffersize
|
||||
@param eof A pointer to a BOOL in which to store whether the read operation reached the end of the audio file.
|
||||
*/
|
||||
- (void)readFrames:(UInt32)frames
|
||||
audioBufferList:(AudioBufferList *)audioBufferList
|
||||
bufferSize:(UInt32 *)bufferSize
|
||||
eof:(BOOL *)eof;
|
||||
-(void)readFrames:(UInt32)frames
|
||||
audioBufferList:(AudioBufferList*)audioBufferList
|
||||
bufferSize:(UInt32*)bufferSize
|
||||
eof:(BOOL*)eof;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@name Seeking Through The Audio File
|
||||
*/
|
||||
///-----------------------------------------------------------
|
||||
/// @name Seeking Through The Audio File
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Seeks through an audio file to a specified frame. This will notify the EZAudioFileDelegate (if specified) with the audioFile:updatedPosition: function.
|
||||
@param frame The new frame position to seek to as a SInt64.
|
||||
*/
|
||||
- (void)seekToFrame:(SInt64)frame;
|
||||
-(void)seekToFrame:(SInt64)frame;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Getters
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
@name Getting Information About The Audio File
|
||||
*/
|
||||
///-----------------------------------------------------------
|
||||
/// @name Getting Information About The Audio File
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the common AudioStreamBasicDescription that will be used for in-app interaction. The file's format will be converted to this format and then sent back as either a float array or a `AudioBufferList` pointer. For instance, the file on disk could be a 22.5 kHz, float format, but we might have an audio processing graph that has a 44.1 kHz, signed integer format that we'd like to interact with. The client format lets us set that 44.1 kHz format on the audio file to properly read samples from it with any interpolation or format conversion that must take place done automatically within the EZAudioFile `readFrames:audioBufferList:bufferSize:eof:` method. Default is stereo, non-interleaved, 44.1 kHz.
|
||||
@warning This must be a linear PCM format!
|
||||
Provides the AudioStreamBasicDescription structure used within the app. The file's format will be converted to this format and then sent back as either a float array or a `AudioBufferList` pointer. Use this when communicating with other EZAudio components.
|
||||
@return An AudioStreamBasicDescription structure describing the format of the audio file.
|
||||
*/
|
||||
@property (readwrite) AudioStreamBasicDescription clientFormat;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current offset in the audio file as an NSTimeInterval (i.e. in seconds). When setting this it will determine the correct frame offset and perform a `seekToFrame` to the new time offset.
|
||||
@warning Make sure the new current time offset is less than the `duration` or you will receive an invalid seek assertion.
|
||||
*/
|
||||
@property (nonatomic, readwrite) NSTimeInterval currentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration of the audio file in seconds.
|
||||
*/
|
||||
@property (readonly) NSTimeInterval duration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(AudioStreamBasicDescription)clientFormat;
|
||||
|
||||
/**
|
||||
Provides the AudioStreamBasicDescription structure containing the format of the file.
|
||||
@return An AudioStreamBasicDescription structure describing the format of the audio file.
|
||||
*/
|
||||
@property (readonly) AudioStreamBasicDescription fileFormat;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(AudioStreamBasicDescription)fileFormat;
|
||||
|
||||
/**
|
||||
Provides the current time as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedCurrentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedDuration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the frame index (a.k.a the seek positon) within the audio file as SInt64. This can be helpful when seeking through the audio file.
|
||||
Provides the frame index (a.k.a the seek positon) within the audio file as an integer. This can be helpful when seeking through the audio file.
|
||||
@return The current frame index within the audio file as a SInt64.
|
||||
*/
|
||||
@property (readonly) SInt64 frameIndex;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(SInt64)frameIndex;
|
||||
|
||||
/**
|
||||
Provides a dictionary containing the metadata (ID3) tags that are included in the header for the audio file. Typically this contains stuff like artist, title, release year, etc.
|
||||
@return An NSDictionary containing the metadata for the audio file.
|
||||
*/
|
||||
@property (readonly) NSDictionary *metadata;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(NSDictionary *)metadata;
|
||||
|
||||
/**
|
||||
Provides the total duration of the audio file in seconds.
|
||||
@deprecated This property is deprecated starting in version 0.3.0.
|
||||
@note Please use `duration` property instead.
|
||||
@return The total duration of the audio file as a Float32.
|
||||
*/
|
||||
@property (readonly) NSTimeInterval totalDuration __attribute__((deprecated));
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(Float32)totalDuration;
|
||||
|
||||
/**
|
||||
Provides the total frame count of the audio file in the client format.
|
||||
@return The total number of frames in the audio file in the AudioStreamBasicDescription representing the client format as a SInt64.
|
||||
Provides the total frame count of the audio file.
|
||||
@return The total number of frames in the audio file as a SInt64.
|
||||
*/
|
||||
@property (readonly) SInt64 totalClientFrames;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the total frame count of the audio file in the file format.
|
||||
@return The total number of frames in the audio file in the AudioStreamBasicDescription representing the file format as a SInt64.
|
||||
*/
|
||||
@property (readonly) SInt64 totalFrames;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(SInt64)totalFrames;
|
||||
|
||||
/**
|
||||
Provides the NSURL for the audio file.
|
||||
@return An NSURL representing the path of the EZAudioFile instance.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSURL *url;
|
||||
-(NSURL*)url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
///-----------------------------------------------------------
|
||||
/// @name Manipulating The Audio Data
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Synchronously pulls the waveform amplitude data into a float array for the receiver. This returns a waveform with a default resolution of 1024, meaning there are 1024 data points to plot the waveform.
|
||||
@param numberOfPoints A UInt32 representing the number of data points you need. The higher the number of points the more detailed the waveform will be.
|
||||
@return A EZAudioFloatData instance containing the audio data for all channels of the audio.
|
||||
Tells the caller whether the EZAudioFile has cached waveform data that was loaded via the getWaveformDataWithCompletionBlock: function.
|
||||
* @return A BOOL indicating whether there is cached waveform data
|
||||
*/
|
||||
- (EZAudioFloatData *)getWaveformData;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Synchronously pulls the waveform amplitude data into a float array for the receiver.
|
||||
@param numberOfPoints A UInt32 representing the number of data points you need. The higher the number of points the more detailed the waveform will be.
|
||||
@return A EZAudioFloatData instance containing the audio data for all channels of the audio.
|
||||
*/
|
||||
- (EZAudioFloatData *)getWaveformDataWithNumberOfPoints:(UInt32)numberOfPoints;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Asynchronously pulls the waveform amplitude data into a float array for the receiver. This returns a waveform with a default resolution of 1024, meaning there are 1024 data points to plot the waveform.
|
||||
@param completion A EZAudioWaveformDataCompletionBlock that executes when the waveform data has been extracted. Provides a `EZAudioFloatData` instance containing the waveform data for all audio channels.
|
||||
*/
|
||||
- (void)getWaveformDataWithCompletionBlock:(EZAudioWaveformDataCompletionBlock)completion;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(BOOL)hasLoadedAudioData;
|
||||
|
||||
/**
|
||||
Asynchronously pulls the waveform amplitude data into a float array for the receiver.
|
||||
@param numberOfPoints A UInt32 representing the number of data points you need. The higher the number of points the more detailed the waveform will be.
|
||||
@param completion A EZAudioWaveformDataCompletionBlock that executes when the waveform data has been extracted. Provides a `EZAudioFloatData` instance containing the waveform data for all audio channels.
|
||||
@param waveformDataCompletionBlock A WaveformDataCompletionBlock that executes when the waveform data has been extracted. Provides the waveform data as a float array and the length of the array.
|
||||
*/
|
||||
- (void)getWaveformDataWithNumberOfPoints:(UInt32)numberOfPoints
|
||||
completion:(EZAudioWaveformDataCompletionBlock)completion;
|
||||
-(void)getWaveformDataWithCompletionBlock:(WaveformDataCompletionBlock)waveformDataCompletionBlock;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Provides the minimum number of buffers that would be required with the constant frames read rate provided.
|
||||
@param frameRate A constant frame rate to use when calculating the number of buffers needed as a UInt32.
|
||||
@return The minimum number of buffers required for the constant frames read rate provided as a UInt32.
|
||||
*/
|
||||
-(UInt32)minBuffersWithFrameRate:(UInt32)frameRate;
|
||||
|
||||
/**
|
||||
Provides a frame rate to use when drawing and averaging a bin of values to create each point in a graph. The ideal amount of end buffers seems to be between 1000-3000 so we determine a frame rate per audio file that can achieve a high degree of detail for the entire waveform.
|
||||
@return A frame rate value as a UInt32 to use when reading frames in a file.
|
||||
*/
|
||||
-(UInt32)recommendedDrawingFrameRate;
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,712 +24,343 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "EZAudioFile.h"
|
||||
#import "AEFloatConverter.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#define kEZAudioFileWaveformDefaultResolution (1024)
|
||||
|
||||
#import "EZAudio.h"
|
||||
#import "EZAudioFloatConverter.h"
|
||||
#import "EZAudioFloatData.h"
|
||||
#include <pthread.h>
|
||||
|
||||
// constants
|
||||
static UInt32 EZAudioFileWaveformDefaultResolution = 1024;
|
||||
static NSString *EZAudioFileWaveformDataQueueIdentifier = @"com.ezaudio.waveformQueue";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AudioFileID audioFileID;
|
||||
AudioStreamBasicDescription clientFormat;
|
||||
NSTimeInterval duration;
|
||||
ExtAudioFileRef extAudioFileRef;
|
||||
AudioStreamBasicDescription fileFormat;
|
||||
SInt64 frames;
|
||||
CFURLRef sourceURL;
|
||||
} EZAudioFileInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFile
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@interface EZAudioFile ()
|
||||
@property (nonatomic, strong) EZAudioFloatConverter *floatConverter;
|
||||
@property (nonatomic) float **floatData;
|
||||
@property (nonatomic) EZAudioFileInfo *info;
|
||||
@property (nonatomic) pthread_mutex_t lock;
|
||||
@property (nonatomic) dispatch_queue_t waveformQueue;
|
||||
@interface EZAudioFile (){
|
||||
|
||||
// Reading from the audio file
|
||||
ExtAudioFileRef _audioFile;
|
||||
AudioStreamBasicDescription _clientFormat;
|
||||
AudioStreamBasicDescription _fileFormat;
|
||||
float **_floatBuffers;
|
||||
AEFloatConverter *_floatConverter;
|
||||
SInt64 _frameIndex;
|
||||
CFURLRef _sourceURL;
|
||||
Float32 _totalDuration;
|
||||
SInt64 _totalFrames;
|
||||
|
||||
// Waveform Data
|
||||
float *_waveformData;
|
||||
UInt32 _waveformFrameRate;
|
||||
UInt32 _waveformTotalBuffers;
|
||||
|
||||
}
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation EZAudioFile
|
||||
@synthesize audioFileDelegate = _audioFileDelegate;
|
||||
@synthesize waveformResolution = _waveformResolution;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
self.floatConverter = nil;
|
||||
pthread_mutex_destroy(&_lock);
|
||||
[EZAudioUtilities freeFloatBuffers:self.floatData numberOfChannels:self.clientFormat.mChannelsPerFrame];
|
||||
[EZAudioUtilities checkResult:ExtAudioFileDispose(self.info->extAudioFileRef) operation:"Failed to dispose of ext audio file"];
|
||||
free(self.info);
|
||||
#pragma mark - Initializers
|
||||
-(EZAudioFile*)initWithURL:(NSURL*)url {
|
||||
self = [super init];
|
||||
if(self){
|
||||
_sourceURL = (__bridge CFURLRef)url;
|
||||
[self _configureAudioFile];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initialization
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
self.info = (EZAudioFileInfo *)malloc(sizeof(EZAudioFileInfo));
|
||||
_floatData = NULL;
|
||||
pthread_mutex_init(&_lock, NULL);
|
||||
_waveformQueue = dispatch_queue_create(EZAudioFileWaveformDataQueueIdentifier.UTF8String, DISPATCH_QUEUE_PRIORITY_DEFAULT);
|
||||
}
|
||||
return self;
|
||||
-(EZAudioFile *)initWithURL:(NSURL *)url andDelegate:(id<EZAudioFileDelegate>)delegate {
|
||||
self = [self initWithURL:url];
|
||||
if(self){
|
||||
self.audioFileDelegate = delegate;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
{
|
||||
return [self initWithURL:url delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioFileDelegate>)delegate
|
||||
{
|
||||
return [self initWithURL:url
|
||||
delegate:delegate
|
||||
clientFormat:[self.class defaultClientFormat]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioFileDelegate>)delegate
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
{
|
||||
self = [self init];
|
||||
if (self)
|
||||
{
|
||||
self.info->sourceURL = (__bridge CFURLRef)(url);
|
||||
self.info->clientFormat = clientFormat;
|
||||
self.delegate = delegate;
|
||||
if (![self setup])
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioFileWithURL:(NSURL *)url
|
||||
{
|
||||
return [[self alloc] initWithURL:url];
|
||||
+(EZAudioFile*)audioFileWithURL:(NSURL*)url {
|
||||
return [[EZAudioFile alloc] initWithURL:url];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioFileWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioFileDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithURL:url delegate:delegate];
|
||||
+(EZAudioFile *)audioFileWithURL:(NSURL *)url andDelegate:(id<EZAudioFileDelegate>)delegate {
|
||||
return [[EZAudioFile alloc] initWithURL:url andDelegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioFileWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioFileDelegate>)delegate
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
{
|
||||
return [[self alloc] initWithURL:url
|
||||
delegate:delegate
|
||||
clientFormat:clientFormat];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - NSCopying
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
return [EZAudioFile audioFileWithURL:self.url];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Methods
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (AudioStreamBasicDescription)defaultClientFormat
|
||||
{
|
||||
return [EZAudioUtilities stereoFloatNonInterleavedFormatWithSampleRate:[self defaultClientFormatSampleRate]];
|
||||
+(NSArray *)supportedAudioFileTypes {
|
||||
return @[ @"aac",
|
||||
@"caf",
|
||||
@"aif",
|
||||
@"aiff",
|
||||
@"aifc",
|
||||
@"mp3",
|
||||
@"mp4",
|
||||
@"m4a",
|
||||
@"snd",
|
||||
@"au",
|
||||
@"sd2",
|
||||
@"wav" ];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (Float64)defaultClientFormatSampleRate
|
||||
{
|
||||
return 44100.0f;
|
||||
#pragma mark - Private Configuation
|
||||
-(void)_configureAudioFile {
|
||||
|
||||
// Source URL should not be nil
|
||||
NSAssert(_sourceURL,@"Source URL was not specified correctly.");
|
||||
|
||||
// Try to open the file for reading
|
||||
[EZAudioUtilities checkResult:ExtAudioFileOpenURL(_sourceURL,&_audioFile)
|
||||
operation:"Failed to open audio file for reading"];
|
||||
|
||||
// Try pulling the stream description
|
||||
UInt32 size = sizeof(_fileFormat);
|
||||
[EZAudioUtilities checkResult:ExtAudioFileGetProperty(_audioFile,kExtAudioFileProperty_FileDataFormat, &size, &_fileFormat)
|
||||
operation:"Failed to get audio stream basic description of input file"];
|
||||
|
||||
// Try pulling the total frame size
|
||||
size = sizeof(_totalFrames);
|
||||
[EZAudioUtilities checkResult:ExtAudioFileGetProperty(_audioFile,kExtAudioFileProperty_FileLengthFrames, &size, &_totalFrames)
|
||||
operation:"Failed to get total frames of input file"];
|
||||
_totalFrames = MAX(1, _totalFrames);
|
||||
|
||||
// Total duration
|
||||
_totalDuration = _totalFrames / _fileFormat.mSampleRate;
|
||||
|
||||
// Set the client format on the stream
|
||||
switch (_fileFormat.mChannelsPerFrame) {
|
||||
case 1:
|
||||
_clientFormat = [EZAudioUtilities monoFloatFormatWithSampleRate:_fileFormat.mSampleRate];
|
||||
break;
|
||||
case 2:
|
||||
_clientFormat = [EZAudioUtilities stereoFloatInterleavedFormatWithSampleRate:_fileFormat.mSampleRate];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSetProperty(_audioFile,
|
||||
kExtAudioFileProperty_ClientDataFormat,
|
||||
sizeof (AudioStreamBasicDescription),
|
||||
&_clientFormat)
|
||||
operation:"Couldn't set client data format on input ext file"];
|
||||
|
||||
// Allocate the float buffers
|
||||
_floatConverter = [[AEFloatConverter alloc] initWithSourceFormat:_clientFormat];
|
||||
size_t sizeToAllocate = sizeof(float*) * _clientFormat.mChannelsPerFrame;
|
||||
sizeToAllocate = MAX(8, sizeToAllocate);
|
||||
_floatBuffers = (float**)malloc( sizeToAllocate);
|
||||
UInt32 outputBufferSize = 32 * 1024; // 32 KB
|
||||
for ( int i=0; i< _clientFormat.mChannelsPerFrame; i++) {
|
||||
_floatBuffers[i] = (float*)malloc(outputBufferSize);
|
||||
}
|
||||
|
||||
[EZAudioUtilities printASBD:_fileFormat];
|
||||
|
||||
// There's no waveform data yet
|
||||
_waveformData = NULL;
|
||||
|
||||
// Set the default resolution for the waveform data
|
||||
_waveformResolution = kEZAudioFileWaveformDefaultResolution;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (NSArray *)supportedAudioFileTypes
|
||||
{
|
||||
return @
|
||||
[
|
||||
@"aac",
|
||||
@"caf",
|
||||
@"aif",
|
||||
@"aiff",
|
||||
@"aifc",
|
||||
@"mp3",
|
||||
@"mp4",
|
||||
@"m4a",
|
||||
@"snd",
|
||||
@"au",
|
||||
@"sd2",
|
||||
@"wav"
|
||||
];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (BOOL)setup
|
||||
{
|
||||
//
|
||||
// Try to open the file, bail if the file could not be opened
|
||||
//
|
||||
BOOL success = [self openAudioFile];
|
||||
if (!success)
|
||||
{
|
||||
return success;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the client format
|
||||
//
|
||||
self.clientFormat = self.info->clientFormat;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Creating/Opening Audio File
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (BOOL)openAudioFile
|
||||
{
|
||||
//
|
||||
// Need a source url
|
||||
//
|
||||
NSAssert(self.info->sourceURL, @"EZAudioFile cannot be created without a source url!");
|
||||
|
||||
//
|
||||
// Determine if the file actually exists
|
||||
//
|
||||
CFURLRef url = self.info->sourceURL;
|
||||
NSURL *fileURL = (__bridge NSURL *)(url);
|
||||
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:fileURL.path];
|
||||
|
||||
//
|
||||
// Create an ExtAudioFileRef for the file handle
|
||||
//
|
||||
if (fileExists)
|
||||
{
|
||||
[EZAudioUtilities checkResult:ExtAudioFileOpenURL(url, &self.info->extAudioFileRef)
|
||||
operation:"Failed to create ExtAudioFileRef"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the underlying AudioFileID
|
||||
//
|
||||
UInt32 propSize = sizeof(self.info->audioFileID);
|
||||
[EZAudioUtilities checkResult:ExtAudioFileGetProperty(self.info->extAudioFileRef,
|
||||
kExtAudioFileProperty_AudioFile,
|
||||
&propSize,
|
||||
&self.info->audioFileID)
|
||||
operation:"Failed to get underlying AudioFileID"];
|
||||
|
||||
//
|
||||
// Store the file format
|
||||
//
|
||||
propSize = sizeof(self.info->fileFormat);
|
||||
[EZAudioUtilities checkResult:ExtAudioFileGetProperty(self.info->extAudioFileRef,
|
||||
kExtAudioFileProperty_FileDataFormat,
|
||||
&propSize,
|
||||
&self.info->fileFormat)
|
||||
operation:"Failed to get file audio format on existing audio file"];
|
||||
|
||||
//
|
||||
// Get the total frames and duration
|
||||
//
|
||||
propSize = sizeof(SInt64);
|
||||
[EZAudioUtilities checkResult:ExtAudioFileGetProperty(self.info->extAudioFileRef,
|
||||
kExtAudioFileProperty_FileLengthFrames,
|
||||
&propSize,
|
||||
&self.info->frames)
|
||||
operation:"Failed to get total frames"];
|
||||
self.info->duration = (NSTimeInterval) self.info->frames / self.info->fileFormat.mSampleRate;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Events
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)readFrames:(UInt32)frames
|
||||
audioBufferList:(AudioBufferList *)audioBufferList
|
||||
bufferSize:(UInt32 *)bufferSize
|
||||
eof:(BOOL *)eof
|
||||
{
|
||||
if (pthread_mutex_trylock(&_lock) == 0)
|
||||
{
|
||||
// perform read
|
||||
[EZAudioUtilities checkResult:ExtAudioFileRead(self.info->extAudioFileRef,
|
||||
&frames,
|
||||
audioBufferList)
|
||||
operation:"Failed to read audio data from file"];
|
||||
*bufferSize = frames;
|
||||
*eof = frames == 0;
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(audioFileUpdatedPosition:)])
|
||||
{
|
||||
[self.delegate audioFileUpdatedPosition:self];
|
||||
}
|
||||
|
||||
//
|
||||
// Deprecated, but supported until 1.0
|
||||
//
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
if ([self.delegate respondsToSelector:@selector(audioFile:updatedPosition:)])
|
||||
{
|
||||
[self.delegate audioFile:self updatedPosition:[self frameIndex]];
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(audioFile:readAudio:withBufferSize:withNumberOfChannels:)])
|
||||
{
|
||||
// convert into float data
|
||||
[self.floatConverter convertDataFromAudioBufferList:audioBufferList
|
||||
withNumberOfFrames:*bufferSize
|
||||
toFloatBuffers:self.floatData];
|
||||
|
||||
// notify delegate
|
||||
UInt32 channels = self.clientFormat.mChannelsPerFrame;
|
||||
[self.delegate audioFile:self
|
||||
readAudio:self.floatData
|
||||
withBufferSize:*bufferSize
|
||||
withNumberOfChannels:channels];
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_lock);
|
||||
|
||||
-(void)readFrames:(UInt32)frames
|
||||
audioBufferList:(AudioBufferList *)audioBufferList
|
||||
bufferSize:(UInt32 *)bufferSize
|
||||
eof:(BOOL *)eof {
|
||||
[EZAudioUtilities checkResult:ExtAudioFileRead(_audioFile,
|
||||
&frames,
|
||||
audioBufferList)
|
||||
operation:"Failed to read audio data from audio file"];
|
||||
*bufferSize = audioBufferList->mBuffers[0].mDataByteSize/sizeof(float);
|
||||
*eof = frames == 0;
|
||||
_frameIndex += frames;
|
||||
if (self.audioFileDelegate){
|
||||
if ([self.audioFileDelegate respondsToSelector:@selector(audioFile:updatedPosition:)]){
|
||||
[self.audioFileDelegate audioFile:self
|
||||
updatedPosition:_frameIndex];
|
||||
}
|
||||
if ([self.audioFileDelegate respondsToSelector:@selector(audioFile:readAudio:withBufferSize:withNumberOfChannels:)]){
|
||||
AEFloatConverterToFloat(_floatConverter,audioBufferList,_floatBuffers,frames);
|
||||
[self.audioFileDelegate audioFile:self
|
||||
readAudio:_floatBuffers
|
||||
withBufferSize:frames
|
||||
withNumberOfChannels:_clientFormat.mChannelsPerFrame];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)seekToFrame:(SInt64)frame
|
||||
{
|
||||
if (pthread_mutex_trylock(&_lock) == 0)
|
||||
{
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSeek(self.info->extAudioFileRef,
|
||||
frame)
|
||||
operation:"Failed to seek frame position within audio file"];
|
||||
|
||||
pthread_mutex_unlock(&_lock);
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(audioFileUpdatedPosition:)])
|
||||
{
|
||||
[self.delegate audioFileUpdatedPosition:self];
|
||||
}
|
||||
|
||||
//
|
||||
// Deprecated, but supported until 1.0
|
||||
//
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
if ([self.delegate respondsToSelector:@selector(audioFile:updatedPosition:)])
|
||||
{
|
||||
[self.delegate audioFile:self updatedPosition:[self frameIndex]];
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
-(void)seekToFrame:(SInt64)frame {
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSeek(_audioFile,frame)
|
||||
operation:"Failed to seek frame position within audio file"];
|
||||
_frameIndex = frame;
|
||||
if (self.audioFileDelegate){
|
||||
if ([self.audioFileDelegate respondsToSelector:@selector(audioFile:updatedPosition:)]){
|
||||
[self.audioFileDelegate audioFile:self updatedPosition:_frameIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Getters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (AudioStreamBasicDescription)floatFormat
|
||||
{
|
||||
return [EZAudioUtilities stereoFloatNonInterleavedFormatWithSampleRate:44100.0f];
|
||||
-(BOOL)hasLoadedAudioData {
|
||||
return _waveformData != NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (EZAudioFloatData *)getWaveformData
|
||||
{
|
||||
return [self getWaveformDataWithNumberOfPoints:EZAudioFileWaveformDefaultResolution];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (EZAudioFloatData *)getWaveformDataWithNumberOfPoints:(UInt32)numberOfPoints
|
||||
{
|
||||
EZAudioFloatData *waveformData;
|
||||
if (pthread_mutex_trylock(&_lock) == 0)
|
||||
{
|
||||
// store current frame
|
||||
SInt64 currentFrame = self.frameIndex;
|
||||
BOOL interleaved = [EZAudioUtilities isInterleaved:self.clientFormat];
|
||||
UInt32 channels = self.clientFormat.mChannelsPerFrame;
|
||||
if (channels == 0)
|
||||
{
|
||||
// prevent division by zero
|
||||
pthread_mutex_unlock(&_lock);
|
||||
return nil;
|
||||
}
|
||||
float **data = (float **)malloc( sizeof(float*) * channels );
|
||||
for (int i = 0; i < channels; i++)
|
||||
{
|
||||
data[i] = (float *)malloc( sizeof(float) * numberOfPoints );
|
||||
}
|
||||
|
||||
// seek to 0
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSeek(self.info->extAudioFileRef,
|
||||
0)
|
||||
operation:"Failed to seek frame position within audio file"];
|
||||
|
||||
// calculate the required number of frames per buffer
|
||||
SInt64 framesPerBuffer = ((SInt64) self.totalClientFrames / numberOfPoints);
|
||||
SInt64 framesPerChannel = framesPerBuffer / channels;
|
||||
|
||||
// allocate an audio buffer list
|
||||
AudioBufferList *audioBufferList = [EZAudioUtilities audioBufferListWithNumberOfFrames:(UInt32)framesPerBuffer
|
||||
numberOfChannels:self.info->clientFormat.mChannelsPerFrame
|
||||
interleaved:interleaved];
|
||||
|
||||
// read through file and calculate rms at each point
|
||||
for (SInt64 i = 0; i < numberOfPoints; i++)
|
||||
{
|
||||
UInt32 bufferSize = (UInt32) framesPerBuffer;
|
||||
[EZAudioUtilities checkResult:ExtAudioFileRead(self.info->extAudioFileRef,
|
||||
&bufferSize,
|
||||
audioBufferList)
|
||||
operation:"Failed to read audio data from file waveform"];
|
||||
if (interleaved)
|
||||
{
|
||||
float *buffer = (float *)audioBufferList->mBuffers[0].mData;
|
||||
for (int channel = 0; channel < channels; channel++)
|
||||
{
|
||||
float channelData[framesPerChannel];
|
||||
for (int frame = 0; frame < framesPerChannel; frame++)
|
||||
{
|
||||
channelData[frame] = buffer[frame * channels + channel];
|
||||
}
|
||||
float rms = [EZAudioUtilities RMS:channelData length:(UInt32)framesPerChannel];
|
||||
data[channel][i] = rms;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int channel = 0; channel < channels; channel++)
|
||||
{
|
||||
float *channelData = audioBufferList->mBuffers[channel].mData;
|
||||
float rms = [EZAudioUtilities RMS:channelData length:bufferSize];
|
||||
data[channel][i] = rms;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean up
|
||||
[EZAudioUtilities freeBufferList:audioBufferList];
|
||||
|
||||
// seek back to previous position
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSeek(self.info->extAudioFileRef,
|
||||
currentFrame)
|
||||
operation:"Failed to seek frame position within audio file"];
|
||||
|
||||
pthread_mutex_unlock(&_lock);
|
||||
|
||||
waveformData = [EZAudioFloatData dataWithNumberOfChannels:channels
|
||||
buffers:(float **)data
|
||||
bufferSize:numberOfPoints];
|
||||
|
||||
// cleanup
|
||||
for (int i = 0; i < channels; i++)
|
||||
{
|
||||
free(data[i]);
|
||||
}
|
||||
free(data);
|
||||
-(void)getWaveformDataWithCompletionBlock:(WaveformDataCompletionBlock)waveformDataCompletionBlock {
|
||||
|
||||
SInt64 currentFramePosition = _frameIndex;
|
||||
|
||||
if (_waveformData != NULL){
|
||||
waveformDataCompletionBlock( _waveformData, _waveformTotalBuffers);
|
||||
return;
|
||||
}
|
||||
|
||||
_waveformFrameRate = [self recommendedDrawingFrameRate];
|
||||
_waveformTotalBuffers = [self minBuffersWithFrameRate:_waveformFrameRate];
|
||||
_waveformData = (float*)malloc(sizeof(float)*_waveformTotalBuffers);
|
||||
|
||||
if (self.totalFrames == 0){
|
||||
waveformDataCompletionBlock( _waveformData, _waveformTotalBuffers);
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0ul), ^{
|
||||
|
||||
for( int i = 0; i < _waveformTotalBuffers; i++){
|
||||
|
||||
// Take a snapshot of each buffer through the audio file to form the waveform
|
||||
AudioBufferList *bufferList = [EZAudioUtilities audioBufferListWithNumberOfFrames:_waveformFrameRate
|
||||
numberOfChannels:_clientFormat.mChannelsPerFrame
|
||||
interleaved:YES];
|
||||
UInt32 bufferSize;
|
||||
BOOL eof;
|
||||
|
||||
// Read in the specified number of frames
|
||||
[EZAudioUtilities checkResult:ExtAudioFileRead(_audioFile,
|
||||
&_waveformFrameRate,
|
||||
bufferList)
|
||||
operation:"Failed to read audio data from audio file"];
|
||||
bufferSize = bufferList->mBuffers[0].mDataByteSize/sizeof(float);
|
||||
bufferSize = MAX(1, bufferSize);
|
||||
eof = _waveformFrameRate == 0;
|
||||
_frameIndex += _waveformFrameRate;
|
||||
|
||||
// Calculate RMS of each buffer
|
||||
float rms = [EZAudioUtilities RMS:bufferList->mBuffers[0].mData
|
||||
length:bufferSize];
|
||||
_waveformData[i] = rms;
|
||||
|
||||
// Since we malloc'ed, we should cleanup
|
||||
[EZAudioUtilities freeBufferList:bufferList];
|
||||
|
||||
}
|
||||
return waveformData;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)getWaveformDataWithCompletionBlock:(EZAudioWaveformDataCompletionBlock)waveformDataCompletionBlock
|
||||
{
|
||||
[self getWaveformDataWithNumberOfPoints:EZAudioFileWaveformDefaultResolution
|
||||
completion:waveformDataCompletionBlock];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)getWaveformDataWithNumberOfPoints:(UInt32)numberOfPoints
|
||||
completion:(EZAudioWaveformDataCompletionBlock)completion
|
||||
{
|
||||
if (!completion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// async get waveform data
|
||||
__weak EZAudioFile *weakSelf = self;
|
||||
dispatch_async(self.waveformQueue, ^{
|
||||
EZAudioFloatData *waveformData = [weakSelf getWaveformDataWithNumberOfPoints:numberOfPoints];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(waveformData.buffers, waveformData.bufferSize);
|
||||
});
|
||||
|
||||
// Seek the audio file back to the beginning
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSeek(_audioFile,currentFramePosition)
|
||||
operation:"Failed to seek frame position within audio file"];
|
||||
_frameIndex = currentFramePosition;
|
||||
|
||||
// Once we're done send off the waveform data
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
waveformDataCompletionBlock( _waveformData, _waveformTotalBuffers);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (AudioStreamBasicDescription)clientFormat
|
||||
{
|
||||
return self.info->clientFormat;
|
||||
-(AudioStreamBasicDescription)clientFormat {
|
||||
return _clientFormat;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)currentTime
|
||||
{
|
||||
return [EZAudioUtilities MAP:(float)[self frameIndex]
|
||||
leftMin:0.0f
|
||||
leftMax:(float)[self totalFrames]
|
||||
rightMin:0.0f
|
||||
rightMax:[self duration]];
|
||||
-(AudioStreamBasicDescription)fileFormat {
|
||||
return _fileFormat;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)duration
|
||||
{
|
||||
return self.info->duration;
|
||||
-(SInt64)frameIndex {
|
||||
return _frameIndex;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (AudioStreamBasicDescription)fileFormat
|
||||
-(NSDictionary *)metadata
|
||||
{
|
||||
return self.info->fileFormat;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedCurrentTime
|
||||
{
|
||||
return [EZAudioUtilities displayTimeStringFromSeconds:[self currentTime]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedDuration
|
||||
{
|
||||
return [EZAudioUtilities displayTimeStringFromSeconds:[self duration]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)frameIndex
|
||||
{
|
||||
SInt64 frameIndex;
|
||||
[EZAudioUtilities checkResult:ExtAudioFileTell(self.info->extAudioFileRef, &frameIndex)
|
||||
operation:"Failed to get frame index"];
|
||||
return frameIndex;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSDictionary *)metadata
|
||||
{
|
||||
// get size of metadata property (dictionary)
|
||||
UInt32 propSize = sizeof(self.info->audioFileID);
|
||||
AudioFileID audioFileID;
|
||||
UInt32 propSize = sizeof(audioFileID);
|
||||
[EZAudioUtilities checkResult:ExtAudioFileGetProperty(_audioFile,
|
||||
kExtAudioFileProperty_AudioFile,
|
||||
&propSize,
|
||||
&audioFileID)
|
||||
operation:"Failed to get audio file id"];
|
||||
|
||||
CFDictionaryRef metadata;
|
||||
UInt32 writable;
|
||||
[EZAudioUtilities checkResult:AudioFileGetPropertyInfo(self.info->audioFileID,
|
||||
kAudioFilePropertyInfoDictionary,
|
||||
&propSize,
|
||||
&writable)
|
||||
operation:"Failed to get the size of the metadata dictionary"];
|
||||
UInt32 isWritable;
|
||||
[EZAudioUtilities checkResult:AudioFileGetPropertyInfo(audioFileID,
|
||||
kAudioFilePropertyInfoDictionary,
|
||||
&propSize,
|
||||
&isWritable)
|
||||
operation:"Failed to get the size of the metadata dictionary"];
|
||||
|
||||
// pull metadata
|
||||
[EZAudioUtilities checkResult:AudioFileGetProperty(self.info->audioFileID,
|
||||
kAudioFilePropertyInfoDictionary,
|
||||
&propSize,
|
||||
&metadata)
|
||||
operation:"Failed to get metadata dictionary"];
|
||||
[EZAudioUtilities checkResult:AudioFileGetProperty(audioFileID,
|
||||
kAudioFilePropertyInfoDictionary,
|
||||
&propSize,
|
||||
&metadata)
|
||||
operation:"Failed to get metadata dictionary"];
|
||||
|
||||
// cast to NSDictionary
|
||||
return (__bridge NSDictionary*)metadata;
|
||||
return (__bridge NSDictionary *)metadata;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)totalDuration
|
||||
{
|
||||
return self.info->duration;
|
||||
-(Float32)totalDuration {
|
||||
return _totalDuration;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)totalClientFrames
|
||||
{
|
||||
SInt64 totalFrames = [self totalFrames];
|
||||
AudioStreamBasicDescription clientFormat = self.info->clientFormat;
|
||||
AudioStreamBasicDescription fileFormat = self.info->fileFormat;
|
||||
BOOL sameSampleRate = clientFormat.mSampleRate == fileFormat.mSampleRate;
|
||||
if (!sameSampleRate)
|
||||
{
|
||||
totalFrames = self.info->duration * clientFormat.mSampleRate;
|
||||
}
|
||||
return totalFrames;
|
||||
-(SInt64)totalFrames {
|
||||
return _totalFrames;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)totalFrames
|
||||
{
|
||||
return self.info->frames;
|
||||
-(NSURL *)url {
|
||||
return (__bridge NSURL*)_sourceURL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSURL *)url
|
||||
{
|
||||
return (__bridge NSURL*)self.info->sourceURL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setClientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
{
|
||||
//
|
||||
// Clear any float data currently cached
|
||||
//
|
||||
if (self.floatData)
|
||||
{
|
||||
self.floatData = nil;
|
||||
-(void)setWaveformResolution:(UInt32)waveformResolution {
|
||||
if (_waveformResolution != waveformResolution){
|
||||
_waveformResolution = waveformResolution;
|
||||
if (_waveformData){
|
||||
free(_waveformData);
|
||||
_waveformData = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Client format can only be linear PCM!
|
||||
//
|
||||
NSAssert([EZAudioUtilities isLinearPCM:clientFormat], @"Client format must be linear PCM");
|
||||
|
||||
//
|
||||
// Store the client format
|
||||
//
|
||||
self.info->clientFormat = clientFormat;
|
||||
|
||||
//
|
||||
// Set the client format on the ExtAudioFileRef
|
||||
//
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSetProperty(self.info->extAudioFileRef,
|
||||
kExtAudioFileProperty_ClientDataFormat,
|
||||
sizeof(clientFormat),
|
||||
&clientFormat)
|
||||
operation:"Couldn't set client data format on file"];
|
||||
|
||||
//
|
||||
// Create a new float converter using the client format as the input format
|
||||
//
|
||||
self.floatConverter = [EZAudioFloatConverter converterWithInputFormat:clientFormat];
|
||||
|
||||
//
|
||||
// Determine how big our float buffers need to be to hold a buffer of float
|
||||
// data for the audio received callback.
|
||||
//
|
||||
UInt32 maxPacketSize;
|
||||
UInt32 propSize = sizeof(maxPacketSize);
|
||||
[EZAudioUtilities checkResult:ExtAudioFileGetProperty(self.info->extAudioFileRef,
|
||||
kExtAudioFileProperty_ClientMaxPacketSize,
|
||||
&propSize,
|
||||
&maxPacketSize)
|
||||
operation:"Failed to get max packet size"];
|
||||
|
||||
self.floatData = [EZAudioUtilities floatBuffersWithNumberOfFrames:1024
|
||||
numberOfChannels:self.clientFormat.mChannelsPerFrame];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setCurrentTime:(NSTimeInterval)currentTime
|
||||
{
|
||||
NSAssert(currentTime < [self duration], @"Invalid seek operation, expected current time to be less than duration");
|
||||
SInt64 frame = [EZAudioUtilities MAP:currentTime
|
||||
leftMin:0.0f
|
||||
leftMax:[self duration]
|
||||
rightMin:0.0f
|
||||
rightMax:[self totalFrames]];
|
||||
[self seekToFrame:frame];
|
||||
#pragma mark - Helpers
|
||||
-(UInt32)minBuffersWithFrameRate:(UInt32)frameRate {
|
||||
frameRate = frameRate > 0 ? frameRate : 1;
|
||||
UInt32 val = (UInt32) _totalFrames / frameRate + 1;
|
||||
return MAX(1, val);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Description
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ {\n"
|
||||
" url: %@,\n"
|
||||
" duration: %f,\n"
|
||||
" totalFrames: %lld,\n"
|
||||
" metadata: %@,\n"
|
||||
" fileFormat: { %@ },\n"
|
||||
" clientFormat: { %@ } \n"
|
||||
"}",
|
||||
[super description],
|
||||
[self url],
|
||||
[self duration],
|
||||
[self totalFrames],
|
||||
[self metadata],
|
||||
[EZAudioUtilities stringForAudioStreamBasicDescription:[self fileFormat]],
|
||||
[EZAudioUtilities stringForAudioStreamBasicDescription:[self clientFormat]]];
|
||||
-(UInt32)recommendedDrawingFrameRate {
|
||||
UInt32 val = 1;
|
||||
if(_waveformResolution > 0){
|
||||
val = (UInt32) _totalFrames / _waveformResolution;
|
||||
if(val > 1)
|
||||
--val;
|
||||
}
|
||||
return MAX(1, val);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Cleanup
|
||||
-(void)dealloc {
|
||||
if (_waveformData){
|
||||
free(_waveformData);
|
||||
_waveformData = NULL;
|
||||
}
|
||||
// if (_floatBuffers){
|
||||
// free(_floatBuffers);
|
||||
// _floatBuffers = NULL;
|
||||
// }
|
||||
_frameIndex = 0;
|
||||
_waveformFrameRate = 0;
|
||||
_waveformTotalBuffers = 0;
|
||||
if (_audioFile){
|
||||
[EZAudioUtilities checkResult:ExtAudioFileDispose(_audioFile)
|
||||
operation:"Failed to dispose of audio file"];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/23/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/23/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -58,12 +58,9 @@ OSStatus EZAudioFloatConverterCallback(AudioConverterRef inAudioConv
|
||||
void *inUserData)
|
||||
{
|
||||
AudioBufferList *sourceBuffer = (AudioBufferList *)inUserData;
|
||||
|
||||
memcpy(ioData,
|
||||
sourceBuffer,
|
||||
sizeof(AudioBufferList) + (sourceBuffer->mNumberBuffers - 1) * sizeof(AudioBuffer));
|
||||
sourceBuffer = NULL;
|
||||
|
||||
sizeof(AudioBufferList) + (sourceBuffer->mNumberBuffers - 1)*sizeof(AudioBuffer));
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@@ -200,19 +197,12 @@ OSStatus EZAudioFloatConverterCallback(AudioConverterRef inAudioConv
|
||||
toFloatBuffers:(float **)buffers
|
||||
packetDescriptions:(AudioStreamPacketDescription *)packetDescriptions
|
||||
{
|
||||
if (frames != 0)
|
||||
if (frames == 0)
|
||||
{
|
||||
//
|
||||
// Make sure the data size coming in is consistent with the number
|
||||
// of frames we're actually getting
|
||||
//
|
||||
for (int i = 0; i < audioBufferList->mNumberBuffers; i++) {
|
||||
audioBufferList->mBuffers[i].mDataByteSize = frames * self.info->inputFormat.mBytesPerFrame;
|
||||
}
|
||||
|
||||
//
|
||||
// Fill out the audio converter with the source buffer
|
||||
//
|
||||
}
|
||||
else
|
||||
{
|
||||
[EZAudioUtilities checkResult:AudioConverterFillComplexBuffer(self.info->converterRef,
|
||||
EZAudioFloatConverterCallback,
|
||||
audioBufferList,
|
||||
@@ -220,11 +210,6 @@ OSStatus EZAudioFloatConverterCallback(AudioConverterRef inAudioConv
|
||||
self.info->floatAudioBufferList,
|
||||
packetDescriptions ? packetDescriptions : self.info->packetDescriptions)
|
||||
operation:"Failed to fill complex buffer in float converter"];
|
||||
|
||||
//
|
||||
// Copy the converted buffers into the float buffer array stored
|
||||
// in memory
|
||||
//
|
||||
for (int i = 0; i < self.info->floatAudioBufferList->mNumberBuffers; i++)
|
||||
{
|
||||
memcpy(buffers[i],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/23/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/23/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
//
|
||||
// EZAudioOSX.m
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Tommaso Piazza on 30/09/15.
|
||||
// Copyright © 2015 Andrew Breckenridge. 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 <EZAudioOSX/EZAudio.h>
|
||||
@@ -28,74 +28,41 @@
|
||||
#import "EZAudioFile.h"
|
||||
#import "EZOutput.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
|
||||
@class EZAudioPlayer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Data Structures
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
typedef NS_ENUM(NSUInteger, EZAudioPlayerState)
|
||||
{
|
||||
EZAudioPlayerStateEndOfFile,
|
||||
EZAudioPlayerStatePaused,
|
||||
EZAudioPlayerStatePlaying,
|
||||
EZAudioPlayerStateReadyToPlay,
|
||||
EZAudioPlayerStateSeeking,
|
||||
EZAudioPlayerStateUnknown,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Notifications
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `audioFile` property. Check the new value using the EZAudioPlayer's `audioFile` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangeAudioFileNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `device` property. Check the new value using the EZAudioPlayer's `device` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangeOutputDeviceNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `output` component's `pan` property. Check the new value using the EZAudioPlayer's `pan` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangePanNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `output` component's play state. Check the new value using the EZAudioPlayer's `isPlaying` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangePlayStateNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer changes its `output` component's `volume` property. Check the new value using the EZAudioPlayer's `volume` property.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidChangeVolumeNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer has reached the end of a file and its `shouldLoop` property has been set to NO.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidReachEndOfFileNotification;
|
||||
|
||||
/**
|
||||
Notification that occurs whenever the EZAudioPlayer performs a seek via the `seekToFrame` method or `setCurrentTime:` property setter. Check the new `currentTime` or `frameIndex` value using the EZAudioPlayer's `currentTime` or `frameIndex` property, respectively.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * const EZAudioPlayerDidSeekNotification;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayerDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioPlayerDelegate provides event callbacks for the EZAudioPlayer. Since 0.5.0 the EZAudioPlayerDelegate provides a smaller set of delegate methods in favor of notifications to allow multiple receivers of the EZAudioPlayer event callbacks since only one player is typically used in an application. Specifically, these methods are provided for high frequency callbacks that wrap the EZAudioPlayer's internal EZAudioFile and EZOutput instances.
|
||||
The EZAudioPlayerDelegate provides event callbacks for the EZAudioPlayer. These type of events are triggered by changes in the EZAudioPlayer's state and allow someone implementing the EZAudioPlayer to more easily update their user interface. Events are triggered anytime the EZAudioPlayer resumes/pauses playback, reaches the end of the file, reads audio data and converts it to float data visualizations (using the EZAudioFile), and updates its cursor position within the audio file during playback (use this for the play position on a slider on the user interface).
|
||||
@warning These callbacks don't necessarily occur on the main thread so make sure you wrap any UI code in a GCD block like: dispatch_async(dispatch_get_main_queue(), ^{ // Update UI });
|
||||
*/
|
||||
@protocol EZAudioPlayerDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
/**
|
||||
Triggered by the EZAudioPlayer when the playback has been resumed or started.
|
||||
@param audioPlayer The instance of the EZAudioPlayer that triggered the event
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
-(void)audioPlayer:(EZAudioPlayer*)audioPlayer didResumePlaybackOnAudioFile:(EZAudioFile*)audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Triggered by the EZAudioPlayer when the playback has been paused.
|
||||
@param audioPlayer The instance of the EZAudioPlayer that triggered the event
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
-(void)audioPlayer:(EZAudioPlayer*)audioPlayer didPausePlaybackOnAudioFile:(EZAudioFile*)audioFile;
|
||||
|
||||
/**
|
||||
Triggered by the EZAudioPlayer when the output has reached the end of the EZAudioFile it's playing. If the EZAudioPlayer has its `shouldLoop` property set to true this will trigger, but playback will continue to loop once its hit the end of the audio file.
|
||||
@param audioPlayer The instance of the EZAudioPlayer that triggered the event
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
-(void)audioPlayer:(EZAudioPlayer*)audioPlayer reachedEndOfAudioFile:(EZAudioFile*)audioFile;
|
||||
|
||||
/**
|
||||
Triggered by the EZAudioPlayer's internal EZAudioFile's EZAudioFileDelegate callback and notifies the delegate of the read audio data as a float array instead of a buffer list. Common use case of this would be to visualize the float data using an audio plot or audio data dependent OpenGL sketch.
|
||||
@@ -105,13 +72,11 @@ FOUNDATION_EXPORT NSString * const EZAudioPlayerDidSeekNotification;
|
||||
@param numberOfChannels The number of channels. 2 for stereo, 1 for mono.
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
- (void) audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
playedAudio:(float **)buffer
|
||||
-(void) audioPlayer:(EZAudioPlayer*)audioPlayer
|
||||
readAudio:(float**)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
inAudioFile:(EZAudioFile *)audioFile;;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inAudioFile:(EZAudioFile*)audioFile;;
|
||||
|
||||
/**
|
||||
Triggered by EZAudioPlayer's internal EZAudioFile's EZAudioFileDelegate callback and notifies the delegate of the current playback position. The framePosition provides the current frame position and can be calculated against the EZAudioPlayer's total frames using the `totalFrames` function from the EZAudioPlayer.
|
||||
@@ -119,36 +84,18 @@ FOUNDATION_EXPORT NSString * const EZAudioPlayerDidSeekNotification;
|
||||
@param framePosition The new frame index as a 64-bit signed integer
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
- (void)audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
updatedPosition:(SInt64)framePosition
|
||||
inAudioFile:(EZAudioFile *)audioFile;
|
||||
|
||||
|
||||
/**
|
||||
Triggered by EZAudioPlayer's internal EZAudioFile's EZAudioFileDelegate callback and notifies the delegate that the end of the file has been reached.
|
||||
@param audioPlayer The instance of the EZAudioPlayer that triggered the event
|
||||
@param audioFile The instance of the EZAudioFile that the event was triggered from
|
||||
*/
|
||||
- (void)audioPlayer:(EZAudioPlayer *)audioPlayer
|
||||
reachedEndOfAudioFile:(EZAudioFile *)audioFile;
|
||||
-(void)audioPlayer:(EZAudioPlayer*)audioPlayer
|
||||
updatedPosition:(SInt64)framePosition
|
||||
inAudioFile:(EZAudioFile*)audioFile;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayer
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioPlayer provides an interface that combines the EZAudioFile and EZOutput to play local audio files. This class acts as the master delegate (the EZAudioFileDelegate) over whatever EZAudioFile instance, the `audioFile` property, it is using for playback as well as the EZOutputDelegate and EZOutputDataSource over whatever EZOutput instance is set as the `output`. Classes that want to get the EZAudioFileDelegate callbacks should implement the EZAudioPlayer's EZAudioPlayerDelegate on the EZAudioPlayer instance. Since 0.5.0 the EZAudioPlayer offers notifications over the usual delegate methods to allow multiple receivers to get the EZAudioPlayer's state changes since one player will typically be used in one application. The EZAudioPlayerDelegate, the `delegate`, provides callbacks for high frequency methods that simply wrap the EZAudioFileDelegate and EZOutputDelegate callbacks for providing the audio buffer played as well as the position updating (you will typically have one scrub bar in an application).
|
||||
The EZAudioPlayer acts as the master delegate (the EZAudioFileDelegate) over whatever EZAudioFile it is using for playback. Classes that want to get the EZAudioFileDelegate callbacks should implement the EZAudioPlayer's EZAudioPlayerDelegate on the EZAudioPlayer instance.
|
||||
*/
|
||||
@interface EZAudioPlayer : NSObject <EZAudioFileDelegate,
|
||||
EZOutputDataSource,
|
||||
EZOutputDelegate>
|
||||
@interface EZAudioPlayer : NSObject
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Properties
|
||||
///-----------------------------------------------------------
|
||||
@@ -156,26 +103,14 @@ reachedEndOfAudioFile:(EZAudioFile *)audioFile;
|
||||
/**
|
||||
The EZAudioPlayerDelegate that will handle the audio player callbacks
|
||||
*/
|
||||
@property (nonatomic, weak) id<EZAudioPlayerDelegate> delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@property (nonatomic,assign) id<EZAudioPlayerDelegate> audioPlayerDelegate;
|
||||
|
||||
/**
|
||||
A BOOL indicating whether the player should loop the file
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldLoop;
|
||||
@property (nonatomic,assign) BOOL shouldLoop;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
An EZAudioPlayerState value representing the current internal playback and file state of the EZAudioPlayer instance.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) EZAudioPlayerState state;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Initializers
|
||||
///-----------------------------------------------------------
|
||||
@@ -185,114 +120,72 @@ reachedEndOfAudioFile:(EZAudioFile *)audioFile;
|
||||
@param audioFile The instance of the EZAudioFile to use for initializing the EZAudioPlayer
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
- (instancetype)initWithAudioFile:(EZAudioFile *)audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(EZAudioPlayer*)initWithEZAudioFile:(EZAudioFile*)audioFile;
|
||||
|
||||
/**
|
||||
Initializes the EZAudioPlayer with an EZAudioFile instance and provides a way to assign the EZAudioPlayerDelegate on instantiation. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
@param audioFile The instance of the EZAudioFile to use for initializing the EZAudioPlayer
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithAudioFile: function instead.
|
||||
@param audioPlayerDelegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithEZAudioFile: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
- (instancetype)initWithAudioFile:(EZAudioFile *)audioFile
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Initializes the EZAudioPlayer with an EZAudioPlayerDelegate.
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithAudioFile: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
- (instancetype)initWithDelegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(EZAudioPlayer*)initWithEZAudioFile:(EZAudioFile*)audioFile
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate;
|
||||
|
||||
/**
|
||||
Initializes the EZAudioPlayer with an NSURL instance representing the file path of the audio file.
|
||||
@param url The NSURL instance representing the file path of the audio file.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL*)url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(EZAudioPlayer*)initWithURL:(NSURL*)url;
|
||||
|
||||
/**
|
||||
Initializes the EZAudioPlayer with an NSURL instance representing the file path of the audio file and a caller to assign as the EZAudioPlayerDelegate on instantiation.
|
||||
@param url The NSURL instance representing the file path of the audio file.
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithAudioFile: function instead.
|
||||
@param audioPlayerDelegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the initWithEZAudioFile: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL*)url
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
-(EZAudioPlayer*)initWithURL:(NSURL*)url
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class initializer that creates a default EZAudioPlayer.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+ (instancetype)audioPlayer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class initializer that creates the EZAudioPlayer with an EZAudioFile instance. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
Class initializer that initializes the EZAudioPlayer with an EZAudioFile instance. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
@param audioFile The instance of the EZAudioFile to use for initializing the EZAudioPlayer
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+ (instancetype)audioPlayerWithAudioFile:(EZAudioFile *)audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
+(EZAudioPlayer*)audioPlayerWithEZAudioFile:(EZAudioFile*)audioFile;
|
||||
|
||||
/**
|
||||
Class initializer that creates the EZAudioPlayer with an EZAudioFile instance and provides a way to assign the EZAudioPlayerDelegate on instantiation. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
Class initializer that initializes the EZAudioPlayer with an EZAudioFile instance and provides a way to assign the EZAudioPlayerDelegate on instantiation. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
@param audioFile The instance of the EZAudioFile to use for initializing the EZAudioPlayer
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the audioPlayerWithAudioFile: function instead.
|
||||
@param audioPlayerDelegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the audioPlayerWithEZAudioFile: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+ (instancetype)audioPlayerWithAudioFile:(EZAudioFile *)audioFile
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
+(EZAudioPlayer*)audioPlayerWithEZAudioFile:(EZAudioFile*)audioFile
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate;
|
||||
|
||||
/**
|
||||
Class initializer that creates a default EZAudioPlayer with an EZAudioPlayerDelegate..
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+ (instancetype)audioPlayerWithDelegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class initializer that creates the EZAudioPlayer with an NSURL instance representing the file path of the audio file.
|
||||
Class initializer that initializes the EZAudioPlayer with an NSURL instance representing the file path of the audio file.
|
||||
@param url The NSURL instance representing the file path of the audio file.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+ (instancetype)audioPlayerWithURL:(NSURL*)url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
+(EZAudioPlayer*)audioPlayerWithURL:(NSURL*)url;
|
||||
|
||||
/**
|
||||
Class initializer that creates the EZAudioPlayer with an NSURL instance representing the file path of the audio file and a caller to assign as the EZAudioPlayerDelegate on instantiation.
|
||||
Class initializer that initializes the EZAudioPlayer with an NSURL instance representing the file path of the audio file and a caller to assign as the EZAudioPlayerDelegate on instantiation.
|
||||
@param url The NSURL instance representing the file path of the audio file.
|
||||
@param delegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the audioPlayerWithURL: function instead.
|
||||
@param audioPlayerDelegate The receiver that will act as the EZAudioPlayerDelegate. Set to nil if it should have no delegate or use the audioPlayerWithURL: function instead.
|
||||
@return The newly created instance of the EZAudioPlayer
|
||||
*/
|
||||
+ (instancetype)audioPlayerWithURL:(NSURL*)url
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate;
|
||||
+(EZAudioPlayer*)audioPlayerWithURL:(NSURL*)url
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Singleton
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Shared Instance
|
||||
///-----------------------------------------------------------
|
||||
@@ -301,144 +194,108 @@ reachedEndOfAudioFile:(EZAudioFile *)audioFile;
|
||||
The shared instance (singleton) of the audio player. Most applications will only have one instance of the EZAudioPlayer that can be reused with multiple different audio files.
|
||||
* @return The shared instance of the EZAudioPlayer.
|
||||
*/
|
||||
+ (instancetype)sharedAudioPlayer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
+(EZAudioPlayer*)sharedAudioPlayer;
|
||||
|
||||
#pragma mark - Getters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Properties
|
||||
/// @name Getting The Audio Player's Properties
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the EZAudioFile instance that is being used as the datasource for playback. When set it creates a copy of the EZAudioFile provided for internal use. This does not use the EZAudioFile by reference, but instead creates a copy of the EZAudioFile instance provided.
|
||||
Provides the EZAudioFile instance that is being used as the datasource for playback.
|
||||
@return The EZAudioFile instance that is currently being used for playback.
|
||||
*/
|
||||
@property (nonatomic, readwrite, copy) EZAudioFile *audioFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(EZAudioFile*)audioFile;
|
||||
|
||||
/**
|
||||
Provides the current offset in the audio file as an NSTimeInterval (i.e. in seconds). When setting this it will determine the correct frame offset and perform a `seekToFrame` to the new time offset.
|
||||
@warning Make sure the new current time offset is less than the `duration` or you will receive an invalid seek assertion.
|
||||
Provides the current time (a.k.a. the seek position) in seconds within the audio file that's being used for playback. This can be helpful when displaying the audio player's current time over duration.
|
||||
@return A float representing the current time within the audio file used for playback.
|
||||
*/
|
||||
@property (nonatomic, readwrite) NSTimeInterval currentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(float)currentTime;
|
||||
|
||||
/**
|
||||
The EZAudioDevice instance that is being used by the `output`. Similarly, setting this just sets the `device` property of the `output`.
|
||||
Provides a flag indicating whether the EZAudioPlayer has reached the end of the audio file used for playback.
|
||||
@return A BOOL indicating whether or not the EZAudioPlayer has reached the end of the file it is using for playback.
|
||||
*/
|
||||
@property (readwrite) EZAudioDevice *device;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration of the audio file in seconds.
|
||||
*/
|
||||
@property (readonly) NSTimeInterval duration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current time as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedCurrentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedDuration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the EZOutput that is being used to handle the actual playback of the audio data. This property is also settable, but note that the EZAudioPlayer will become the output's EZOutputDataSource and EZOutputDelegate. To listen for the EZOutput's delegate methods your view should implement the EZAudioPlayerDelegate and set itself as the EZAudioPlayer's `delegate`.
|
||||
*/
|
||||
@property (nonatomic, strong, readwrite) EZOutput *output;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(BOOL)endOfFile;
|
||||
|
||||
/**
|
||||
Provides the frame index (a.k.a the seek positon) within the audio file being used for playback. This can be helpful when seeking through the audio file.
|
||||
@return An SInt64 representing the current frame index within the audio file used for playback.
|
||||
*/
|
||||
@property (readonly) SInt64 frameIndex;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(SInt64)frameIndex;
|
||||
|
||||
/**
|
||||
Provides a flag indicating whether the EZAudioPlayer is currently playing back any audio.
|
||||
@return A BOOL indicating whether or not the EZAudioPlayer is performing playback,
|
||||
*/
|
||||
@property (readonly) BOOL isPlaying;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(BOOL)isPlaying;
|
||||
|
||||
/**
|
||||
Provides the current pan from the audio player's internal `output` component. Setting the pan adjusts the direction of the audio signal from left (0) to right (1). Default is 0.5 (middle).
|
||||
Provides the EZOutput instance that is being used to provide playback to the system output.
|
||||
@return The EZOutput instance that is currently being used for output playback.
|
||||
*/
|
||||
@property (nonatomic, assign) float pan;
|
||||
-(EZOutput*)output;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Provides the total duration of the current audio file being used for playback (in seconds).
|
||||
@return A float representing the total duration of the current audio file being used for playback in seconds.
|
||||
*/
|
||||
-(float)totalDuration;
|
||||
|
||||
/**
|
||||
Provides the total amount of frames in the current audio file being used for playback.
|
||||
@return A SInt64 representing the total amount of frames in the current audio file being used for playback.
|
||||
*/
|
||||
@property (readonly) SInt64 totalFrames;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(SInt64)totalFrames;
|
||||
|
||||
/**
|
||||
Provides the file path that's currently being used by the player for playback.
|
||||
@return The NSURL representing the file path of the audio file being used for playback.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSURL *url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current volume from the audio player's internal `output` component. Setting the volume adjusts the gain of the output between 0 and 1. Default is 1.
|
||||
*/
|
||||
@property (nonatomic, assign) float volume;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
-(NSURL*)url;
|
||||
|
||||
#pragma mark - Setters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Controlling Playback
|
||||
/// @name Setting The File/Output
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Starts playback.
|
||||
Sets the EZAudioFile to use for playback. This does not use the EZAudioFile by reference, but instead creates a separate EZAudioFile instance with the same file at the given file path provided by the internal NSURL to use for internal seeking so it doesn't cause any locking between the caller's instance of the EZAudioFile.
|
||||
@param audioFile The new EZAudioFile instance that should be used for playback
|
||||
*/
|
||||
- (void)play;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(void)setAudioFile:(EZAudioFile*)audioFile;
|
||||
|
||||
/**
|
||||
Loads an EZAudioFile and immediately starts playing it.
|
||||
@param audioFile An EZAudioFile to use for immediate playback.
|
||||
Sets the EZOutput to route playback. By default this uses the [EZOutput sharedOutput] singleton.
|
||||
@param output The new EZOutput instance that should be used for playback
|
||||
*/
|
||||
- (void)playAudioFile:(EZAudioFile *)audioFile;
|
||||
-(void)setOutput:(EZOutput*)output;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Methods
|
||||
///-----------------------------------------------------------
|
||||
/// @name Play/Pause/Seeking the Player
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Starts or resumes playback.
|
||||
*/
|
||||
-(void)play;
|
||||
|
||||
/**
|
||||
Pauses playback.
|
||||
*/
|
||||
- (void)pause;
|
||||
-(void)pause;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stops playback.
|
||||
*/
|
||||
-(void)stop;
|
||||
|
||||
/**
|
||||
Seeks playback to a specified frame within the internal EZAudioFile. This will notify the EZAudioFileDelegate (if specified) with the audioPlayer:updatedPosition:inAudioFile: function.
|
||||
@param frame The new frame position to seek to as a SInt64.
|
||||
*/
|
||||
- (void)seekToFrame:(SInt64)frame;
|
||||
-(void)seekToFrame:(SInt64)frame;
|
||||
|
||||
@end
|
||||
|
||||
@@ -26,434 +26,272 @@
|
||||
#import "EZAudioPlayer.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Notifications
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
NSString * const EZAudioPlayerDidChangeAudioFileNotification = @"EZAudioPlayerDidChangeAudioFileNotification";
|
||||
NSString * const EZAudioPlayerDidChangeOutputDeviceNotification = @"EZAudioPlayerDidChangeOutputDeviceNotification";
|
||||
NSString * const EZAudioPlayerDidChangePanNotification = @"EZAudioPlayerDidChangePanNotification";
|
||||
NSString * const EZAudioPlayerDidChangePlayStateNotification = @"EZAudioPlayerDidChangePlayStateNotification";
|
||||
NSString * const EZAudioPlayerDidChangeVolumeNotification = @"EZAudioPlayerDidChangeVolumeNotification";
|
||||
NSString * const EZAudioPlayerDidReachEndOfFileNotification = @"EZAudioPlayerDidReachEndOfFileNotification";
|
||||
NSString * const EZAudioPlayerDidSeekNotification = @"EZAudioPlayerDidSeekNotification";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayer (Interface Extension)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@interface EZAudioPlayer ()
|
||||
@property (nonatomic, assign, readwrite) EZAudioPlayerState state;
|
||||
#if TARGET_OS_IPHONE
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
@interface EZAudioPlayer () <EZAudioFileDelegate,EZOutputDataSource>
|
||||
{
|
||||
BOOL _eof;
|
||||
}
|
||||
@property (nonatomic,strong,setter=setAudioFile:) EZAudioFile *audioFile;
|
||||
@property (nonatomic,strong,setter=setOutput:) EZOutput *output;
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlayer (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation EZAudioPlayer
|
||||
@synthesize audioFile = _audioFile;
|
||||
@synthesize audioPlayerDelegate = _audioPlayerDelegate;
|
||||
@synthesize output = _output;
|
||||
@synthesize shouldLoop = _shouldLoop;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Methods
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayer
|
||||
{
|
||||
return [[self alloc] init];
|
||||
#pragma mark - Initializers
|
||||
-(id)init {
|
||||
self = [super init];
|
||||
if(self){
|
||||
[self _configureAudioPlayer];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithDelegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithDelegate:delegate];
|
||||
-(EZAudioPlayer*)initWithEZAudioFile:(EZAudioFile *)audioFile {
|
||||
return [self initWithEZAudioFile:audioFile withDelegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
return [[self alloc] initWithAudioFile:audioFile];
|
||||
-(EZAudioPlayer *)initWithEZAudioFile:(EZAudioFile *)audioFile
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate {
|
||||
self = [super init];
|
||||
if(self){
|
||||
// This should make a separate reference to the audio file
|
||||
[self _configureAudioPlayer];
|
||||
self.audioFile = audioFile;
|
||||
self.audioPlayerDelegate = audioPlayerDelegate;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithAudioFile:(EZAudioFile *)audioFile
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithAudioFile:audioFile
|
||||
delegate:delegate];
|
||||
-(EZAudioPlayer *)initWithURL:(NSURL *)url {
|
||||
return [self initWithURL:url withDelegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithURL:(NSURL *)url
|
||||
{
|
||||
return [[self alloc] initWithURL:url];
|
||||
-(EZAudioPlayer *)initWithURL:(NSURL *)url
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate {
|
||||
self = [super init];
|
||||
if(self){
|
||||
[self _configureAudioPlayer];
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:url andDelegate:self];
|
||||
self.audioPlayerDelegate = audioPlayerDelegate;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)audioPlayerWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithURL:url delegate:delegate];
|
||||
#pragma mark - Class Initializers
|
||||
+(EZAudioPlayer *)audioPlayerWithEZAudioFile:(EZAudioFile *)audioFile {
|
||||
return [[EZAudioPlayer alloc] initWithEZAudioFile:audioFile];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initialization
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
[self setup];
|
||||
}
|
||||
return self;
|
||||
+(EZAudioPlayer *)audioPlayerWithEZAudioFile:(EZAudioFile *)audioFile
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate {
|
||||
return [[EZAudioPlayer alloc] initWithEZAudioFile:audioFile
|
||||
withDelegate:audioPlayerDelegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithDelegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
self = [self init];
|
||||
if (self)
|
||||
{
|
||||
self.delegate = delegate;
|
||||
}
|
||||
return self;
|
||||
+(EZAudioPlayer *)audioPlayerWithURL:(NSURL *)url {
|
||||
return [[EZAudioPlayer alloc] initWithURL:url];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
return [self initWithAudioFile:audioFile delegate:nil];
|
||||
+(EZAudioPlayer *)audioPlayerWithURL:(NSURL *)url
|
||||
withDelegate:(id<EZAudioPlayerDelegate>)audioPlayerDelegate {
|
||||
return [[EZAudioPlayer alloc] initWithURL:url
|
||||
withDelegate:audioPlayerDelegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithAudioFile:(EZAudioFile *)audioFile
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
self = [self initWithDelegate:delegate];
|
||||
if (self)
|
||||
{
|
||||
self.audioFile = audioFile;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
{
|
||||
return [self initWithURL:url delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
delegate:(id<EZAudioPlayerDelegate>)delegate
|
||||
{
|
||||
self = [self initWithDelegate:delegate];
|
||||
if (self)
|
||||
{
|
||||
self.audioFile = [EZAudioFile audioFileWithURL:url delegate:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Singleton
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)sharedAudioPlayer
|
||||
{
|
||||
static EZAudioPlayer *player;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^
|
||||
{
|
||||
player = [[self alloc] init];
|
||||
});
|
||||
return player;
|
||||
+(EZAudioPlayer *)sharedAudioPlayer {
|
||||
static EZAudioPlayer *_sharedAudioPlayer = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_sharedAudioPlayer = [[EZAudioPlayer alloc] init];
|
||||
});
|
||||
return _sharedAudioPlayer;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setup
|
||||
{
|
||||
self.output = [EZOutput output];
|
||||
self.state = EZAudioPlayerStateReadyToPlay;
|
||||
#pragma mark - Private Configuration
|
||||
-(void)_configureAudioPlayer {
|
||||
|
||||
// Defaults
|
||||
self.output = [EZOutput sharedOutput];
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// Configure the AVSession
|
||||
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
|
||||
NSError *err = NULL;
|
||||
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];
|
||||
if (err){
|
||||
NSLog(@"There was an error creating the audio session");
|
||||
}
|
||||
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:NULL];
|
||||
if (err){
|
||||
NSLog(@"There was an error sending the audio to the speakers");
|
||||
}
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Getters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)currentTime
|
||||
{
|
||||
return [self.audioFile currentTime];
|
||||
-(EZAudioFile*)audioFile {
|
||||
return _audioFile;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (EZAudioDevice *)device
|
||||
{
|
||||
return [self.output device];
|
||||
-(float)currentTime {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return [EZAudioUtilities MAP:self.audioFile.frameIndex
|
||||
leftMin:0
|
||||
leftMax:self.audioFile.totalFrames
|
||||
rightMin:0
|
||||
rightMax:self.audioFile.totalDuration];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)duration
|
||||
{
|
||||
return [self.audioFile duration];
|
||||
-(BOOL)endOfFile {
|
||||
return _eof;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedCurrentTime
|
||||
{
|
||||
return [self.audioFile formattedCurrentTime];
|
||||
-(SInt64)frameIndex {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return _audioFile.frameIndex;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedDuration
|
||||
{
|
||||
return [self.audioFile formattedDuration];
|
||||
-(BOOL)isPlaying {
|
||||
return self.output.isPlaying;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)frameIndex
|
||||
{
|
||||
return [self.audioFile frameIndex];
|
||||
-(EZOutput*)output {
|
||||
NSAssert(_output,@"No output was found, this should by default be the EZOutput shared instance");
|
||||
return _output;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (BOOL)isPlaying
|
||||
{
|
||||
return [self.output isPlaying];
|
||||
-(float)totalDuration {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return _audioFile.totalDuration;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float)pan
|
||||
{
|
||||
return [self.output pan];
|
||||
-(SInt64)totalFrames {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return _audioFile.totalFrames;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)totalFrames
|
||||
{
|
||||
return [self.audioFile totalFrames];
|
||||
-(NSURL *)url {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
return _audioFile.url;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (float)volume
|
||||
{
|
||||
return [self.output volume];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
_audioFile = [audioFile copy];
|
||||
_audioFile.delegate = self;
|
||||
AudioStreamBasicDescription inputFormat = _audioFile.clientFormat;
|
||||
[self.output setInputFormat:inputFormat];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangeAudioFileNotification
|
||||
object:self];
|
||||
-(void)setAudioFile:(EZAudioFile *)audioFile {
|
||||
if (_audioFile){
|
||||
_audioFile.audioFileDelegate = nil;
|
||||
}
|
||||
_eof = NO;
|
||||
_audioFile = [EZAudioFile audioFileWithURL:audioFile.url andDelegate:self];
|
||||
NSAssert(_output,@"No output was found, this should by default be the EZOutput shared instance");
|
||||
[_output setAudioStreamBasicDescription:self.audioFile.clientFormat];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setCurrentTime:(NSTimeInterval)currentTime
|
||||
{
|
||||
[self.audioFile setCurrentTime:currentTime];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidSeekNotification
|
||||
object:self];
|
||||
-(void)setOutput:(EZOutput*)output {
|
||||
_output = output;
|
||||
_output.outputDataSource = self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setDevice:(EZAudioDevice *)device
|
||||
{
|
||||
[self.output setDevice:device];
|
||||
#pragma mark - Methods
|
||||
-(void)play {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
if (_audioFile){
|
||||
[_output startPlayback];
|
||||
if (self.frameIndex != self.totalFrames){
|
||||
_eof = NO;
|
||||
}
|
||||
if (self.audioPlayerDelegate){
|
||||
if ([self.audioPlayerDelegate respondsToSelector:@selector(audioPlayer:didResumePlaybackOnAudioFile:)]){
|
||||
// Notify the delegate we're starting playback
|
||||
[self.audioPlayerDelegate audioPlayer:self didResumePlaybackOnAudioFile:_audioFile];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setOutput:(EZOutput *)output
|
||||
{
|
||||
_output = output;
|
||||
_output.dataSource = self;
|
||||
_output.delegate = self;
|
||||
-(void)pause {
|
||||
NSAssert(self.audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
if (_audioFile){
|
||||
[_output stopPlayback];
|
||||
if (self.audioPlayerDelegate){
|
||||
if ([self.audioPlayerDelegate respondsToSelector:@selector(audioPlayer:didPausePlaybackOnAudioFile:)]){
|
||||
// Notify the delegate we're pausing playback
|
||||
[self.audioPlayerDelegate audioPlayer:self didPausePlaybackOnAudioFile:_audioFile];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setPan:(float)pan
|
||||
{
|
||||
[self.output setPan:pan];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangePanNotification
|
||||
object:self];
|
||||
-(void)seekToFrame:(SInt64)frame {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
if (_audioFile){
|
||||
[_audioFile seekToFrame:frame];
|
||||
}
|
||||
if (self.frameIndex != self.totalFrames){
|
||||
_eof = NO;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setVolume:(float)volume
|
||||
{
|
||||
[self.output setVolume:volume];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangeVolumeNotification
|
||||
object:self];
|
||||
-(void)stop {
|
||||
NSAssert(_audioFile,@"No audio file to perform the seek on, check that EZAudioFile is not nil");
|
||||
if (_audioFile){
|
||||
[_output stopPlayback];
|
||||
[_audioFile seekToFrame:0];
|
||||
_eof = NO;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)play
|
||||
{
|
||||
[self.output startPlayback];
|
||||
self.state = EZAudioPlayerStatePlaying;
|
||||
#pragma mark - EZAudioFileDelegate
|
||||
-(void)audioFile:(EZAudioFile *)audioFile
|
||||
readAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels {
|
||||
if (self.audioPlayerDelegate){
|
||||
if ([self.audioPlayerDelegate respondsToSelector:@selector(audioPlayer:readAudio:withBufferSize:withNumberOfChannels:inAudioFile:)]){
|
||||
[self.audioPlayerDelegate audioPlayer:self
|
||||
readAudio:buffer
|
||||
withBufferSize:bufferSize
|
||||
withNumberOfChannels:numberOfChannels
|
||||
inAudioFile:audioFile];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)playAudioFile:(EZAudioFile *)audioFile
|
||||
{
|
||||
//
|
||||
// stop playing anything that might currently be playing
|
||||
//
|
||||
[self pause];
|
||||
|
||||
//
|
||||
// set new stream
|
||||
//
|
||||
self.audioFile = audioFile;
|
||||
|
||||
//
|
||||
// begin playback
|
||||
//
|
||||
[self play];
|
||||
-(void)audioFile:(EZAudioFile *)audioFile updatedPosition:(SInt64)framePosition {
|
||||
if (self.audioPlayerDelegate){
|
||||
if ([self.audioPlayerDelegate respondsToSelector:@selector(audioPlayer:updatedPosition:inAudioFile:)]){
|
||||
[self.audioPlayerDelegate audioPlayer:self
|
||||
updatedPosition:framePosition
|
||||
inAudioFile:audioFile];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)pause
|
||||
{
|
||||
[self.output stopPlayback];
|
||||
self.state = EZAudioPlayerStatePaused;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)seekToFrame:(SInt64)frame
|
||||
{
|
||||
self.state = EZAudioPlayerStateSeeking;
|
||||
[self.audioFile seekToFrame:frame];
|
||||
self.state = self.isPlaying ? EZAudioPlayerStatePlaying : EZAudioPlayerStatePaused;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidSeekNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDataSource
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (OSStatus) output:(EZOutput *)output
|
||||
-(void) output:(EZOutput *)output
|
||||
shouldFillAudioBufferList:(AudioBufferList *)audioBufferList
|
||||
withNumberOfFrames:(UInt32)frames
|
||||
timestamp:(const AudioTimeStamp *)timestamp
|
||||
{
|
||||
if (self.audioFile)
|
||||
{
|
||||
UInt32 bufferSize;
|
||||
BOOL eof;
|
||||
[self.audioFile readFrames:frames
|
||||
audioBufferList:audioBufferList
|
||||
bufferSize:&bufferSize
|
||||
eof:&eof];
|
||||
if (eof && [self.delegate respondsToSelector:@selector(audioPlayer:reachedEndOfAudioFile:)])
|
||||
{
|
||||
[self.delegate audioPlayer:self reachedEndOfAudioFile:self.audioFile];
|
||||
}
|
||||
if (eof && self.shouldLoop)
|
||||
eof:&_eof];
|
||||
if (_eof && self.shouldLoop)
|
||||
{
|
||||
[self seekToFrame:0];
|
||||
}
|
||||
else if (eof)
|
||||
{
|
||||
[self pause];
|
||||
[self seekToFrame:0];
|
||||
self.state = EZAudioPlayerStateEndOfFile;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidReachEndOfFileNotification
|
||||
object:self];
|
||||
}
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioFileDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)audioFileUpdatedPosition:(EZAudioFile *)audioFile
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(audioPlayer:updatedPosition:inAudioFile:)])
|
||||
{
|
||||
[self.delegate audioPlayer:self
|
||||
updatedPosition:[audioFile frameIndex]
|
||||
inAudioFile:audioFile];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)output:(EZOutput *)output changedDevice:(EZAudioDevice *)device
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangeOutputDeviceNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)output:(EZOutput *)output changedPlayingState:(BOOL)isPlaying
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:EZAudioPlayerDidChangePlayStateNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void) output:(EZOutput *)output
|
||||
playedAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(audioPlayer:playedAudio:withBufferSize:withNumberOfChannels:inAudioFile:)])
|
||||
{
|
||||
[self.delegate audioPlayer:self
|
||||
playedAudio:buffer
|
||||
withBufferSize:bufferSize
|
||||
withNumberOfChannels:numberOfChannels
|
||||
inAudioFile:self.audioFile];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 9/2/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,53 +23,14 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import "TargetConditionals.h"
|
||||
#import "EZPlot.h"
|
||||
#import "EZAudioDisplayLink.h"
|
||||
|
||||
@class EZAudio;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Constants
|
||||
//------------------------------------------------------------------------------
|
||||
#define kEZAudioPlotMaxHistoryBufferLength (8192)
|
||||
|
||||
/**
|
||||
The default value used for the maximum rolling history buffer length of any EZAudioPlot.
|
||||
@deprecated This constant is deprecated starting in version 0.2.0.
|
||||
@note Please use EZAudioPlotDefaultMaxHistoryBufferLength instead.
|
||||
*/
|
||||
FOUNDATION_EXPORT UInt32 const kEZAudioPlotMaxHistoryBufferLength __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
The default value used for the default rolling history buffer length of any EZAudioPlot.
|
||||
@deprecated This constant is deprecated starting in version 0.2.0.
|
||||
@note Please use EZAudioPlotDefaultHistoryBufferLength instead.
|
||||
*/
|
||||
FOUNDATION_EXPORT UInt32 const kEZAudioPlotDefaultHistoryBufferLength __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
The default value used for the default rolling history buffer length of any EZAudioPlot.
|
||||
*/
|
||||
FOUNDATION_EXPORT UInt32 const EZAudioPlotDefaultHistoryBufferLength;
|
||||
|
||||
/**
|
||||
The default value used for the maximum rolling history buffer length of any EZAudioPlot.
|
||||
*/
|
||||
FOUNDATION_EXPORT UInt32 const EZAudioPlotDefaultMaxHistoryBufferLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlotWaveformLayer
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZAudioPlotWaveformLayer is a lightweight subclass of the CAShapeLayer that allows implicit animations on the `path` key.
|
||||
*/
|
||||
@interface EZAudioPlotWaveformLayer : CAShapeLayer
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlot
|
||||
//------------------------------------------------------------------------------
|
||||
#define kEZAudioPlotDefaultHistoryBufferLength (1024)
|
||||
|
||||
/**
|
||||
`EZAudioPlot`, a subclass of `EZPlot`, is a cross-platform (iOS and OSX) class that plots an audio waveform using Core Graphics.
|
||||
@@ -85,123 +46,37 @@ FOUNDATION_EXPORT UInt32 const EZAudioPlotDefaultMaxHistoryBufferLength;
|
||||
|
||||
*/
|
||||
@interface EZAudioPlot : EZPlot
|
||||
{
|
||||
CGPoint *plotData;
|
||||
UInt32 plotLength;
|
||||
}
|
||||
|
||||
/**
|
||||
A BOOL that allows optimizing the audio plot's drawing for real-time displays. Since the update function may be updating the plot's data very quickly (over 60 frames per second) this property will throttle the drawing calls to be 60 frames per second (or whatever the screen rate is). Specifically, it disables implicit path change animations on the `waveformLayer` and sets up a display link to render 60 fps (audio updating the plot at 44.1 kHz causes it to re-render 86 fps - far greater than what is needed for a visual display).
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldOptimizeForRealtimePlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A BOOL indicating whether the plot should center itself vertically.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldCenterYAxis;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
An EZAudioPlotWaveformLayer that is used to render the actual waveform. By switching the drawing code to Core Animation layers in version 0.2.0 most work, specifically the compositing step, is now done on the GPU. Hence, multiple EZAudioPlot instances can be used simultaneously with very low CPU overhead so these are now practical for table and collection views.
|
||||
*/
|
||||
@property (nonatomic, strong) EZAudioPlotWaveformLayer *waveformLayer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Adjust Resolution
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Adjusting The Resolution
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the length of the rolling history buffer (i.e. the number of points in the rolling plot's buffer). Can grow or shrink the display up to the maximum size specified by the `maximumRollingHistoryLength` method. Will return the actual set value, which will be either the given value if smaller than the `maximumRollingHistoryLength` or `maximumRollingHistoryLength` if a larger value is attempted to be set.
|
||||
Sets the length of the rolling history display. Can grow or shrink the display up to the maximum size specified by the kEZAudioPlotMaxHistoryBufferLength macro. Will return the actual set value, which will be either the given value if smaller than the kEZAudioPlotMaxHistoryBufferLength or kEZAudioPlotMaxHistoryBufferLength if a larger value is attempted to be set.
|
||||
@param historyLength The new length of the rolling history buffer.
|
||||
@return The new value equal to the historyLength or the `maximumRollingHistoryLength`.
|
||||
@return The new value equal to the historyLength or the kEZAudioPlotMaxHistoryBufferLength.
|
||||
*/
|
||||
-(int)setRollingHistoryLength:(int)historyLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the length of the rolling history buffer (i.e. the number of points in the rolling plot's buffer).
|
||||
Provides the length of the rolling history buffer
|
||||
* @return An int representing the length of the rolling history buffer
|
||||
*/
|
||||
-(int)rollingHistoryLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Subclass Methods
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Subclass Methods
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Main method that handles converting the points created from the `updatedBuffer:withBufferSize:` method into a CGPathRef to store in the `waveformLayer`. In this method you can create any path you'd like using the point array (for instance, maybe mapping the points to a circle instead of the standard 2D plane).
|
||||
@param points An array of CGPoint structures, with the x values ranging from 0 - (pointCount - 1) and y values containing the last audio data's buffer.
|
||||
@param pointCount A UInt32 of the length of the point array.
|
||||
@param rect An EZRect (CGRect on iOS or NSRect on OSX) that the path should be created relative to.
|
||||
@return A CGPathRef that is the path you'd like to store on the `waveformLayer` to visualize the audio data.
|
||||
<#Description#>
|
||||
@param data <#theplotData description#>
|
||||
@param length <#length description#>
|
||||
*/
|
||||
- (CGPathRef)createPathWithPoints:(CGPoint *)points
|
||||
pointCount:(UInt32)pointCount
|
||||
inRect:(EZRect)rect;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the default length of the rolling history buffer when the plot is initialized. Default is `EZAudioPlotDefaultHistoryBufferLength` constant.
|
||||
@return An int describing the initial length of the rolling history buffer.
|
||||
*/
|
||||
- (int)defaultRollingHistoryLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called after the view has been created. Subclasses should use to add any additional methods needed instead of overriding the init methods.
|
||||
*/
|
||||
- (void)setupPlot;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the default number of points that will be used to initialize the graph's points data structure that holds. Essentially the plot starts off as a flat line of this many points. Default is 100.
|
||||
@return An int describing the initial number of points the plot should have when flat lined.
|
||||
*/
|
||||
- (int)initialPointCount;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the default maximum rolling history length - that is, the maximum amount of points the `setRollingHistoryLength:` method may be set to. If a length higher than this is set then the plot will likely crash because the appropriate resources are only allocated once during the plot's initialization step. Defualt is `EZAudioPlotDefaultMaxHistoryBufferLength` constant.
|
||||
@return An int describing the maximum length of the absolute rolling history buffer.
|
||||
*/
|
||||
- (int)maximumRollingHistoryLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Method to cause the waveform layer's path to get recreated and redrawn on screen using the last buffer of data provided. This is the equivalent to the drawRect: method used to normally subclass a view's drawing. This normally don't need to be overrode though - a better approach would be to override the `createPathWithPoints:pointCount:inRect:` method.
|
||||
*/
|
||||
- (void)redraw;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Main method used to copy the sample data from the source buffer and update the
|
||||
plot. Subclasses can overwrite this method for custom behavior.
|
||||
@param data A float array of the sample data. Subclasses should copy this data to a separate array to avoid threading issues.
|
||||
@param length The length of the float array as an int.
|
||||
*/
|
||||
-(void)setSampleData:(float *)data length:(int)length;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(void)setSampleData:(float *)data
|
||||
length:(int)length;
|
||||
|
||||
@end
|
||||
|
||||
@interface EZAudioPlot () <EZAudioDisplayLinkDelegate>
|
||||
@property (nonatomic, strong) EZAudioDisplayLink *displayLink;
|
||||
@property (nonatomic, assign) EZPlotHistoryInfo *historyInfo;
|
||||
@property (nonatomic, assign) CGPoint *points;
|
||||
@property (nonatomic, assign) UInt32 pointCount;
|
||||
@end
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 9/2/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,430 +24,274 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "EZAudioPlot.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Constants
|
||||
//------------------------------------------------------------------------------
|
||||
@interface EZAudioPlot () {
|
||||
// BOOL _hasData;
|
||||
// TPCircularBuffer _historyBuffer;
|
||||
|
||||
UInt32 const kEZAudioPlotMaxHistoryBufferLength = 8192;
|
||||
UInt32 const kEZAudioPlotDefaultHistoryBufferLength = 512;
|
||||
UInt32 const EZAudioPlotDefaultHistoryBufferLength = 512;
|
||||
UInt32 const EZAudioPlotDefaultMaxHistoryBufferLength = 8192;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlot (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation EZAudioPlot
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[EZAudioUtilities freeHistoryInfo:self.historyInfo];
|
||||
free(self.points);
|
||||
// Rolling History
|
||||
BOOL _setMaxLength;
|
||||
float *_scrollHistory;
|
||||
int _scrollHistoryIndex;
|
||||
UInt32 _scrollHistoryLength;
|
||||
BOOL _changingHistorySize;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initialization
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
[self initPlot];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)aDecoder
|
||||
{
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self)
|
||||
{
|
||||
[self initPlot];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (id)initWithFrame:(CGRect)frameRect
|
||||
#elif TARGET_OS_MAC
|
||||
- (id)initWithFrame:(NSRect)frameRect
|
||||
#endif
|
||||
{
|
||||
self = [super initWithFrame:frameRect];
|
||||
if (self)
|
||||
{
|
||||
[self initPlot];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
[CATransaction begin];
|
||||
[CATransaction setDisableActions:YES];
|
||||
self.waveformLayer.frame = self.bounds;
|
||||
[self redraw];
|
||||
[CATransaction commit];
|
||||
}
|
||||
#elif TARGET_OS_MAC
|
||||
- (void)layout
|
||||
{
|
||||
[super layout];
|
||||
[CATransaction begin];
|
||||
[CATransaction setDisableActions:YES];
|
||||
self.waveformLayer.frame = self.bounds;
|
||||
[self redraw];
|
||||
[CATransaction commit];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)initPlot
|
||||
{
|
||||
self.shouldCenterYAxis = YES;
|
||||
self.shouldOptimizeForRealtimePlot = YES;
|
||||
self.gain = 1.0;
|
||||
self.plotType = EZPlotTypeBuffer;
|
||||
self.shouldMirror = NO;
|
||||
self.shouldFill = NO;
|
||||
|
||||
// Setup history window
|
||||
[self resetHistoryBuffers];
|
||||
|
||||
self.waveformLayer = [EZAudioPlotWaveformLayer layer];
|
||||
self.waveformLayer.frame = self.bounds;
|
||||
self.waveformLayer.lineWidth = 1.0f;
|
||||
self.waveformLayer.fillColor = nil;
|
||||
self.waveformLayer.backgroundColor = nil;
|
||||
self.waveformLayer.opaque = YES;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
self.color = [UIColor colorWithHue:0 saturation:1.0 brightness:1.0 alpha:1.0];
|
||||
#elif TARGET_OS_MAC
|
||||
self.color = [NSColor colorWithCalibratedHue:0 saturation:1.0 brightness:1.0 alpha:1.0];
|
||||
self.wantsLayer = YES;
|
||||
self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
|
||||
#endif
|
||||
self.backgroundColor = nil;
|
||||
[self.layer insertSublayer:self.waveformLayer atIndex:0];
|
||||
|
||||
//
|
||||
// Allow subclass to initialize plot
|
||||
//
|
||||
[self setupPlot];
|
||||
|
||||
self.points = calloc(EZAudioPlotDefaultMaxHistoryBufferLength, sizeof(CGPoint));
|
||||
self.pointCount = [self initialPointCount];
|
||||
[self redraw];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setupPlot
|
||||
{
|
||||
//
|
||||
// Override in subclass
|
||||
//
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setup
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)resetHistoryBuffers
|
||||
{
|
||||
//
|
||||
// Clear any existing data
|
||||
//
|
||||
if (self.historyInfo)
|
||||
{
|
||||
[EZAudioUtilities freeHistoryInfo:self.historyInfo];
|
||||
}
|
||||
|
||||
self.historyInfo = [EZAudioUtilities historyInfoWithDefaultLength:[self defaultRollingHistoryLength]
|
||||
maximumLength:[self maximumRollingHistoryLength]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setBackgroundColor:(id)backgroundColor
|
||||
{
|
||||
[super setBackgroundColor:backgroundColor];
|
||||
self.layer.backgroundColor = [backgroundColor CGColor];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setColor:(id)color
|
||||
{
|
||||
[super setColor:color];
|
||||
self.waveformLayer.strokeColor = [color CGColor];
|
||||
if (self.shouldFill)
|
||||
{
|
||||
self.waveformLayer.fillColor = [color CGColor];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setShouldOptimizeForRealtimePlot:(BOOL)shouldOptimizeForRealtimePlot
|
||||
{
|
||||
_shouldOptimizeForRealtimePlot = shouldOptimizeForRealtimePlot;
|
||||
if (shouldOptimizeForRealtimePlot && !self.displayLink)
|
||||
{
|
||||
self.displayLink = [EZAudioDisplayLink displayLinkWithDelegate:self];
|
||||
[self.displayLink start];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.displayLink stop];
|
||||
self.displayLink = nil;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setShouldFill:(BOOL)shouldFill
|
||||
{
|
||||
[super setShouldFill:shouldFill];
|
||||
self.waveformLayer.fillColor = shouldFill ? [self.color CGColor] : nil;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Drawing
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)clear
|
||||
{
|
||||
if (self.pointCount > 0)
|
||||
{
|
||||
[self resetHistoryBuffers];
|
||||
float data[self.pointCount];
|
||||
memset(data, 0, self.pointCount * sizeof(float));
|
||||
[self setSampleData:data length:self.pointCount];
|
||||
[self redraw];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)redraw
|
||||
{
|
||||
EZRect frame = [self.waveformLayer frame];
|
||||
CGPathRef path = [self createPathWithPoints:self.points
|
||||
pointCount:self.pointCount
|
||||
inRect:frame];
|
||||
if (self.shouldOptimizeForRealtimePlot)
|
||||
{
|
||||
[CATransaction begin];
|
||||
[CATransaction setDisableActions:YES];
|
||||
self.waveformLayer.path = path;
|
||||
[CATransaction commit];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.waveformLayer.path = path;
|
||||
}
|
||||
CGPathRelease(path);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (CGPathRef)createPathWithPoints:(CGPoint *)points
|
||||
pointCount:(UInt32)pointCount
|
||||
inRect:(EZRect)rect
|
||||
{
|
||||
CGMutablePathRef path = NULL;
|
||||
if (pointCount > 0)
|
||||
{
|
||||
path = CGPathCreateMutable();
|
||||
double xscale = (rect.size.width) / ((float)self.pointCount);
|
||||
double halfHeight = floor(rect.size.height / 2.0);
|
||||
int deviceOriginFlipped = [self isDeviceOriginFlipped] ? -1 : 1;
|
||||
CGAffineTransform xf = CGAffineTransformIdentity;
|
||||
CGFloat translateY = 0.0f;
|
||||
if (!self.shouldCenterYAxis)
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
translateY = CGRectGetHeight(rect);
|
||||
#elif TARGET_OS_MAC
|
||||
translateY = 0.0f;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
translateY = halfHeight + rect.origin.y;
|
||||
}
|
||||
xf = CGAffineTransformTranslate(xf, 0.0, translateY);
|
||||
double yScaleFactor = halfHeight;
|
||||
if (!self.shouldCenterYAxis)
|
||||
{
|
||||
yScaleFactor = 2.0 * halfHeight;
|
||||
}
|
||||
xf = CGAffineTransformScale(xf, xscale, deviceOriginFlipped * yScaleFactor);
|
||||
CGPathAddLines(path, &xf, self.points, self.pointCount);
|
||||
if (self.shouldMirror)
|
||||
{
|
||||
xf = CGAffineTransformScale(xf, 1.0f, -1.0f);
|
||||
CGPathAddLines(path, &xf, self.points, self.pointCount);
|
||||
}
|
||||
if (self.shouldFill)
|
||||
{
|
||||
CGPathCloseSubpath(path);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Update
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)updateBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize
|
||||
{
|
||||
// append the buffer to the history
|
||||
[EZAudioUtilities appendBufferRMS:buffer
|
||||
withBufferSize:bufferSize
|
||||
toHistoryInfo:self.historyInfo];
|
||||
|
||||
// copy samples
|
||||
switch (self.plotType)
|
||||
{
|
||||
case EZPlotTypeBuffer:
|
||||
[self setSampleData:buffer
|
||||
length:bufferSize];
|
||||
break;
|
||||
case EZPlotTypeRolling:
|
||||
|
||||
[self setSampleData:self.historyInfo->buffer
|
||||
length:self.historyInfo->bufferSize];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// update drawing
|
||||
if (!self.shouldOptimizeForRealtimePlot)
|
||||
{
|
||||
[self redraw];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setSampleData:(float *)data length:(int)length
|
||||
{
|
||||
CGPoint *points = self.points;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
points[i].x = i;
|
||||
points[i].y = data[i] * self.gain;
|
||||
}
|
||||
points[0].y = points[length - 1].y = 0.0f;
|
||||
self.pointCount = length;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Adjusting History Resolution
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (int)rollingHistoryLength
|
||||
{
|
||||
return self.historyInfo->bufferSize;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (int)setRollingHistoryLength:(int)historyLength
|
||||
{
|
||||
self.historyInfo->bufferSize = MIN(EZAudioPlotDefaultMaxHistoryBufferLength, historyLength);
|
||||
return self.historyInfo->bufferSize;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Subclass
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (int)defaultRollingHistoryLength
|
||||
{
|
||||
return EZAudioPlotDefaultHistoryBufferLength;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (int)initialPointCount
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (int)maximumRollingHistoryLength
|
||||
{
|
||||
return EZAudioPlotDefaultMaxHistoryBufferLength;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (BOOL)isDeviceOriginFlipped
|
||||
{
|
||||
BOOL isDeviceOriginFlipped = NO;
|
||||
#if TARGET_OS_IPHONE
|
||||
isDeviceOriginFlipped = YES;
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
return isDeviceOriginFlipped;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioDisplayLinkDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)displayLinkNeedsDisplay:(EZAudioDisplayLink *)displayLink
|
||||
{
|
||||
[self redraw];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
////------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlotWaveformLayer (Implementation)
|
||||
////------------------------------------------------------------------------------
|
||||
@implementation EZAudioPlot
|
||||
@synthesize backgroundColor = _backgroundColor;
|
||||
@synthesize color = _color;
|
||||
@synthesize gain = _gain;
|
||||
@synthesize plotType = _plotType;
|
||||
@synthesize shouldFill = _shouldFill;
|
||||
@synthesize shouldMirror = _shouldMirror;
|
||||
|
||||
@implementation EZAudioPlotWaveformLayer
|
||||
|
||||
- (id<CAAction>)actionForKey:(NSString *)event
|
||||
{
|
||||
if ([event isEqualToString:@"path"])
|
||||
{
|
||||
if ([CATransaction disableActions])
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
CABasicAnimation *animation = [CABasicAnimation animation];
|
||||
animation.timingFunction = [CATransaction animationTimingFunction];
|
||||
animation.duration = [CATransaction animationDuration];
|
||||
return animation;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
return [super actionForKey:event];
|
||||
#pragma mark - Initialization
|
||||
-(id)init {
|
||||
self = [super init];
|
||||
if(self){
|
||||
[self initPlot];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
-(id)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if(self){
|
||||
[self initPlot];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
-(id)initWithFrame:(CGRect)frameRect {
|
||||
#elif TARGET_OS_MAC
|
||||
-(id)initWithFrame:(NSRect)frameRect {
|
||||
#endif
|
||||
self = [super initWithFrame:frameRect];
|
||||
if(self){
|
||||
[self initPlot];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)initPlot {
|
||||
#if TARGET_OS_IPHONE
|
||||
self.backgroundColor = [UIColor blackColor];
|
||||
self.color = [UIColor colorWithHue:0 saturation:1.0 brightness:1.0 alpha:1.0];
|
||||
#elif TARGET_OS_MAC
|
||||
self.backgroundColor = [NSColor blackColor];
|
||||
self.color = [NSColor colorWithCalibratedHue:0 saturation:1.0 brightness:1.0 alpha:1.0];
|
||||
#endif
|
||||
self.gain = 1.0;
|
||||
self.plotType = EZPlotTypeRolling;
|
||||
self.shouldMirror = NO;
|
||||
self.shouldFill = NO;
|
||||
plotData = NULL;
|
||||
_scrollHistory = NULL;
|
||||
_scrollHistoryLength = kEZAudioPlotDefaultHistoryBufferLength;
|
||||
}
|
||||
|
||||
#pragma mark - Setters
|
||||
-(void)setBackgroundColor:(id)backgroundColor {
|
||||
_backgroundColor = backgroundColor;
|
||||
[self _refreshDisplay];
|
||||
}
|
||||
|
||||
-(void)setColor:(id)color {
|
||||
_color = color;
|
||||
[self _refreshDisplay];
|
||||
}
|
||||
|
||||
-(void)setGain:(float)gain {
|
||||
_gain = gain;
|
||||
[self _refreshDisplay];
|
||||
}
|
||||
|
||||
-(void)setPlotType:(EZPlotType)plotType {
|
||||
_plotType = plotType;
|
||||
[self _refreshDisplay];
|
||||
}
|
||||
|
||||
-(void)setShouldFill:(BOOL)shouldFill {
|
||||
_shouldFill = shouldFill;
|
||||
[self _refreshDisplay];
|
||||
}
|
||||
|
||||
-(void)setShouldMirror:(BOOL)shouldMirror {
|
||||
_shouldMirror = shouldMirror;
|
||||
[self _refreshDisplay];
|
||||
}
|
||||
|
||||
-(void)_refreshDisplay {
|
||||
#if TARGET_OS_IPHONE
|
||||
[self setNeedsDisplay];
|
||||
#elif TARGET_OS_MAC
|
||||
[self setNeedsDisplay:YES];
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma mark - Get Data
|
||||
-(void)setSampleData:(float *)data
|
||||
length:(int)length {
|
||||
if (plotData != nil){
|
||||
free(plotData);
|
||||
}
|
||||
|
||||
plotData = (CGPoint *)calloc(sizeof(CGPoint),length);
|
||||
plotLength = length;
|
||||
|
||||
for(int i = 0; i < length; i++) {
|
||||
data[i] = i == 0 ? 0 : data[i];
|
||||
plotData[i] = CGPointMake(i,data[i] * _gain);
|
||||
}
|
||||
|
||||
[self _refreshDisplay];
|
||||
}
|
||||
|
||||
#pragma mark - Update
|
||||
-(void)updateBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize {
|
||||
if (_plotType == EZPlotTypeRolling){
|
||||
|
||||
// Update the scroll history datasource
|
||||
[EZAudioUtilities updateScrollHistory:&_scrollHistory
|
||||
withLength:_scrollHistoryLength
|
||||
atIndex:&_scrollHistoryIndex
|
||||
withBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
isResolutionChanging:&_changingHistorySize];
|
||||
|
||||
//
|
||||
[self setSampleData:_scrollHistory
|
||||
length:(!_setMaxLength?kEZAudioPlotMaxHistoryBufferLength:_scrollHistoryLength)];
|
||||
_setMaxLength = YES;
|
||||
|
||||
}
|
||||
else if (_plotType == EZPlotTypeBuffer){
|
||||
|
||||
[self setSampleData:buffer
|
||||
length:bufferSize];
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
// Unknown plot type
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
CGContextRef ctx = UIGraphicsGetCurrentContext();
|
||||
CGContextSaveGState(ctx);
|
||||
CGRect frame = self.bounds;
|
||||
#elif TARGET_OS_MAC
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
[[NSGraphicsContext currentContext] saveGraphicsState];
|
||||
NSGraphicsContext * nsGraphicsContext = [NSGraphicsContext currentContext];
|
||||
CGContextRef ctx = (CGContextRef) [nsGraphicsContext graphicsPort];
|
||||
NSRect frame = self.bounds;
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// Set the background color
|
||||
[(UIColor*)self.backgroundColor set];
|
||||
UIRectFill(frame);
|
||||
// Set the waveform line color
|
||||
[(UIColor*)self.color set];
|
||||
#elif TARGET_OS_MAC
|
||||
[(NSColor*)self.backgroundColor set];
|
||||
NSRectFill(frame);
|
||||
[(NSColor*)self.color set];
|
||||
#endif
|
||||
|
||||
if(plotLength > 0) {
|
||||
|
||||
plotData[plotLength-1] = CGPointMake(plotLength-1,0.0f);
|
||||
|
||||
CGMutablePathRef halfPath = CGPathCreateMutable();
|
||||
CGPathAddLines(halfPath,
|
||||
NULL,
|
||||
plotData,
|
||||
plotLength);
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
|
||||
double xscale = (frame.size.width) / (float)plotLength;
|
||||
double halfHeight = floor( frame.size.height / 2.0);
|
||||
|
||||
// iOS drawing origin is flipped by default so make sure we account for that
|
||||
int deviceOriginFlipped = 1;
|
||||
#if TARGET_OS_IPHONE
|
||||
deviceOriginFlipped = -1;
|
||||
#elif TARGET_OS_MAC
|
||||
deviceOriginFlipped = 1;
|
||||
#endif
|
||||
|
||||
CGAffineTransform xf = CGAffineTransformIdentity;
|
||||
xf = CGAffineTransformTranslate( xf, frame.origin.x , halfHeight + frame.origin.y);
|
||||
xf = CGAffineTransformScale( xf, xscale, deviceOriginFlipped*halfHeight);
|
||||
CGPathAddPath( path, &xf, halfPath);
|
||||
|
||||
if (self.shouldMirror){
|
||||
xf = CGAffineTransformIdentity;
|
||||
xf = CGAffineTransformTranslate( xf, frame.origin.x , halfHeight + frame.origin.y);
|
||||
xf = CGAffineTransformScale( xf, xscale, -deviceOriginFlipped*(halfHeight));
|
||||
CGPathAddPath( path, &xf, halfPath);
|
||||
}
|
||||
CGPathRelease( halfPath);
|
||||
|
||||
// Now, path contains the full waveform path.
|
||||
CGContextAddPath(ctx, path);
|
||||
|
||||
// Make this color customizable
|
||||
if (self.shouldFill){
|
||||
CGContextFillPath(ctx);
|
||||
}
|
||||
else {
|
||||
CGContextStrokePath(ctx);
|
||||
}
|
||||
CGPathRelease(path);
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
CGContextRestoreGState(ctx);
|
||||
#elif TARGET_OS_MAC
|
||||
[[NSGraphicsContext currentContext] restoreGraphicsState];
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma mark - Adjust Resolution
|
||||
-(int)setRollingHistoryLength:(int)historyLength {
|
||||
historyLength = MIN(historyLength,kEZAudioPlotMaxHistoryBufferLength);
|
||||
size_t floatByteSize = sizeof(float);
|
||||
_changingHistorySize = YES;
|
||||
if (_scrollHistoryLength != historyLength){
|
||||
_scrollHistoryLength = historyLength;
|
||||
}
|
||||
_scrollHistory = realloc(_scrollHistory,_scrollHistoryLength*floatByteSize);
|
||||
if (_scrollHistoryIndex < _scrollHistoryLength){
|
||||
memset(&_scrollHistory[_scrollHistoryIndex],
|
||||
0,
|
||||
(_scrollHistoryLength-_scrollHistoryIndex)*floatByteSize);
|
||||
}
|
||||
else {
|
||||
_scrollHistoryIndex = _scrollHistoryLength;
|
||||
}
|
||||
_changingHistorySize = NO;
|
||||
return historyLength;
|
||||
}
|
||||
|
||||
-(int)rollingHistoryLength {
|
||||
return _scrollHistoryLength;
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
if (plotData){
|
||||
free(plotData);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 11/22/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,134 +23,126 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <GLKit/GLKit.h>
|
||||
#import "TargetConditionals.h"
|
||||
#import "EZPlot.h"
|
||||
#if !TARGET_OS_IPHONE
|
||||
#import <OpenGL/OpenGL.h>
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <GLKit/GLKit.h>
|
||||
@class EZAudioPlotGLKViewController;
|
||||
#elif TARGET_OS_MAC
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <GLKit/GLKit.h>
|
||||
#import <OpenGL/gl3.h>
|
||||
#import <QuartzCore/CVDisplayLink.h>
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Data Structures
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Enumerations
|
||||
/**
|
||||
Constant drawing types wrapping around the OpenGL equivalents. In the audio drawings the line strip will be the stroked graph while the triangle will provide the filled equivalent.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger,EZAudioPlotGLDrawType){
|
||||
/**
|
||||
* Maps to the OpenGL constant for a line strip, which for the audio graph will correspond to a stroked drawing (no fill).
|
||||
*/
|
||||
EZAudioPlotGLDrawTypeLineStrip = GL_LINE_STRIP,
|
||||
/**
|
||||
* Maps to the OpenGL constant for a triangle strip, which for the audio graph will correspond to a filled drawing.
|
||||
*/
|
||||
EZAudioPlotGLDrawTypeTriangleStrip = GL_TRIANGLE_STRIP
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLfloat x;
|
||||
GLfloat y;
|
||||
#pragma mark - Structures
|
||||
/**
|
||||
A structure describing a 2D point (x,y) in space for an audio plot.
|
||||
*/
|
||||
typedef struct {
|
||||
GLfloat x;
|
||||
GLfloat y;
|
||||
} EZAudioPlotGLPoint;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioPlotGL
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
EZAudioPlotGL is a subclass of either a GLKView on iOS or an NSOpenGLView on OSX. As of 0.6.0 this class no longer depends on an embedded GLKViewController for iOS as the display link is just manually managed within this single view instead. The EZAudioPlotGL provides the same kind of audio plot as the EZAudioPlot, but uses OpenGL to GPU-accelerate the drawing of the points, which means you can fit a lot more points and complex geometries.
|
||||
EZAudioPlotGL is a subclass of either the EZPlot on iOS or an NSOpenGLView on OSX. I apologize ahead of time for the weirdness in the docs for this class, but I had to do a bit of hackery to get a universal namespace for something works on both iOS and OSX without any additional components. The EZAudioPlotGL provides an the same utilities and interface as the EZAudioPlot with the added benefit of being GPU-accelerated. This is the recommended plot to use on iOS devices to get super fast real-time drawings of audio streams. For the methods and properties below I've included notes on the bottom just indicating which OS they correspond to. In most (if not all) use cases you can just refer to the EZPlot documentation to see which custom properties can be setup. There update function is the same as the EZPlot as well: `updateBuffer:withBufferSize:`
|
||||
*/
|
||||
#if TARGET_OS_IPHONE
|
||||
@interface EZAudioPlotGL : GLKView
|
||||
@interface EZAudioPlotGL : EZPlot
|
||||
#elif TARGET_OS_MAC
|
||||
@interface EZAudioPlotGL : NSOpenGLView
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
// Inherited from EZPlot
|
||||
|
||||
#elif TARGET_OS_MAC
|
||||
|
||||
#pragma mark - Properties
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Plot's Appearance
|
||||
///-----------------------------------------------------------
|
||||
/**
|
||||
The default background color of the plot. For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is black.
|
||||
*/
|
||||
@property (nonatomic,strong) id backgroundColor;
|
||||
|
||||
/**
|
||||
The default background color of the plot. For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is a sweet looking green.
|
||||
@warning On OSX, if you set the background to a value where the alpha component is 0 then the EZAudioPlotGL will automatically set its superview to be layer-backed.
|
||||
The default color of the plot's data (i.e. waveform, y-axis values). For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is red.
|
||||
*/
|
||||
#if TARGET_OS_IPHONE
|
||||
@property (nonatomic, strong) IBInspectable UIColor *backgroundColor;
|
||||
#elif TARGET_OS_MAC
|
||||
@property (nonatomic, strong) IBInspectable NSColor *backgroundColor;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The default color of the plot's data (i.e. waveform, y-axis values). For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is white.
|
||||
*/
|
||||
#if TARGET_OS_IPHONE
|
||||
@property (nonatomic, strong) IBInspectable UIColor *color;
|
||||
#elif TARGET_OS_MAC
|
||||
@property (nonatomic, strong) IBInspectable NSColor *color;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@property (nonatomic,strong) id color;
|
||||
|
||||
/**
|
||||
The plot's gain value, which controls the scale of the y-axis values. The default value of the gain is 1.0f and should always be greater than 0.0f.
|
||||
*/
|
||||
@property (nonatomic, assign) IBInspectable float gain;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@property (nonatomic,assign,setter=setGain:) float gain;
|
||||
|
||||
/**
|
||||
The type of plot as specified by the `EZPlotType` enumeration (i.e. a buffer or rolling plot type). Default is EZPlotTypeBuffer.
|
||||
The type of plot as specified by the `EZPlotType` enumeration (i.e. a buffer or rolling plot type).
|
||||
*/
|
||||
@property (nonatomic, assign) EZPlotType plotType;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@property (nonatomic,assign,setter=setPlotType:) EZPlotType plotType;
|
||||
|
||||
/**
|
||||
A BOOL indicating whether or not to fill in the graph. A value of YES will make a filled graph (filling in the space between the x-axis and the y-value), while a value of NO will create a stroked graph (connecting the points along the y-axis). Default is NO.
|
||||
A BOOL indicating whether or not to fill in the graph. A value of YES will make a filled graph (filling in the space between the x-axis and the y-value), while a value of NO will create a stroked graph (connecting the points along the y-axis).
|
||||
*/
|
||||
@property (nonatomic, assign) IBInspectable BOOL shouldFill;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@property (nonatomic,assign,setter=setShouldFill:) BOOL shouldFill;
|
||||
|
||||
/**
|
||||
A boolean indicating whether the graph should be rotated along the x-axis to give a mirrored reflection. This is typical for audio plots to produce the classic waveform look. A value of YES will produce a mirrored reflection of the y-values about the x-axis, while a value of NO will only plot the y-values. Default is NO.
|
||||
A boolean indicating whether the graph should be rotated along the x-axis to give a mirrored reflection. This is typical for audio plots to produce the classic waveform look. A value of YES will produce a mirrored reflection of the y-values about the x-axis, while a value of NO will only plot the y-values.
|
||||
*/
|
||||
@property (nonatomic, assign) IBInspectable BOOL shouldMirror;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Updating The Plot
|
||||
//------------------------------------------------------------------------------
|
||||
@property (nonatomic,assign,setter=setShouldMirror:) BOOL shouldMirror;
|
||||
|
||||
#pragma mark - Get Samples
|
||||
///-----------------------------------------------------------
|
||||
/// @name Updating The Plot
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Updates the plot with the new buffer data and tells the view to redraw itself. Caller will provide a float array with the values they expect to see on the y-axis. The plot will internally handle mapping the x-axis and y-axis to the current view port, any interpolation for fills effects, and mirroring.
|
||||
@param buffer A float array of values to map to the y-axis.
|
||||
@param bufferSize The size of the float array that will be mapped to the y-axis.
|
||||
@warning The bufferSize is expected to be the same, constant value once initial triggered. For plots using OpenGL a vertex buffer object will be allocated with a maximum buffersize of (2 * the initial given buffer size) to account for any interpolation necessary for filling in the graph. Updates use the glBufferSubData(...) function, which will crash if the buffersize exceeds the initial maximum allocated size.
|
||||
*/
|
||||
-(void)updateBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize;
|
||||
-(void)updateBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Adjust Resolution
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Adjusting The Resolution
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the length of the rolling history buffer (i.e. the number of points in the rolling plot's buffer). Can grow or shrink the display up to the maximum size specified by the `maximumRollingHistoryLength` method. Will return the actual set value, which will be either the given value if smaller than the `maximumRollingHistoryLength` or `maximumRollingHistoryLength` if a larger value is attempted to be set.
|
||||
Sets the length of the rolling history display. Can grow or shrink the display up to the maximum size specified by the kEZAudioPlotMaxHistoryBufferLength macro. Will return the actual set value, which will be either the given value if smaller than the kEZAudioPlotMaxHistoryBufferLength or kEZAudioPlotMaxHistoryBufferLength if a larger value is attempted to be set.
|
||||
@param historyLength The new length of the rolling history buffer.
|
||||
@return The new value equal to the historyLength or the `maximumRollingHistoryLength`.
|
||||
@return The new value equal to the historyLength or the kEZAudioPlotMaxHistoryBufferLength.
|
||||
*/
|
||||
-(int)setRollingHistoryLength:(int)historyLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the length of the rolling history buffer (i.e. the number of points in the rolling plot's buffer).
|
||||
Provides the length of the rolling history buffer
|
||||
* @return An int representing the length of the rolling history buffer
|
||||
*/
|
||||
-(int)rollingHistoryLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Clearing The Plot
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#pragma mark - Shared Methods
|
||||
///-----------------------------------------------------------
|
||||
/// @name Clearing The Plot
|
||||
///-----------------------------------------------------------
|
||||
@@ -160,92 +152,32 @@ typedef struct
|
||||
*/
|
||||
-(void)clear;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Start/Stop Display Link
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Call this method to tell the EZAudioDisplayLink to stop drawing temporarily.
|
||||
*/
|
||||
- (void)pauseDrawing;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Call this method to manually tell the EZAudioDisplayLink to start drawing again.
|
||||
*/
|
||||
- (void)resumeDrawing;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Subclass
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Drawing
|
||||
/// @name Shared OpenGL Methods
|
||||
///-----------------------------------------------------------
|
||||
/**
|
||||
Converts a float array to an array of EZAudioPlotGLPoint structures that hold the (x,y) values the OpenGL buffer needs to properly plot its points.
|
||||
@param graph A pointer to the array that should hold the EZAudioPlotGLPoint structures.
|
||||
@param graphSize The size (or length) of the array with the EZAudioPlotGLPoint structures.
|
||||
@param drawingType The EZAudioPlotGLDrawType constant defining whether the plot should interpolate between points for a triangle strip (filled waveform) or not for a line strip (stroked waveform)
|
||||
@param buffer The float array holding the audio data
|
||||
@param bufferSize The size of the float array holding the audio data
|
||||
@param gain The gain (always greater than 0.0) to apply to the amplitudes (y-values) of the graph. Y-values can only range from -1.0 to 1.0 so any value that's greater will be rounded to -1.0 or 1.0.
|
||||
*/
|
||||
+(void)fillGraph:(EZAudioPlotGLPoint*)graph
|
||||
withGraphSize:(UInt32)graphSize
|
||||
forDrawingType:(EZAudioPlotGLDrawType)drawingType
|
||||
withBuffer:(float*)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withGain:(float)gain;
|
||||
|
||||
/**
|
||||
This method is used to perform the actual OpenGL drawing code to clear the background and draw the lines representing the 2D audio plot. Subclasses can use the current implementation as an example and implement their own custom geometries. This is the analogy of overriding the drawRect: method in an NSView or UIView.
|
||||
@param points An array of EZAudioPlotGLPoint structures representing the mapped audio data to x,y coordinates. The x-axis goes from 0 to the number of points (pointCount) while the y-axis goes from -1 to 1. Check out the implementation of this method to see how the model view matrix of the base effect is transformed to map this properly to the viewport.
|
||||
@param pointCount A UInt32 representing the number of points contained in the points array.
|
||||
@param baseEffect An optional GLKBaseEffect to use as a default shader. Call prepareToDraw on the base effect before any glDrawArrays call.
|
||||
@param vbo The Vertex Buffer Object used to buffer the point data.
|
||||
@param vab The Vertex Array Buffer used to bind the Vertex Buffer Object. This is a Mac only thing, you can ignore this completely on iOS.
|
||||
@param interpolated A BOOL indicating whether the data has been interpolated. This means the point data is twice as long, where every other point is 0 on the y-axis to allow drawing triangle stripes for filled in waveforms. Typically if the point data is interpolated you will be using the GL_TRIANGLE_STRIP drawing mode, while non-interpolated plots will just use a GL_LINE_STRIP drawing mode.
|
||||
@param mirrored A BOOL indicating whether the plot should be mirrored about the y-axis (or whatever geometry you come up with).
|
||||
@param gain A float representing a gain that should be used to influence the height or intensity of your geometry's shape. A gain of 0.0 means silence, a gain of 1.0 means full volume (you're welcome to boost this to whatever you want).
|
||||
Determines the proper size of a graph given a EZAudioPlotGLDrawType (line strip or triangle strip) and the size of the incoming buffer. Triangle strips require interpolating between points so the buffer becomes 2*bufferSize
|
||||
@param drawingType The EZAudioPlotGLDraw type (line strip or triangle strip)
|
||||
@param bufferSize The size of the float array holding the audio data coming in.
|
||||
@return A Int32 representing the proper graph size that should be used to account for any necessary interpolating between points.
|
||||
*/
|
||||
- (void)redrawWithPoints:(EZAudioPlotGLPoint *)points
|
||||
pointCount:(UInt32)pointCount
|
||||
baseEffect:(GLKBaseEffect *)baseEffect
|
||||
vertexBufferObject:(GLuint)vbo
|
||||
vertexArrayBuffer:(GLuint)vab
|
||||
interpolated:(BOOL)interpolated
|
||||
mirrored:(BOOL)mirrored
|
||||
gain:(float)gain;
|
||||
+(UInt32)graphSizeForDrawingType:(EZAudioPlotGLDrawType)drawingType
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called during the OpenGL run loop to constantly update the drawing 60 fps. Callers can use this force update the screen while subclasses can override this for complete control over their rendering. However, subclasses are more encouraged to use the `redrawWithPoints:pointCount:baseEffect:vertexBufferObject:vertexArrayBuffer:interpolated:mirrored:gain:`
|
||||
*/
|
||||
- (void)redraw;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called after the view has been created. Subclasses should use to add any additional methods needed instead of overriding the init methods.
|
||||
*/
|
||||
- (void)setup;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Main method used to copy the sample data from the source buffer and update the
|
||||
plot. Subclasses can overwrite this method for custom behavior.
|
||||
@param data A float array of the sample data. Subclasses should copy this data to a separate array to avoid threading issues.
|
||||
@param length The length of the float array as an int.
|
||||
*/
|
||||
- (void)setSampleData:(float *)data length:(int)length;
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Subclass Methods
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the default length of the rolling history buffer when the plot is initialized. Default is `EZAudioPlotDefaultHistoryBufferLength` constant.
|
||||
@return An int describing the initial length of the rolling history buffer.
|
||||
*/
|
||||
- (int)defaultRollingHistoryLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the default maximum rolling history length - that is, the maximum amount of points the `setRollingHistoryLength:` method may be set to. If a length higher than this is set then the plot will likely crash because the appropriate resources are only allocated once during the plot's initialization step. Defualt is `EZAudioPlotDefaultMaxHistoryBufferLength` constant.
|
||||
@return An int describing the maximum length of the absolute rolling history buffer.
|
||||
*/
|
||||
- (int)maximumRollingHistoryLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// EZAudioPlotGLKViewController.h
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 11/22/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "TargetConditionals.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
#import "EZAudioPlotGL.h"
|
||||
|
||||
@class EZAudio;
|
||||
|
||||
/**
|
||||
EZAudioPlotGLKViewController is a subclass of the GLKViewController and handles the OpenGL drawing routine for iOS OpenGL ES views. This class has not been used outside the scope of the EZAudioPlotGL, but should be safe to use by itself if the intended use case is to have a view controller take up the whole screen.
|
||||
*/
|
||||
@interface EZAudioPlotGLKViewController : GLKViewController
|
||||
|
||||
#pragma mark - Properties
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Plot's Appearance
|
||||
///-----------------------------------------------------------
|
||||
/**
|
||||
The default background color of the plot. For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is black.
|
||||
*/
|
||||
@property (nonatomic,strong) UIColor *backgroundColor;
|
||||
|
||||
/**
|
||||
The default shader to use to fill the graph.
|
||||
*/
|
||||
@property (nonatomic,strong) GLKBaseEffect *baseEffect;
|
||||
|
||||
/**
|
||||
The default color of the plot's data (i.e. waveform, y-axis values). For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is red.
|
||||
*/
|
||||
@property (nonatomic,strong) UIColor *color;
|
||||
|
||||
/**
|
||||
The OpenGL ES context (EAGLContext) in which to perform the drawing
|
||||
*/
|
||||
@property (nonatomic,strong) EAGLContext *context;
|
||||
|
||||
/**
|
||||
The EZAudioPlotGLDrawType specifying which OpenGL primitive to use for drawing (either line strip for stroke and no fill or triangle strip for fill)
|
||||
*/
|
||||
@property (nonatomic,assign) EZAudioPlotGLDrawType drawingType;
|
||||
|
||||
/**
|
||||
The plot's gain value, which controls the scale of the y-axis values. The default value of the gain is 1.0f and should always be greater than 0.0f.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setGain:) float gain;
|
||||
|
||||
/**
|
||||
The type of plot as specified by the `EZPlotType` enumeration (i.e. a buffer or rolling plot type).
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setPlotType:) EZPlotType plotType;
|
||||
|
||||
/**
|
||||
A boolean indicating whether the graph should be rotated along the x-axis to give a mirrored reflection. This is typical for audio plots to produce the classic waveform look. A value of YES will produce a mirrored reflection of the y-values about the x-axis, while a value of NO will only plot the y-values.
|
||||
*/
|
||||
@property (nonatomic,assign,setter=setShouldMirror:) BOOL shouldMirror;
|
||||
|
||||
#pragma mark - Adjust Resolution
|
||||
///-----------------------------------------------------------
|
||||
/// @name Adjusting The Resolution
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets the length of the rolling history display. Can grow or shrink the display up to the maximum size specified by the kEZAudioPlotMaxHistoryBufferLength macro. Will return the actual set value, which will be either the given value if smaller than the kEZAudioPlotMaxHistoryBufferLength or kEZAudioPlotMaxHistoryBufferLength if a larger value is attempted to be set.
|
||||
@param historyLength The new length of the rolling history buffer.
|
||||
@return The new value equal to the historyLength or the kEZAudioPlotMaxHistoryBufferLength.
|
||||
*/
|
||||
-(int)setRollingHistoryLength:(int)historyLength;
|
||||
|
||||
/**
|
||||
Provides the length of the rolling history buffer
|
||||
* @return An int representing the length of the rolling history buffer
|
||||
*/
|
||||
-(int)rollingHistoryLength;
|
||||
|
||||
#pragma mark - Clearing
|
||||
///-----------------------------------------------------------
|
||||
/// @name Clearing The Plot
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Clears all data from the audio plot (includes both EZPlotTypeBuffer and EZPlotTypeRolling)
|
||||
*/
|
||||
-(void)clear;
|
||||
|
||||
#pragma mark - Get Samples
|
||||
///-----------------------------------------------------------
|
||||
/// @name Updating The Plot
|
||||
///-----------------------------------------------------------
|
||||
/**
|
||||
Updates the plot with the new buffer data and tells the view to redraw itself. Caller will provide a float array with the values they expect to see on the y-axis. The plot will internally handle mapping the x-axis and y-axis to the current view port, any interpolation for fills effects, and mirroring.
|
||||
@param buffer A float array of values to map to the y-axis.
|
||||
@param bufferSize The size of the float array that will be mapped to the y-axis.
|
||||
@warning The bufferSize is expected to be the same, constant value once initial triggered. For plots using OpenGL a vertex buffer object will be allocated with a maximum buffersize of (2 * the initial given buffer size) to account for any interpolation necessary for filling in the graph. Updates use the glBufferSubData(...) function, which will crash if the buffersize exceeds the initial maximum allocated size.
|
||||
*/
|
||||
-(void)updateBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
@end
|
||||
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
@@ -0,0 +1,486 @@
|
||||
//
|
||||
// EZAudioPlotGLKViewController.m
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 11/22/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
#import "EZAudioPlotGLKViewController.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
#import "EZAudioPlot.h"
|
||||
|
||||
@interface EZAudioPlotGLKViewController () {
|
||||
|
||||
// Flags indicating whether the plots have been instantiated
|
||||
BOOL _hasBufferPlotData;
|
||||
BOOL _hasRollingPlotData;
|
||||
|
||||
// The buffers
|
||||
GLuint _bufferPlotVBO;
|
||||
GLuint _rollingPlotVBO;
|
||||
|
||||
// Buffers size
|
||||
UInt32 _bufferPlotGraphSize;
|
||||
UInt32 _rollingPlotGraphSize;
|
||||
|
||||
// Rolling History
|
||||
BOOL _setMaxLength;
|
||||
float *_scrollHistory;
|
||||
int _scrollHistoryIndex;
|
||||
UInt32 _scrollHistoryLength;
|
||||
BOOL _changingHistorySize;
|
||||
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation EZAudioPlotGLKViewController
|
||||
@synthesize baseEffect = _baseEffect;
|
||||
@synthesize context = _context;
|
||||
@synthesize drawingType = _drawingType;
|
||||
@synthesize plotType = _plotType;
|
||||
@synthesize shouldMirror = _shouldMirror;
|
||||
|
||||
#pragma mark - Initialization
|
||||
-(id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self initializeView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if(self){
|
||||
[self initializeView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if(self){
|
||||
[self initializeView];
|
||||
}
|
||||
return self;
|
||||
|
||||
}
|
||||
#pragma mark - Initialize Properties Here
|
||||
-(void)initializeView {
|
||||
// Setup the base effect
|
||||
self.baseEffect = [[GLKBaseEffect alloc] init];
|
||||
self.baseEffect.useConstantColor = GL_TRUE;
|
||||
self.preferredFramesPerSecond = 60;
|
||||
_scrollHistory = NULL;
|
||||
_scrollHistoryLength = kEZAudioPlotDefaultHistoryBufferLength;
|
||||
}
|
||||
|
||||
#pragma mark - View Did Load
|
||||
-(void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
// Setup the context
|
||||
if (![EAGLContext currentContext])
|
||||
{
|
||||
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.context = [EAGLContext currentContext];
|
||||
}
|
||||
|
||||
if (!self.context) {
|
||||
NSLog(@"Failed to create ES context");
|
||||
}
|
||||
else {
|
||||
EAGLContext.currentContext = self.context;
|
||||
}
|
||||
|
||||
// Set the view's context
|
||||
GLKView *view = (GLKView *)self.view;
|
||||
view.context = self.context;
|
||||
view.drawableMultisample = GLKViewDrawableMultisample4X;
|
||||
view.opaque = NO;
|
||||
|
||||
// Generate both the buffer id references
|
||||
glGenBuffers(1, &_bufferPlotVBO);
|
||||
glGenBuffers(1, &_rollingPlotVBO);
|
||||
|
||||
// Refresh color values
|
||||
[self _refreshWithBackgroundColor: self.backgroundColor];
|
||||
[self _refreshWithColor: self.color];
|
||||
|
||||
// Set the line width for the context
|
||||
glLineWidth(2.0);
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Adjust Resolution
|
||||
-(int)setRollingHistoryLength:(int)historyLength {
|
||||
_changingHistorySize = YES;
|
||||
historyLength = MIN(historyLength,kEZAudioPlotMaxHistoryBufferLength);
|
||||
size_t floatByteSize = sizeof(float);
|
||||
if (_scrollHistoryLength != historyLength){
|
||||
_scrollHistoryLength = historyLength;
|
||||
}
|
||||
_scrollHistory = realloc(_scrollHistory,_scrollHistoryLength*floatByteSize);
|
||||
if (_scrollHistoryIndex < _scrollHistoryLength){
|
||||
memset(&_scrollHistory[_scrollHistoryIndex],
|
||||
0,
|
||||
(_scrollHistoryLength-_scrollHistoryIndex)*floatByteSize);
|
||||
}
|
||||
else {
|
||||
_scrollHistoryIndex = _scrollHistoryLength;
|
||||
}
|
||||
[self _updateRollingPlotDisplay];
|
||||
_changingHistorySize = NO;
|
||||
return historyLength;
|
||||
}
|
||||
|
||||
-(int)rollingHistoryLength {
|
||||
return _scrollHistoryLength;
|
||||
}
|
||||
|
||||
#pragma mark - Clearing
|
||||
-(void)clear
|
||||
{
|
||||
_scrollHistoryIndex = 0;
|
||||
[self _clearBufferPlot];
|
||||
[self _clearRollingPlot];
|
||||
}
|
||||
|
||||
-(void)_clearBufferPlot
|
||||
{
|
||||
if (_hasBufferPlotData)
|
||||
{
|
||||
float empty[_bufferPlotGraphSize];
|
||||
memset( empty, 0.0f, sizeof(float));
|
||||
[self _updateBufferPlotBufferWithAudioReceived:empty
|
||||
withBufferSize:_bufferPlotGraphSize];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)_clearRollingPlot
|
||||
{
|
||||
if (_hasRollingPlotData)
|
||||
{
|
||||
float empty[_rollingPlotGraphSize];
|
||||
EZAudioPlotGLPoint graph[_rollingPlotGraphSize];
|
||||
// Figure out better way to do this
|
||||
for(int i = 0; i < _rollingPlotGraphSize; i++)
|
||||
{
|
||||
empty[i] = 0.0f;
|
||||
}
|
||||
for(int i = 0; i < _scrollHistoryLength; i++)
|
||||
{
|
||||
_scrollHistory[i] = 0.0f;
|
||||
}
|
||||
// Update the scroll history datasource
|
||||
[EZAudioUtilities updateScrollHistory:&_scrollHistory
|
||||
withLength:_scrollHistoryLength
|
||||
atIndex:&_scrollHistoryIndex
|
||||
withBuffer:empty
|
||||
withBufferSize:_rollingPlotGraphSize
|
||||
isResolutionChanging:&_changingHistorySize];
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_rollingPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:_scrollHistory
|
||||
withBufferSize:_scrollHistoryLength
|
||||
withGain:self.gain];
|
||||
// Update the drawing
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(graph), graph);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Get Samples
|
||||
-(void)updateBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize {
|
||||
|
||||
// Make sure the update render loop is active
|
||||
if (self.paused) self.paused = NO;
|
||||
|
||||
// Make sure we are updating the buffers on the correct gl context.
|
||||
EAGLContext.currentContext = self.context;
|
||||
|
||||
// Draw based on plot type
|
||||
switch(_plotType) {
|
||||
case EZPlotTypeBuffer:
|
||||
[self _updateBufferPlotBufferWithAudioReceived:buffer
|
||||
withBufferSize:bufferSize];
|
||||
break;
|
||||
case EZPlotTypeRolling:
|
||||
[self _updateRollingPlotBufferWithAudioReceived:buffer
|
||||
withBufferSize:bufferSize];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Buffer Updating By Type
|
||||
-(void)_updateBufferPlotBufferWithAudioReceived:(float*)buffer
|
||||
withBufferSize:(UInt32)bufferSize {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _bufferPlotVBO);
|
||||
|
||||
// If starting with a VBO of half of our max size make sure we initialize it to anticipate
|
||||
// a filled graph (which needs 2 * bufferSize) to allocate its resources properly
|
||||
if (!_hasBufferPlotData && _drawingType == EZAudioPlotGLDrawTypeLineStrip){
|
||||
EZAudioPlotGLPoint maxGraph[2*bufferSize];
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(maxGraph), maxGraph, GL_STREAM_DRAW);
|
||||
_hasBufferPlotData = YES;
|
||||
}
|
||||
|
||||
// Setup the buffer plot's graph size
|
||||
_bufferPlotGraphSize = [EZAudioPlotGL graphSizeForDrawingType:_drawingType
|
||||
withBufferSize:bufferSize];
|
||||
|
||||
// Setup the graph
|
||||
EZAudioPlotGLPoint graph[_bufferPlotGraphSize];
|
||||
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_bufferPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
withGain:self.gain];
|
||||
|
||||
if (!_hasBufferPlotData){
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(graph), graph, GL_STREAM_DRAW);
|
||||
_hasBufferPlotData = YES;
|
||||
}
|
||||
else {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(graph), graph);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
}
|
||||
|
||||
-(void)_updateRollingPlotBufferWithAudioReceived:(float*)buffer
|
||||
withBufferSize:(UInt32)bufferSize {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _rollingPlotVBO);
|
||||
|
||||
|
||||
|
||||
// If starting with a VBO of half of our max size make sure we initialize it to anticipate
|
||||
// a filled graph (which needs 2 * bufferSize) to allocate its resources properly
|
||||
if (!_hasRollingPlotData){
|
||||
EZAudioPlotGLPoint maxGraph[2*kEZAudioPlotMaxHistoryBufferLength];
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(maxGraph), maxGraph, GL_STREAM_DRAW);
|
||||
_hasRollingPlotData = YES;
|
||||
}
|
||||
|
||||
// Setup the plot
|
||||
_rollingPlotGraphSize = [EZAudioPlotGL graphSizeForDrawingType:_drawingType
|
||||
withBufferSize:_scrollHistoryLength];
|
||||
|
||||
// Fill the graph with data
|
||||
EZAudioPlotGLPoint graph[_rollingPlotGraphSize];
|
||||
|
||||
// Update the scroll history datasource
|
||||
[EZAudioUtilities updateScrollHistory:&_scrollHistory
|
||||
withLength:_scrollHistoryLength
|
||||
atIndex:&_scrollHistoryIndex
|
||||
withBuffer:buffer
|
||||
withBufferSize:bufferSize
|
||||
isResolutionChanging:&_changingHistorySize];
|
||||
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_rollingPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:_scrollHistory
|
||||
withBufferSize:_scrollHistoryLength
|
||||
withGain:self.gain];
|
||||
|
||||
// Update the drawing
|
||||
if (!_hasRollingPlotData){
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(graph) , graph, GL_STREAM_DRAW);
|
||||
_hasRollingPlotData = YES;
|
||||
}
|
||||
else {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(graph), graph);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
}
|
||||
|
||||
-(void)_updateRollingPlotDisplay {
|
||||
// Setup the plot
|
||||
_rollingPlotGraphSize = [EZAudioPlotGL graphSizeForDrawingType:_drawingType
|
||||
withBufferSize:_scrollHistoryLength];
|
||||
|
||||
// Fill the graph with data
|
||||
EZAudioPlotGLPoint graph[_rollingPlotGraphSize];
|
||||
|
||||
// Fill in graph data
|
||||
[EZAudioPlotGL fillGraph:graph
|
||||
withGraphSize:_rollingPlotGraphSize
|
||||
forDrawingType:_drawingType
|
||||
withBuffer:_scrollHistory
|
||||
withBufferSize:_scrollHistoryLength
|
||||
withGain:self.gain];
|
||||
|
||||
// Update the drawing
|
||||
if (_hasRollingPlotData){
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(graph), graph);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Drawing
|
||||
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
|
||||
|
||||
EAGLContext.currentContext = self.context;
|
||||
|
||||
// Clear the context
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (_hasBufferPlotData || _hasRollingPlotData){
|
||||
// Prepare the effect for drawing
|
||||
[self.baseEffect prepareToDraw];
|
||||
|
||||
// Plot either a buffer plot or a rolling plot
|
||||
switch(_plotType) {
|
||||
case EZPlotTypeBuffer:
|
||||
[self _drawBufferPlotWithView:view
|
||||
drawInRect:rect];
|
||||
break;
|
||||
case EZPlotTypeRolling:
|
||||
[self _drawRollingPlotWithView:view
|
||||
drawInRect:rect];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Private Drawing
|
||||
-(void)_drawBufferPlotWithView:(GLKView*)view drawInRect:(CGRect)rect {
|
||||
if (_hasBufferPlotData){
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _bufferPlotVBO);
|
||||
glEnableVertexAttribArray(GLKVertexAttribPosition);
|
||||
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(EZAudioPlotGLPoint), NULL);
|
||||
|
||||
// Normal plot
|
||||
|
||||
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(0);
|
||||
glDrawArrays(_drawingType, 0, _bufferPlotGraphSize);
|
||||
|
||||
|
||||
if (self.shouldMirror){
|
||||
// Mirrored plot
|
||||
[self.baseEffect prepareToDraw];
|
||||
|
||||
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(M_PI);
|
||||
glDrawArrays(_drawingType, 0, _bufferPlotGraphSize);
|
||||
|
||||
}
|
||||
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER,0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
-(void)_drawRollingPlotWithView:(GLKView*)view drawInRect:(CGRect)rect {
|
||||
if (_hasRollingPlotData){
|
||||
|
||||
// Normal plot
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _rollingPlotVBO);
|
||||
glEnableVertexAttribArray(GLKVertexAttribPosition);
|
||||
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(EZAudioPlotGLPoint), NULL);
|
||||
|
||||
// Normal plot
|
||||
|
||||
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(0);
|
||||
glDrawArrays(_drawingType, 0, _rollingPlotGraphSize);
|
||||
|
||||
|
||||
if (self.shouldMirror){
|
||||
// Mirrored plot
|
||||
[self.baseEffect prepareToDraw];
|
||||
|
||||
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(3.14159265359);
|
||||
glDrawArrays(_drawingType, 0, _rollingPlotGraphSize);
|
||||
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER,0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Setters
|
||||
-(void)setBackgroundColor:(UIColor *)backgroundColor {
|
||||
// Set the background color
|
||||
_backgroundColor = backgroundColor;
|
||||
// Refresh background color (map to GL vector)
|
||||
[self _refreshWithBackgroundColor:backgroundColor];
|
||||
}
|
||||
|
||||
-(void)setColor:(UIColor *)color {
|
||||
// Set the color
|
||||
_color = color;
|
||||
// Refresh the color (map to GL vector)
|
||||
[self _refreshWithColor:color];
|
||||
}
|
||||
|
||||
#pragma mark - Private Setters
|
||||
-(void)_refreshWithBackgroundColor:(UIColor*)backgroundColor {
|
||||
// Extract colors
|
||||
CGFloat red; CGFloat green; CGFloat blue; CGFloat alpha;
|
||||
[backgroundColor getRed:&red
|
||||
green:&green
|
||||
blue:&blue
|
||||
alpha:&alpha];
|
||||
// Set them on the context
|
||||
glClearColor((GLclampf)red,(GLclampf)green,(GLclampf)blue,(GLclampf)alpha);
|
||||
}
|
||||
|
||||
-(void)_refreshWithColor:(UIColor*)color {
|
||||
// Extract colors
|
||||
CGFloat red; CGFloat green; CGFloat blue; CGFloat alpha;
|
||||
[color getRed:&red
|
||||
green:&green
|
||||
blue:&blue
|
||||
alpha:&alpha];
|
||||
// Set them on the base shader
|
||||
self.baseEffect.constantColor = GLKVector4Make((GLclampf)red,(GLclampf)green,(GLclampf)blue,(GLclampf)alpha);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#elif TARGET_OS_MAC
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/23/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,47 +25,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <TargetConditionals.h>
|
||||
#import "TPCircularBuffer.h"
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Data Structures
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A data structure that holds information about audio data over time. It contains a circular buffer to incrementally write the audio data to and a scratch buffer to hold a window of audio data relative to the whole circular buffer. In use, this will provide a way to continuously append data while having an adjustable viewable window described by the bufferSize.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
float *buffer;
|
||||
int bufferSize;
|
||||
TPCircularBuffer circularBuffer;
|
||||
} EZPlotHistoryInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
A data structure that holds information about a node in the context of an AUGraph.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
AudioUnit audioUnit;
|
||||
AUNode node;
|
||||
} EZAudioNodeInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
typedef CGRect EZRect;
|
||||
#elif TARGET_OS_MAC
|
||||
typedef NSRect EZRect;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZAudioUtilities
|
||||
@@ -236,7 +196,7 @@ typedef NSRect EZRect;
|
||||
@param sampleRate A float representing the sample rate.
|
||||
@return A new AudioStreamBasicDescription with the specified format.
|
||||
*/
|
||||
+ (AudioStreamBasicDescription)stereoFloatNonInterleavedFormatWithSampleRate:(float)sampleRate;
|
||||
+ (AudioStreamBasicDescription)stereoFloatNonInterleavedFormatWithSampleRate:(float)sameRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// @name AudioStreamBasicDescription Helper Functions
|
||||
@@ -380,13 +340,6 @@ typedef NSRect EZRect;
|
||||
*/
|
||||
+ (float)SGN:(float)value;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Music Utilities
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (NSString *)noteNameStringForFrequency:(float)frequency
|
||||
includeOctave:(BOOL)includeOctave;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - OSStatus Utility
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -411,28 +364,6 @@ typedef NSRect EZRect;
|
||||
*/
|
||||
+ (NSString *)stringFromUInt32Code:(UInt32)code;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Color Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Color Utility
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Helper function to get the color components from a CGColorRef in the RGBA colorspace.
|
||||
@param color A CGColorRef that represents a color.
|
||||
@param red A pointer to a CGFloat to hold the value of the red component. This value will be between 0 and 1.
|
||||
@param green A pointer to a CGFloat to hold the value of the green component. This value will be between 0 and 1.
|
||||
@param blue A pointer to a CGFloat to hold the value of the blue component. This value will be between 0 and 1.
|
||||
@param alpha A pointer to a CGFloat to hold the value of the alpha component. This value will be between 0 and 1.
|
||||
*/
|
||||
+ (void)getColorComponentsFromCGColor:(CGColorRef)color
|
||||
red:(CGFloat *)red
|
||||
green:(CGFloat *)green
|
||||
blue:(CGFloat *)blue
|
||||
alpha:(CGFloat *)alpha;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Plot Utility
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -477,8 +408,8 @@ typedef NSRect EZRect;
|
||||
|
||||
/**
|
||||
Initializes the circular buffer (just a wrapper around the C method)
|
||||
@param circularBuffer Pointer to an instance of the TPCircularBuffer
|
||||
@param size The length of the TPCircularBuffer (usually 1024)
|
||||
* @param circularBuffer Pointer to an instance of the TPCircularBuffer
|
||||
* @param size The length of the TPCircularBuffer (usually 1024)
|
||||
*/
|
||||
+ (void)circularBuffer:(TPCircularBuffer*)circularBuffer
|
||||
withSize:(int)size;
|
||||
@@ -491,59 +422,6 @@ typedef NSRect EZRect;
|
||||
*/
|
||||
+ (void)freeCircularBuffer:(TPCircularBuffer*)circularBuffer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZPlotHistoryInfo Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Calculates the RMS of a float array containing audio data and appends it 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)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;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Zeroes out a EZPlotHistoryInfo data structure without freeing the resources.
|
||||
@param historyInfo A pointer to a EZPlotHistoryInfo data structure
|
||||
*/
|
||||
+ (void)clearHistoryInfo:(EZPlotHistoryInfo *)historyInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Frees a EZPlotHistoryInfo data structure
|
||||
@param historyInfo A pointer to a EZPlotHistoryInfo data structure
|
||||
*/
|
||||
+ (void)freeHistoryInfo:(EZPlotHistoryInfo *)historyInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates an EZPlotHistoryInfo data structure with a default length for the window buffer and a maximum length capacity for the internal circular buffer that holds all the audio data.
|
||||
@param defaultLength An int representing the default length (i.e. the number of points that will be displayed on screen) of the history window.
|
||||
@param maximumLength An int representing the default maximum length that is the absolute maximum amount of values that can be held in the history's circular buffer.
|
||||
@return A pointer to the EZPlotHistoryInfo created. The caller is responsible for freeing this structure using the `freeHistoryInfo` method above.
|
||||
*/
|
||||
+ (EZPlotHistoryInfo *)historyInfoWithDefaultLength:(int)defaultLength
|
||||
maximumLength:(int)maximumLength;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
@end
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 6/23/15.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -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,14 @@ 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);
|
||||
}
|
||||
return audioBufferList;
|
||||
}
|
||||
@@ -136,11 +105,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]);
|
||||
@@ -185,7 +149,7 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
NULL,
|
||||
&propSize,
|
||||
&asbd)
|
||||
operation:"Failed to fill out the rest of the iLBC AudioStreamBasicDescription"];
|
||||
operation:"Failed to fill out the rest of the m4a AudioStreamBasicDescription"];
|
||||
|
||||
return asbd;
|
||||
}
|
||||
@@ -459,11 +423,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 +437,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 +448,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
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -599,31 +533,6 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Color Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Color Utility
|
||||
///-----------------------------------------------------------
|
||||
|
||||
+ (void)getColorComponentsFromCGColor:(CGColorRef)color
|
||||
red:(CGFloat *)red
|
||||
green:(CGFloat *)green
|
||||
blue:(CGFloat *)blue
|
||||
alpha:(CGFloat *)alpha
|
||||
{
|
||||
size_t componentCount = CGColorGetNumberOfComponents(color);
|
||||
if (componentCount == 4)
|
||||
{
|
||||
const CGFloat *components = CGColorGetComponents(color);
|
||||
*red = components[0];
|
||||
*green = components[1];
|
||||
*blue = components[2];
|
||||
*alpha = components[3];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - TPCircularBuffer Utility
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -651,94 +560,6 @@ BOOL __shouldExitOnCheckResultFail = YES;
|
||||
TPCircularBufferCleanup(circularBuffer);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#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
|
||||
{
|
||||
//
|
||||
// Do nothing if there is no buffer
|
||||
//
|
||||
if (bufferSize == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the scroll history datasource
|
||||
//
|
||||
TPCircularBufferProduceBytes(&historyInfo->circularBuffer, buffer, bufferSize * sizeof(float));
|
||||
int32_t targetBytes = historyInfo->bufferSize * sizeof(float);
|
||||
int32_t availableBytes = 0;
|
||||
float *historyBuffer = TPCircularBufferTail(&historyInfo->circularBuffer, &availableBytes);
|
||||
int32_t bytes = MIN(targetBytes, availableBytes);
|
||||
memmove(historyInfo->buffer, historyBuffer, bytes);
|
||||
if (targetBytes <= availableBytes)
|
||||
{
|
||||
TPCircularBufferConsume(&historyInfo->circularBuffer, availableBytes - targetBytes);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (void)clearHistoryInfo:(EZPlotHistoryInfo *)historyInfo
|
||||
{
|
||||
memset(historyInfo->buffer, 0, historyInfo->bufferSize * sizeof(float));
|
||||
TPCircularBufferClear(&historyInfo->circularBuffer);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (void)freeHistoryInfo:(EZPlotHistoryInfo *)historyInfo
|
||||
{
|
||||
free(historyInfo->buffer);
|
||||
free(historyInfo);
|
||||
TPCircularBufferCleanup(&historyInfo->circularBuffer);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (EZPlotHistoryInfo *)historyInfoWithDefaultLength:(int)defaultLength
|
||||
maximumLength:(int)maximumLength
|
||||
{
|
||||
//
|
||||
// Setup buffers
|
||||
//
|
||||
EZPlotHistoryInfo *historyInfo = (EZPlotHistoryInfo *)malloc(sizeof(EZPlotHistoryInfo));
|
||||
historyInfo->bufferSize = defaultLength;
|
||||
historyInfo->buffer = calloc(maximumLength, sizeof(float));
|
||||
TPCircularBufferInit(&historyInfo->circularBuffer, maximumLength);
|
||||
|
||||
//
|
||||
// Zero out circular buffer
|
||||
//
|
||||
float emptyBuffer[maximumLength];
|
||||
memset(emptyBuffer, 0, sizeof(emptyBuffer));
|
||||
TPCircularBufferProduceBytes(&historyInfo->circularBuffer,
|
||||
emptyBuffer,
|
||||
(int32_t)sizeof(emptyBuffer));
|
||||
|
||||
return historyInfo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
@end
|
||||
@@ -1,26 +0,0 @@
|
||||
//
|
||||
// EZAudioiOS.m
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Tommaso Piazza on 30/09/15.
|
||||
// Copyright © 2015 Andrew Breckenridge. 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 <EZAudioiOS/EZAudio.h>
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 9/2/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -36,7 +36,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZMicrophoneDelegate for the EZMicrophone provides a receiver for the incoming audio data events. When the microphone has been successfully internally configured it will try to send its delegate an AudioStreamBasicDescription describing the format of the incoming audio data.
|
||||
The delegate for the EZMicrophone provides a receiver for the incoming audio data events. When the microphone has been successfully internally configured it will try to send its delegate an AudioStreamBasicDescription describing the format of the incoming audio data.
|
||||
|
||||
The audio data itself is sent back to the delegate in various forms:
|
||||
|
||||
@@ -55,18 +55,10 @@
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called anytime the EZMicrophone starts or stops.
|
||||
@param output The instance of the EZMicrophone that triggered the event.
|
||||
@param isPlaying A BOOL indicating whether the EZMicrophone instance is playing or not.
|
||||
*/
|
||||
- (void)microphone:(EZMicrophone *)microphone changedPlayingState:(BOOL)isPlaying;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called anytime the input device changes on an `EZMicrophone` instance.
|
||||
Called anytime the input device changes on an `EZMicrophone` instance. Mac only.
|
||||
@param microphone The instance of the EZMicrophone that triggered the event.
|
||||
@param device The instance of the new EZAudioDevice the microphone is using to pull input.
|
||||
@param notification Incase the device changed because of a notification (like from AVAudioSession) then we provide that notification to give the full context of the change.
|
||||
*/
|
||||
- (void)microphone:(EZMicrophone *)microphone changedDevice:(EZAudioDevice *)device;
|
||||
|
||||
@@ -85,7 +77,7 @@
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
This method provides an array of float arrays of the audio received, each float array representing a channel of audio data This occurs on the background thread so any drawing code must explicity perform its functions on the main thread.
|
||||
Returns back a float array of the audio received. This occurs on the background thread so any drawing code must explicity perform its functions on the main thread.
|
||||
@param microphone The instance of the EZMicrophone that triggered the event.
|
||||
@param buffer The audio data as an array of float arrays. In a stereo signal buffer[0] represents the left channel while buffer[1] would represent the right channel.
|
||||
@param bufferSize The size of each of the buffers (the length of each float array).
|
||||
@@ -312,9 +304,7 @@
|
||||
*/
|
||||
- (AudioUnit *)audioUnit;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Microphone Stream Format
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 9/2/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -41,17 +41,6 @@ typedef struct EZMicrophoneInfo
|
||||
AudioStreamBasicDescription streamFormat;
|
||||
} EZMicrophoneInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Callbacks
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZMicrophone (Interface Extension)
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -70,14 +59,60 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[EZAudioUtilities checkResult:AudioUnitUninitialize(self.info->audioUnit)
|
||||
operation:"Failed to unintialize audio unit for microphone"];
|
||||
[EZAudioUtilities checkResult:AudioUnitUninitialize(self.info->audioUnit) operation:"Failed to unintialize audio unit for microphone"];
|
||||
[EZAudioUtilities freeBufferList:self.info->audioBufferList];
|
||||
[EZAudioUtilities freeFloatBuffers:self.info->floatData
|
||||
numberOfChannels:self.info->streamFormat.mChannelsPerFrame];
|
||||
free(self.info);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Callbacks
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData)
|
||||
{
|
||||
EZMicrophone *microphone = (__bridge EZMicrophone *)inRefCon;
|
||||
EZMicrophoneInfo *info = (EZMicrophoneInfo *)microphone.info;
|
||||
|
||||
// render audio into buffer
|
||||
OSStatus result = AudioUnitRender(info->audioUnit,
|
||||
ioActionFlags,
|
||||
inTimeStamp,
|
||||
inBusNumber,
|
||||
inNumberFrames,
|
||||
info->audioBufferList);
|
||||
|
||||
// notify delegate of new buffer list to process
|
||||
if ([microphone.delegate respondsToSelector:@selector(microphone:hasBufferList:withBufferSize:withNumberOfChannels:)])
|
||||
{
|
||||
[microphone.delegate microphone:microphone
|
||||
hasBufferList:info->audioBufferList
|
||||
withBufferSize:inNumberFrames
|
||||
withNumberOfChannels:info->streamFormat.mChannelsPerFrame];
|
||||
}
|
||||
|
||||
// notify delegate of new float data processed
|
||||
if ([microphone.delegate respondsToSelector:@selector(microphone:hasAudioReceived:withBufferSize:withNumberOfChannels:)])
|
||||
{
|
||||
// convert to float
|
||||
[microphone.floatConverter convertDataFromAudioBufferList:info->audioBufferList
|
||||
withNumberOfFrames:inNumberFrames
|
||||
toFloatBuffers:info->floatData];
|
||||
[microphone.delegate microphone:microphone
|
||||
hasAudioReceived:info->floatData
|
||||
withBufferSize:inNumberFrames
|
||||
withNumberOfChannels:info->streamFormat.mChannelsPerFrame];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initialization
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -117,7 +152,11 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
self = [self initWithMicrophoneDelegate:delegate];
|
||||
if(self)
|
||||
{
|
||||
[self setAudioStreamBasicDescription:audioStreamBasicDescription];
|
||||
self.info = (EZMicrophoneInfo *)malloc(sizeof(EZMicrophoneInfo));
|
||||
memset(self.info, 0, sizeof(EZMicrophoneInfo));
|
||||
self.info->streamFormat = audioStreamBasicDescription;
|
||||
_delegate = delegate;
|
||||
[self setup];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -217,9 +256,6 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
#elif TARGET_OS_MAC
|
||||
inputComponentDescription.componentSubType = kAudioUnitSubType_HALOutput;
|
||||
#endif
|
||||
// The following must be set to zero unless a specific value is requested.
|
||||
inputComponentDescription.componentFlags = 0;
|
||||
inputComponentDescription.componentFlagsMask = 0;
|
||||
|
||||
// get the first matching component
|
||||
AudioComponent inputComponent = AudioComponentFindNext( NULL , &inputComponentDescription);
|
||||
@@ -239,8 +275,13 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
&flag,
|
||||
sizeof(flag))
|
||||
operation:"Couldn't enable input on remote IO unit."];
|
||||
EZAudioDevice *currentInputDevice = [EZAudioDevice currentInputDevice];
|
||||
[self setDevice:currentInputDevice];
|
||||
#elif TARGET_OS_MAC
|
||||
NSArray *inputDevices = [EZAudioDevice inputDevices];
|
||||
EZAudioDevice *defaultMicrophone = [inputDevices lastObject];
|
||||
[self setDevice:defaultMicrophone];
|
||||
#endif
|
||||
[self setDevice:[EZAudioDevice currentInputDevice]];
|
||||
|
||||
UInt32 propSize = sizeof(self.info->inputFormat);
|
||||
[EZAudioUtilities checkResult:AudioUnitGetProperty(self.info->audioUnit,
|
||||
@@ -255,7 +296,11 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
NSAssert(self.info->inputFormat.mSampleRate, @"Expected AVAudioSession sample rate to be greater than 0.0. Did you setup the audio session?");
|
||||
#elif TARGET_OS_MAC
|
||||
#endif
|
||||
[self setAudioStreamBasicDescription:[self defaultStreamFormat]];
|
||||
if (self.info->streamFormat.mSampleRate == 0.0)
|
||||
{
|
||||
self.info->streamFormat = [self defaultStreamFormat];
|
||||
}
|
||||
[self setAudioStreamBasicDescription:self.info->streamFormat];
|
||||
|
||||
// render callback
|
||||
AURenderCallbackStruct renderCallbackStruct;
|
||||
@@ -340,38 +385,16 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
|
||||
-(void)startFetchingAudio
|
||||
{
|
||||
//
|
||||
// Start output unit
|
||||
//
|
||||
[EZAudioUtilities checkResult:AudioOutputUnitStart(self.info->audioUnit)
|
||||
operation:"Failed to start microphone audio unit"];
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(microphone:changedPlayingState:)])
|
||||
{
|
||||
[self.delegate microphone:self changedPlayingState:YES];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void)stopFetchingAudio
|
||||
{
|
||||
//
|
||||
// Stop output unit
|
||||
//
|
||||
[EZAudioUtilities checkResult:AudioOutputUnitStop(self.info->audioUnit)
|
||||
operation:"Failed to stop microphone audio unit"];
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(microphone:changedPlayingState:)])
|
||||
{
|
||||
[self.delegate microphone:self changedPlayingState:NO];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -433,9 +456,7 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
numberOfChannels:self.info->streamFormat.mChannelsPerFrame];
|
||||
}
|
||||
|
||||
//
|
||||
// Set new stream format
|
||||
//
|
||||
// set new stream format
|
||||
self.info->streamFormat = asbd;
|
||||
[EZAudioUtilities checkResult:AudioUnitSetProperty(self.info->audioUnit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
@@ -452,9 +473,7 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
sizeof(asbd))
|
||||
operation:"Failed to set stream format on output scope"];
|
||||
|
||||
//
|
||||
// Allocate scratch buffers
|
||||
//
|
||||
// allocate float buffers
|
||||
UInt32 maximumBufferSize = [self maximumBufferSize];
|
||||
BOOL isInterleaved = [EZAudioUtilities isInterleaved:asbd];
|
||||
UInt32 channels = asbd.mChannelsPerFrame;
|
||||
@@ -462,11 +481,10 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
self.info->floatData = [EZAudioUtilities floatBuffersWithNumberOfFrames:maximumBufferSize
|
||||
numberOfChannels:channels];
|
||||
self.info->audioBufferList = [EZAudioUtilities audioBufferListWithNumberOfFrames:maximumBufferSize
|
||||
numberOfChannels:channels
|
||||
interleaved:isInterleaved];
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
numberOfChannels:channels
|
||||
interleaved:isInterleaved];
|
||||
|
||||
// notify delegate
|
||||
if ([self.delegate respondsToSelector:@selector(microphone:hasAudioStreamBasicDescription:)])
|
||||
{
|
||||
[self.delegate microphone:self hasAudioStreamBasicDescription:asbd];
|
||||
@@ -536,14 +554,10 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
operation:"Couldn't set default device on I/O unit"];
|
||||
#endif
|
||||
|
||||
//
|
||||
// Store device
|
||||
//
|
||||
// store device
|
||||
_device = device;
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
// notify delegate
|
||||
if ([self.delegate respondsToSelector:@selector(microphone:changedDevice:)])
|
||||
{
|
||||
[self.delegate microphone:self changedDevice:device];
|
||||
@@ -557,23 +571,21 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
- (void)setOutput:(EZOutput *)output
|
||||
{
|
||||
_output = output;
|
||||
_output.inputFormat = self.audioStreamBasicDescription;
|
||||
_output.dataSource = self;
|
||||
[_output setAudioStreamBasicDescription:self.audioStreamBasicDescription];
|
||||
_output.outputDataSource = self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDataSource
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (OSStatus) output:(EZOutput *)output
|
||||
- (void) output:(EZOutput *)output
|
||||
shouldFillAudioBufferList:(AudioBufferList *)audioBufferList
|
||||
withNumberOfFrames:(UInt32)frames
|
||||
timestamp:(const AudioTimeStamp *)timestamp
|
||||
{
|
||||
memcpy(audioBufferList,
|
||||
self.info->audioBufferList,
|
||||
sizeof(AudioBufferList) + (self.info->audioBufferList->mNumberBuffers - 1)*sizeof(AudioBuffer));
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -590,76 +602,9 @@ static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
|
||||
- (UInt32)numberOfChannels
|
||||
{
|
||||
#if TARGET_OS_IPHONE
|
||||
return 1;
|
||||
#elif TARGET_OS_MAC
|
||||
return (UInt32)self.device.inputChannelCount;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Callbacks
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static OSStatus EZAudioMicrophoneCallback(void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData)
|
||||
{
|
||||
EZMicrophone *microphone = (__bridge EZMicrophone *)inRefCon;
|
||||
EZMicrophoneInfo *info = (EZMicrophoneInfo *)microphone.info;
|
||||
|
||||
//
|
||||
// Make sure the size of each buffer in the stored buffer array
|
||||
// is properly set using the actual number of frames coming in!
|
||||
//
|
||||
for (int i = 0; i < info->audioBufferList->mNumberBuffers; i++) {
|
||||
info->audioBufferList->mBuffers[i].mDataByteSize = inNumberFrames * info->streamFormat.mBytesPerFrame;
|
||||
}
|
||||
|
||||
//
|
||||
// Render audio into buffer
|
||||
//
|
||||
OSStatus result = AudioUnitRender(info->audioUnit,
|
||||
ioActionFlags,
|
||||
inTimeStamp,
|
||||
inBusNumber,
|
||||
inNumberFrames,
|
||||
info->audioBufferList);
|
||||
|
||||
//
|
||||
// Notify delegate of new buffer list to process
|
||||
//
|
||||
if ([microphone.delegate respondsToSelector:@selector(microphone:hasBufferList:withBufferSize:withNumberOfChannels:)])
|
||||
{
|
||||
[microphone.delegate microphone:microphone
|
||||
hasBufferList:info->audioBufferList
|
||||
withBufferSize:inNumberFrames
|
||||
withNumberOfChannels:info->streamFormat.mChannelsPerFrame];
|
||||
}
|
||||
|
||||
//
|
||||
// Notify delegate of new float data processed
|
||||
//
|
||||
if ([microphone.delegate respondsToSelector:@selector(microphone:hasAudioReceived:withBufferSize:withNumberOfChannels:)])
|
||||
{
|
||||
//
|
||||
// Convert to float
|
||||
//
|
||||
[microphone.floatConverter convertDataFromAudioBufferList:info->audioBufferList
|
||||
withNumberOfFrames:inNumberFrames
|
||||
toFloatBuffers:info->floatData];
|
||||
[microphone.delegate microphone:microphone
|
||||
hasAudioReceived:info->floatData
|
||||
withBufferSize:inNumberFrames
|
||||
withNumberOfChannels:info->streamFormat.mChannelsPerFrame];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@end
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/2/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -30,102 +30,72 @@
|
||||
#import <AudioUnit/AudioUnit.h>
|
||||
#endif
|
||||
|
||||
@class EZAudioDevice;
|
||||
#import "TPCircularBuffer.h"
|
||||
|
||||
@class EZOutput;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Constants
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
FOUNDATION_EXPORT UInt32 const EZOutputMaximumFramesPerSlice;
|
||||
FOUNDATION_EXPORT Float64 const EZOutputDefaultSampleRate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDataSource
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZOutputDataSource specifies a receiver to provide audio data when the EZOutput is started. Since the 0.4.0 release this has been simplified to only one data source method.
|
||||
The EZOutputDataSource (required for the EZOutput) specifies a receiver to provide audio data when the EZOutput is started. Only ONE datasource method is expected to be implemented and priority is given as such:
|
||||
1.) `output:callbackWithActionFlags:inTimeStamp:inBusNumber:inNumberFrames:ioData:`
|
||||
2.) `outputShouldUseCircularBuffer:`
|
||||
3.) `output:needsBufferListWithFrames:withBufferSize:`
|
||||
*/
|
||||
@protocol EZOutputDataSource <NSObject>
|
||||
|
||||
@optional
|
||||
///-----------------------------------------------------------
|
||||
/// @name Providing Audio Data
|
||||
/// @name Pulling The Audio Data
|
||||
///-----------------------------------------------------------
|
||||
|
||||
@required
|
||||
/**
|
||||
Provides complete override of the output callback function. The delegate is expected to
|
||||
@param output The instance of the EZOutput that asked for the data
|
||||
@param ioActionFlags AudioUnitRenderActionFlags provided by the output callback
|
||||
@param inTimeStamp AudioTimeStamp reference provided by the output callback
|
||||
@param inBusNumber UInt32 representing the bus number provided by the output callback
|
||||
@param inNumberFrames UInt32 representing the number of frames provided by the output callback
|
||||
@param ioData AudioBufferList pointer representing the audio data that will be used for output provided by the output callback (fill this!)
|
||||
*/
|
||||
-(void)output:(EZOutput*)output
|
||||
callbackWithActionFlags:(AudioUnitRenderActionFlags*)ioActionFlags
|
||||
inTimeStamp:(const AudioTimeStamp*)inTimeStamp
|
||||
inBusNumber:(UInt32)inBusNumber
|
||||
inNumberFrames:(UInt32)inNumberFrames
|
||||
ioData:(AudioBufferList*)ioData;
|
||||
|
||||
/**
|
||||
Provides a way to provide output with data anytime the EZOutput needs audio data to play. This function provides an already allocated AudioBufferList to use for providing audio data into the output buffer. The expected format of the audio data provided here is specified by the EZOutput `inputFormat` property. This audio data will be converted into the client format specified by the EZOutput `clientFormat` property.
|
||||
Provides output using a circular
|
||||
@param output The instance of the EZOutput that asked for the data
|
||||
@return The EZOutputDataSource's TPCircularBuffer structure holding the audio data in a circular buffer
|
||||
*/
|
||||
-(TPCircularBuffer*)outputShouldUseCircularBuffer:(EZOutput *)output;
|
||||
|
||||
|
||||
/**
|
||||
Provides a way to provide output with data anytime the EZOutput needs audio data to play. This function provides an already allocated AudioBufferList to use for providing audio data into the output buffer.
|
||||
@param output The instance of the EZOutput that asked for the data.
|
||||
@param audioBufferList The AudioBufferList structure pointer that needs to be filled with audio data
|
||||
@param frames The amount of frames as a UInt32 that output will need to properly fill its output buffer.
|
||||
@param timestamp A AudioTimeStamp pointer to use if you need the current host time.
|
||||
@return An OSStatus code. If there was no error then use the noErr status code.
|
||||
@return A pointer to the AudioBufferList structure holding the audio data. If nil or NULL, will output silence.
|
||||
*/
|
||||
- (OSStatus) output:(EZOutput *)output
|
||||
shouldFillAudioBufferList:(AudioBufferList *)audioBufferList
|
||||
withNumberOfFrames:(UInt32)frames
|
||||
timestamp:(const AudioTimeStamp *)timestamp;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZOutputDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZOutputDelegate for the EZOutput component provides a receiver to handle play state, device, and audio data change events. This is very similar to the EZMicrophoneDelegate for the EZMicrophone and the EZAudioFileDelegate for the EZAudioFile.
|
||||
*/
|
||||
@protocol EZOutputDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
Called anytime the EZOutput starts or stops.
|
||||
@param output The instance of the EZOutput that triggered the event.
|
||||
@param isPlaying A BOOL indicating whether the EZOutput instance is playing or not.
|
||||
*/
|
||||
- (void)output:(EZOutput *)output changedPlayingState:(BOOL)isPlaying;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Called anytime the `device` changes on an EZOutput instance.
|
||||
@param output The instance of the EZOutput that triggered the event.
|
||||
@param device The instance of the new EZAudioDevice the output is using to play audio data.
|
||||
*/
|
||||
- (void)output:(EZOutput *)output changedDevice:(EZAudioDevice *)device;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Like the EZMicrophoneDelegate, for the EZOutput this method provides an array of float arrays of the audio received, each float array representing a channel of audio data. This occurs on the background thread so any drawing code must explicity perform its functions on the main thread.
|
||||
@param output The instance of the EZOutput that triggered the event.
|
||||
@param buffer The audio data as an array of float arrays. In a stereo signal buffer[0] represents the left channel while buffer[1] would represent the right channel.
|
||||
@param bufferSize A UInt32 representing the size of each of the buffers (the length of each float array).
|
||||
@param numberOfChannels A UInt32 representing the number of channels (you can use this to know how many float arrays are in the `buffer` parameter.
|
||||
@warning This function executes on a background thread to avoid blocking any audio operations. If operations should be performed on any other thread (like the main thread) it should be performed within a dispatch block like so: dispatch_async(dispatch_get_main_queue(), ^{ ...Your Code... })
|
||||
*/
|
||||
- (void) output:(EZOutput *)output
|
||||
playedAudio:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(void) output:(EZOutput *)output
|
||||
shouldFillAudioBufferList:(AudioBufferList*)audioBufferList
|
||||
withNumberOfFrames:(UInt32)frames;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
The EZOutput component provides a generic output to glue all the other EZAudio components together and push whatever sound you've created to the default output device (think opposite of the microphone). The EZOutputDataSource provides the required AudioBufferList needed to populate the output buffer while the EZOutputDelegate provides the same kind of mechanism as the EZMicrophoneDelegate or EZAudioFileDelegate in that you will receive a callback that provides non-interleaved, float data for visualizing the output (done using an internal float converter). As of 0.4.0 the EZOutput has been simplified to a single EZOutputDataSource method and now uses an AUGraph to provide format conversion from the `inputFormat` to the playback graph's `clientFormat` linear PCM formats, mixer controls for setting volume and pan settings, hooks to add in any number of effect audio units (see the `connectOutputOfSourceNode:sourceNodeOutputBus:toDestinationNode:destinationNodeInputBus:inGraph:` subclass method), and hardware device toggling (via EZAudioDevice).
|
||||
The EZOutput component provides a generic output to glue all the other EZAudio components together and push whatever sound you've created to the default output device (think opposite of the microphone). The EZOutputDataSource provides the required AudioBufferList needed to populate the output buffer.
|
||||
*/
|
||||
@interface EZOutput : NSObject
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
/**
|
||||
The EZOutputDataSource that provides the required AudioBufferList to the output callback function
|
||||
*/
|
||||
@property (nonatomic,assign) id<EZOutputDataSource>outputDataSource;
|
||||
|
||||
#pragma mark - Initializers
|
||||
///-----------------------------------------------------------
|
||||
/// @name Initializers
|
||||
///-----------------------------------------------------------
|
||||
@@ -135,38 +105,29 @@ FOUNDATION_EXPORT Float64 const EZOutputDefaultSampleRate;
|
||||
@param dataSource The EZOutputDataSource that will be used to pull the audio data for the output callback.
|
||||
@return A newly created instance of the EZOutput class.
|
||||
*/
|
||||
- (instancetype)initWithDataSource:(id<EZOutputDataSource>)dataSource;
|
||||
-(id)initWithDataSource:(id<EZOutputDataSource>)dataSource;
|
||||
|
||||
/**
|
||||
Creates a new instance of the EZOutput and allows the caller to specify an EZOutputDataSource.
|
||||
@param dataSource The EZOutputDataSource that will be used to pull the audio data for the output callback.
|
||||
@param inputFormat The AudioStreamBasicDescription of the EZOutput.
|
||||
@warning AudioStreamBasicDescription input formats must be linear PCM!
|
||||
@param audioStreamBasicDescription The AudioStreamBasicDescription of the EZOutput.
|
||||
@warning AudioStreamBasicDescriptions that are invalid will cause the EZOutput to fail to initialize
|
||||
@return A newly created instance of the EZOutput class.
|
||||
*/
|
||||
- (instancetype)initWithDataSource:(id<EZOutputDataSource>)dataSource
|
||||
inputFormat:(AudioStreamBasicDescription)inputFormat;
|
||||
-(id) initWithDataSource:(id<EZOutputDataSource>)dataSource
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create a new instance of the EZOutput
|
||||
@return A newly created instance of the EZOutput class.
|
||||
*/
|
||||
+ (instancetype)output;
|
||||
|
||||
/**
|
||||
Class method to create a new instance of the EZOutput and allows the caller to specify an EZOutputDataSource.
|
||||
@param dataSource The EZOutputDataSource that will be used to pull the audio data for the output callback.
|
||||
@return A newly created instance of the EZOutput class.
|
||||
*/
|
||||
+ (instancetype)outputWithDataSource:(id<EZOutputDataSource>)dataSource;
|
||||
+(EZOutput*)outputWithDataSource:(id<EZOutputDataSource>)dataSource;
|
||||
|
||||
/**
|
||||
Class method to create a new instance of the EZOutput and allows the caller to specify an EZOutputDataSource.
|
||||
@@ -175,13 +136,10 @@ FOUNDATION_EXPORT Float64 const EZOutputDefaultSampleRate;
|
||||
@warning AudioStreamBasicDescriptions that are invalid will cause the EZOutput to fail to initialize
|
||||
@return A newly created instance of the EZOutput class.
|
||||
*/
|
||||
+ (instancetype)outputWithDataSource:(id<EZOutputDataSource>)dataSource
|
||||
inputFormat:(AudioStreamBasicDescription)inputFormat;
|
||||
+(EZOutput*)outputWithDataSource:(id<EZOutputDataSource>)dataSource
|
||||
withAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Singleton
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Shared Instance
|
||||
///-----------------------------------------------------------
|
||||
@@ -190,123 +148,9 @@ FOUNDATION_EXPORT Float64 const EZOutputDefaultSampleRate;
|
||||
Creates a shared instance of the EZOutput (one app will usually only need one output and share the role of the EZOutputDataSource).
|
||||
@return The shared instance of the EZOutput class.
|
||||
*/
|
||||
+ (instancetype)sharedOutput;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Setting/Getting The Stream Formats
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the AudioStreamBasicDescription structure used at the beginning of the playback graph which is then converted into the `clientFormat` using the AUConverter audio unit.
|
||||
@warning The AudioStreamBasicDescription set here must be linear PCM. Compressed formats are not supported...the EZAudioFile's clientFormat performs the audio conversion on the fly from compressed to linear PCM so there is no additional work to be done there.
|
||||
@return An AudioStreamBasicDescription structure describing
|
||||
*/
|
||||
@property (nonatomic, readwrite) AudioStreamBasicDescription inputFormat;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the AudioStreamBasicDescription structure that serves as the common format used throughout the playback graph (similar to how the EZAudioFile as a clientFormat that is linear PCM to be shared amongst other components). The `inputFormat` is converted into this format at the beginning of the playback graph using an AUConverter audio unit. Defaults to the whatever the `defaultClientFormat` method returns is if a custom one isn't explicitly set.
|
||||
@warning The AudioStreamBasicDescription set here must be linear PCM. Compressed formats are not supported by Audio Units.
|
||||
@return An AudioStreamBasicDescription structure describing the common client format for the playback graph.
|
||||
*/
|
||||
@property (nonatomic, readwrite) AudioStreamBasicDescription clientFormat;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Setting/Getting The Data Source and Delegate
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZOutputDataSource that provides the audio data in the `inputFormat` for the EZOutput to play. If an EZOutputDataSource is not specified then the EZOutput will just output silence.
|
||||
*/
|
||||
@property (nonatomic, weak) id<EZOutputDataSource> dataSource;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZOutputDelegate for which to handle the output callbacks
|
||||
*/
|
||||
@property (nonatomic, weak) id<EZOutputDelegate> delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides a flag indicating whether the EZOutput is pulling audio data from the EZOutputDataSource for playback.
|
||||
@return YES if the EZOutput is running, NO if it is stopped
|
||||
*/
|
||||
@property (readonly) BOOL isPlaying;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current pan from the audio player's mixer audio unit in the playback graph. Setting the pan adjusts the direction of the audio signal from left (0) to right (1). Default is 0.5 (middle).
|
||||
*/
|
||||
@property (nonatomic, assign) float pan;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current volume from the audio player's mixer audio unit in the playback graph. Setting the volume adjusts the gain of the output between 0 and 1. Default is 1.
|
||||
*/
|
||||
@property (nonatomic, assign) float volume;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Core Audio Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Core Audio Properties
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
The AUGraph used to chain together the converter, mixer, and output audio units.
|
||||
*/
|
||||
@property (readonly) AUGraph graph;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The AudioUnit that is being used to convert the audio data coming into the output's playback graph.
|
||||
*/
|
||||
@property (readonly) AudioUnit converterAudioUnit;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The AudioUnit that is being used as the mixer to adjust the volume on the output's playback graph.
|
||||
*/
|
||||
@property (readonly) AudioUnit mixerAudioUnit;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The AudioUnit that is being used as the hardware output for the output's playback graph.
|
||||
*/
|
||||
@property (readonly) AudioUnit outputAudioUnit;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Getting/Setting The Output's Hardware Device
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
An EZAudioDevice instance that is used to route the audio data out to the speaker. To find a list of available output devices see the EZAudioDevice `outputDevices` method.
|
||||
*/
|
||||
@property (nonatomic, strong, readwrite) EZAudioDevice *device;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
+(EZOutput*)sharedOutput;
|
||||
|
||||
#pragma mark - Events
|
||||
///-----------------------------------------------------------
|
||||
/// @name Starting/Stopping The Output
|
||||
///-----------------------------------------------------------
|
||||
@@ -314,63 +158,44 @@ FOUNDATION_EXPORT Float64 const EZOutputDefaultSampleRate;
|
||||
/**
|
||||
Starts pulling audio data from the EZOutputDataSource to the default device output.
|
||||
*/
|
||||
- (void)startPlayback;
|
||||
|
||||
///-----------------------------------------------------------
|
||||
-(void)startPlayback;
|
||||
|
||||
/**
|
||||
Stops pulling audio data from the EZOutputDataSource to the default device output.
|
||||
*/
|
||||
- (void)stopPlayback;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Subclass
|
||||
//------------------------------------------------------------------------------
|
||||
-(void)stopPlayback;
|
||||
|
||||
#pragma mark - Getters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Subclass
|
||||
/// @name Getting The Output Audio Format
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
This method handles connecting the converter node to the mixer node within the AUGraph that is being used as the playback graph. Subclasses can override this method and insert their custom nodes to perform effects processing on the audio data being rendered.
|
||||
|
||||
This was inspired by Daniel Kennett's blog post on how to add a custom equalizer to a CocoaLibSpotify SPCoreAudioController's AUGraph. For more information see Daniel's post and example code here: http://ikennd.ac/blog/2012/04/augraph-basics-in-cocoalibspotify/.
|
||||
@param sourceNode An AUNode representing the node the audio data is coming from.
|
||||
@param sourceNodeOutputBus A UInt32 representing the output bus from the source node that should be connected into the next node's input bus.
|
||||
@param destinationNode An AUNode representing the node the audio data should be connected to.
|
||||
@param destinationNodeInputBus A UInt32 representing the input bus the source node's output bus should be connecting to.
|
||||
@param graph The AUGraph that is being used to hold the playback graph. Same as from the `graph` property.
|
||||
@return An OSStatus code. For no error return back `noErr`.
|
||||
Provides the AudioStreamBasicDescription structure containing the format of the microphone's audio.
|
||||
@return An AudioStreamBasicDescription structure describing the format of the microphone's audio.
|
||||
*/
|
||||
- (OSStatus)connectOutputOfSourceNode:(AUNode)sourceNode
|
||||
sourceNodeOutputBus:(UInt32)sourceNodeOutputBus
|
||||
toDestinationNode:(AUNode)destinationNode
|
||||
destinationNodeInputBus:(UInt32)destinationNodeInputBus
|
||||
inGraph:(AUGraph)graph;
|
||||
-(AudioStreamBasicDescription)audioStreamBasicDescription;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
///-----------------------------------------------------------
|
||||
/// @name Getting The State Of The Output
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
The default AudioStreamBasicDescription set as the client format of the output if no custom `clientFormat` is set. Defaults to a 44.1 kHz stereo, non-interleaved, float format.
|
||||
@return An AudioStreamBasicDescription that will be used as the default stream format.
|
||||
Provides a flag indicating whether the EZOutput is pulling audio data from the EZOutputDataSource for playback.
|
||||
@return YES if the EZOutput is pulling audio data to the output device, NO if it is stopped
|
||||
*/
|
||||
- (AudioStreamBasicDescription)defaultClientFormat;
|
||||
-(BOOL)isPlaying;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Output Format
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
The default AudioStreamBasicDescription set as the `inputFormat` of the output if no custom `inputFormat` is set. Defaults to a 44.1 kHz stereo, non-interleaved, float format.
|
||||
@return An AudioStreamBasicDescription that will be used as the default stream format.
|
||||
Sets the AudioStreamBasicDescription on the output.
|
||||
@warning Do not set this during playback.
|
||||
@param asbd The new AudioStreamBasicDescription to use in place of the current audio format description.
|
||||
*/
|
||||
- (AudioStreamBasicDescription)defaultInputFormat;
|
||||
-(void)setAudioStreamBasicDescription:(AudioStreamBasicDescription)asbd;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The default value used as the AudioUnit subtype when creating the hardware output component. By default this is kAudioUnitSubType_RemoteIO for iOS and kAudioUnitSubType_HALOutput for OSX.
|
||||
@warning If you change this to anything other than kAudioUnitSubType_HALOutput for OSX you will get a failed assertion because devices can only be set when using the HAL audio unit.
|
||||
@return An OSType that represents the AudioUnit subtype for the hardware output component.
|
||||
*/
|
||||
- (OSType)outputAudioUnitSubType;
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 11/24/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,12 +24,8 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Enumerations
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Plot Types
|
||||
///-----------------------------------------------------------
|
||||
@@ -37,17 +33,15 @@
|
||||
/**
|
||||
The types of plots that can be displayed in the view using the data.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, EZPlotType)
|
||||
{
|
||||
/**
|
||||
Plot that displays only the samples of the current buffer
|
||||
*/
|
||||
EZPlotTypeBuffer,
|
||||
|
||||
/**
|
||||
Plot that displays a rolling history of values using the RMS calculated for each incoming buffer
|
||||
*/
|
||||
EZPlotTypeRolling
|
||||
typedef NS_ENUM(NSInteger,EZPlotType){
|
||||
/**
|
||||
Plot that displays only the samples of the current buffer
|
||||
*/
|
||||
EZPlotTypeBuffer,
|
||||
/**
|
||||
Plot that displays a rolling history of values using the RMS calculated for each incoming buffer
|
||||
*/
|
||||
EZPlotTypeRolling
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -65,55 +59,41 @@ typedef NS_ENUM(NSInteger, EZPlotType)
|
||||
@interface EZPlot : NSView
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Customizing The Plot's Appearance
|
||||
///-----------------------------------------------------------
|
||||
/**
|
||||
The default background color of the plot. For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is black.
|
||||
*/
|
||||
#if TARGET_OS_IPHONE
|
||||
@property (nonatomic, strong) IBInspectable UIColor *backgroundColor;
|
||||
#elif TARGET_OS_MAC
|
||||
@property (nonatomic, strong) IBInspectable NSColor *backgroundColor;
|
||||
#endif
|
||||
@property (nonatomic,strong) id backgroundColor;
|
||||
|
||||
/**
|
||||
The default color of the plot's data (i.e. waveform, y-axis values). For iOS the color is specified as a UIColor while for OSX the color is an NSColor. The default value on both platforms is red.
|
||||
*/
|
||||
#if TARGET_OS_IPHONE
|
||||
@property (nonatomic, strong) IBInspectable UIColor *color;
|
||||
#elif TARGET_OS_MAC
|
||||
@property (nonatomic, strong) IBInspectable NSColor *color;
|
||||
#endif
|
||||
@property (nonatomic,strong) id color;
|
||||
|
||||
/**
|
||||
The plot's gain value, which controls the scale of the y-axis values. The default value of the gain is 1.0f and should always be greater than 0.0f.
|
||||
*/
|
||||
@property (nonatomic, assign) IBInspectable float gain;
|
||||
@property (nonatomic,assign,setter=setGain:) float gain;
|
||||
|
||||
/**
|
||||
The type of plot as specified by the `EZPlotType` enumeration (i.e. a buffer or rolling plot type).
|
||||
*/
|
||||
@property (nonatomic, assign) IBInspectable EZPlotType plotType;
|
||||
@property (nonatomic,assign,setter=setPlotType:) EZPlotType plotType;
|
||||
|
||||
/**
|
||||
A boolean indicating whether or not to fill in the graph. A value of YES will make a filled graph (filling in the space between the x-axis and the y-value), while a value of NO will create a stroked graph (connecting the points along the y-axis).
|
||||
*/
|
||||
@property (nonatomic, assign) IBInspectable BOOL shouldFill;
|
||||
@property (nonatomic,assign,setter=setShouldFill:) BOOL shouldFill;
|
||||
|
||||
/**
|
||||
A boolean indicating whether the graph should be rotated along the x-axis to give a mirrored reflection. This is typical for audio plots to produce the classic waveform look. A value of YES will produce a mirrored reflection of the y-values about the x-axis, while a value of NO will only plot the y-values.
|
||||
*/
|
||||
@property (nonatomic, assign) IBInspectable BOOL shouldMirror;
|
||||
@property (nonatomic,assign,setter=setShouldMirror:) BOOL shouldMirror;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Clearing
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Clearing The Plot
|
||||
///-----------------------------------------------------------
|
||||
@@ -123,10 +103,7 @@ typedef NS_ENUM(NSInteger, EZPlotType)
|
||||
*/
|
||||
-(void)clear;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Get Samples
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Updating The Plot
|
||||
///-----------------------------------------------------------
|
||||
@@ -137,6 +114,7 @@ typedef NS_ENUM(NSInteger, EZPlotType)
|
||||
@param bufferSize The size of the float array that will be mapped to the y-axis.
|
||||
@warning The bufferSize is expected to be the same, constant value once initial triggered. For plots using OpenGL a vertex buffer object will be allocated with a maximum buffersize of (2 * the initial given buffer size) to account for any interpolation necessary for filling in the graph. Updates use the glBufferSubData(...) function, which will crash if the buffersize exceeds the initial maximum allocated size.
|
||||
*/
|
||||
-(void)updateBuffer:(float *)buffer withBufferSize:(UInt32)bufferSize;
|
||||
-(void)updateBuffer:(float *)buffer
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
@end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 11/24/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,12 +26,6 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
@class EZRecorder;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Data Structures
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
To ensure valid recording formats are used when recording to a file the EZRecorderFileType describes the most common file types that a file can be encoded in. Each of these types can be used to output recordings as such:
|
||||
|
||||
@@ -56,290 +50,57 @@ typedef NS_ENUM(NSInteger, EZRecorderFileType)
|
||||
EZRecorderFileTypeWAV
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZRecorderDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZRecorderDelegate for the EZRecorder provides a receiver for write events, `recorderUpdatedCurrentTime:`, and the close event, `recorderDidClose:`.
|
||||
*/
|
||||
@protocol EZRecorderDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
Triggers when the EZRecorder is explicitly closed with the `closeAudioFile` method.
|
||||
@param recorder The EZRecorder instance that triggered the action
|
||||
*/
|
||||
- (void)recorderDidClose:(EZRecorder *)recorder;
|
||||
|
||||
/**
|
||||
Triggers after the EZRecorder has successfully written audio data from the `appendDataFromBufferList:withBufferSize:` method.
|
||||
@param recorder The EZRecorder instance that triggered the action
|
||||
*/
|
||||
- (void)recorderUpdatedCurrentTime:(EZRecorder *)recorder;
|
||||
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZRecorder
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
The EZRecorder provides a flexible way to create an audio file and append raw audio data to it. The EZRecorder will convert the incoming audio on the fly to the destination format so no conversion is needed between this and any other component. Right now the only supported output format is 'caf'. Each output file should have its own EZRecorder instance (think 1 EZRecorder = 1 audio file).
|
||||
*/
|
||||
@interface EZRecorder : NSObject
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
An EZRecorderDelegate to listen for the write and close events.
|
||||
*/
|
||||
@property (nonatomic, weak) id<EZRecorderDelegate> delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), and a file type (see `EZRecorderFileType`) that will automatically create an internal `fileFormat` and audio file type hint.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), and a file type (see `EZRecorderFileType`) that will automatically create an internal `fileFormat` and audio file type hint, as well as a delegate to respond to the recorder's write and close events.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@param delegate An EZRecorderDelegate to listen for the recorder's write and close events.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
delegate:(id<EZRecorderDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), a file format describing the destination format on disk (see `fileFormat` for more info), and an audio file type (an AudioFileTypeID for Core Audio, not a EZRecorderFileType).
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileFormat An AudioStreamBasicDescription describing the format of the audio being written to disk (MP3, AAC, WAV, etc)
|
||||
@param audioFileTypeID An AudioFileTypeID that matches your fileFormat (i.e. kAudioFileM4AType for an M4A format)
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), a file format describing the destination format on disk (see `fileFormat` for more info), an audio file type (an AudioFileTypeID for Core Audio, not a EZRecorderFileType), and delegate to respond to the recorder's write and close events.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileFormat An AudioStreamBasicDescription describing the format of the audio being written to disk (MP3, AAC, WAV, etc)
|
||||
@param audioFileTypeID An AudioFileTypeID that matches your fileFormat (i.e. kAudioFileM4AType for an M4A format)
|
||||
@param delegate An EZRecorderDelegate to listen for the recorder's write and close events.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
delegate:(id<EZRecorderDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Creates a new instance of an EZRecorder using a destination file path URL and the source format of the incoming audio.
|
||||
@param url An NSURL specifying the file path location of where the audio file should be written to.
|
||||
@param sourceFormat The AudioStreamBasicDescription for the incoming audio that will be written to the file.
|
||||
@param destinationFileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@deprecated This property is deprecated starting in version 0.8.0.
|
||||
@note Please use `initWithURL:clientFormat:fileType:` initializer instead.
|
||||
@return The newly created EZRecorder instance.
|
||||
*/
|
||||
- (instancetype)initWithDestinationURL:(NSURL*)url
|
||||
-(EZRecorder*)initWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType __attribute__((deprecated));
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Class Initializers
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), and a file type (see `EZRecorderFileType`) that will automatically create an internal `fileFormat` and audio file type hint.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), and a file type (see `EZRecorderFileType`) that will automatically create an internal `fileFormat` and audio file type hint, as well as a delegate to respond to the recorder's write and close events.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@param delegate An EZRecorderDelegate to listen for the recorder's write and close events.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
delegate:(id<EZRecorderDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), a file format describing the destination format on disk (see `fileFormat` for more info), and an audio file type (an AudioFileTypeID for Core Audio, not a EZRecorderFileType).
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileFormat An AudioStreamBasicDescription describing the format of the audio being written to disk (MP3, AAC, WAV, etc)
|
||||
@param audioFileTypeID An AudioFileTypeID that matches your fileFormat (i.e. kAudioFileM4AType for an M4A format)
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create an instance of the EZRecorder with a file path URL to write out the file to, a client format describing the in-application common format (see `clientFormat` for more info), a file format describing the destination format on disk (see `fileFormat` for more info), an audio file type (an AudioFileTypeID for Core Audio, not a EZRecorderFileType), and delegate to respond to the recorder's write and close events.
|
||||
@param url An NSURL representing the file path the output file should be written
|
||||
@param clientFormat An AudioStreamBasicDescription describing the in-applciation common format (always linear PCM)
|
||||
@param fileFormat An AudioStreamBasicDescription describing the format of the audio being written to disk (MP3, AAC, WAV, etc)
|
||||
@param audioFileTypeID An AudioFileTypeID that matches your fileFormat (i.e. kAudioFileM4AType for an M4A format)
|
||||
@param delegate An EZRecorderDelegate to listen for the recorder's write and close events.
|
||||
@return A newly created EZRecorder instance.
|
||||
*/
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
delegate:(id<EZRecorderDelegate>)delegate;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Class method to create a new instance of an EZRecorder using a destination file path URL and the source format of the incoming audio.
|
||||
@param url An NSURL specifying the file path location of where the audio file should be written to.
|
||||
@param sourceFormat The AudioStreamBasicDescription for the incoming audio that will be written to the file (also called the `clientFormat`).
|
||||
@param sourceFormat The AudioStreamBasicDescription for the incoming audio that will be written to the file.
|
||||
@param destinationFileType A constant described by the EZRecorderFileType that corresponds to the type of destination file that should be written. For instance, an AAC file written using an '.m4a' extension would correspond to EZRecorderFileTypeM4A. See EZRecorderFileType for all the constants and mapping combinations.
|
||||
@return The newly created EZRecorder instance.
|
||||
*/
|
||||
+ (instancetype)recorderWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType __attribute__((deprecated));
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
+(EZRecorder*)recorderWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType;
|
||||
|
||||
#pragma mark - Getters
|
||||
///-----------------------------------------------------------
|
||||
/// @name Getting The Recorder's Properties
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the common AudioStreamBasicDescription that will be used for in-app interaction. The recorder's format will be converted from this format to the `fileFormat`. For instance, the file on disk could be a 22.5 kHz, float format, but we might have an audio processing graph that has a 44.1 kHz, signed integer format that we'd like to interact with. The client format lets us set that 44.1 kHz format on the recorder to properly write samples from the graph out to the file in the desired destination format.
|
||||
@warning This must be a linear PCM format!
|
||||
@return An AudioStreamBasicDescription structure describing the format of the audio file.
|
||||
*/
|
||||
@property (readwrite) AudioStreamBasicDescription clientFormat;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current write offset in the audio file as an NSTimeInterval (i.e. in seconds). When setting this it will determine the correct frame offset and perform a `seekToFrame` to the new time offset.
|
||||
@warning Make sure the new current time offset is less than the `duration` or you will receive an invalid seek assertion.
|
||||
*/
|
||||
@property (readonly) NSTimeInterval currentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration of the audio file in seconds.
|
||||
*/
|
||||
@property (readonly) NSTimeInterval duration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the AudioStreamBasicDescription structure containing the format of the recorder's audio file.
|
||||
@return An AudioStreamBasicDescription structure describing the format of the audio file.
|
||||
*/
|
||||
@property (readonly) AudioStreamBasicDescription fileFormat;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the current time as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedCurrentTime;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the duration as an NSString with the time format MM:SS.
|
||||
*/
|
||||
@property (readonly) NSString *formattedDuration;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the frame index (a.k.a the write positon) within the audio file as SInt64. This can be helpful when seeking through the audio file.
|
||||
@return The current frame index within the audio file as a SInt64.
|
||||
*/
|
||||
@property (readonly) SInt64 frameIndex;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the total frame count of the recorder's audio file in the file format.
|
||||
@return The total number of frames in the recorder in the AudioStreamBasicDescription representing the file format as a SInt64.
|
||||
*/
|
||||
@property (readonly) SInt64 totalFrames;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Provides the file path that's currently being used by the recorder.
|
||||
@return The NSURL representing the file path of the recorder path being used for recording.
|
||||
@return The NSURL representing the file path of the audio file path being used for recording.
|
||||
*/
|
||||
- (NSURL *)url;
|
||||
-(NSURL*)url;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Events
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Appending Data To The Recorder
|
||||
/// @name Appending Data To The Audio File
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -347,18 +108,16 @@ typedef NS_ENUM(NSInteger, EZRecorderFileType)
|
||||
@param bufferList The AudioBufferList holding the audio data to append
|
||||
@param bufferSize The size of each of the buffers in the buffer list.
|
||||
*/
|
||||
- (void)appendDataFromBufferList:(AudioBufferList *)bufferList
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
-(void)appendDataFromBufferList:(AudioBufferList*)bufferList
|
||||
withBufferSize:(UInt32)bufferSize;
|
||||
|
||||
///-----------------------------------------------------------
|
||||
/// @name Closing The Recorder
|
||||
/// @name Closing The Audio File
|
||||
///-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
Finishes writes to the recorder's audio file and closes it.
|
||||
Finishes writes to the audio file and closes it.
|
||||
*/
|
||||
- (void)closeAudioFile;
|
||||
-(void)closeAudioFile;
|
||||
|
||||
@end
|
||||
@@ -3,7 +3,7 @@
|
||||
// EZAudio
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Copyright (c) 2015 Syed Haris Ali. All rights reserved.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,210 +26,65 @@
|
||||
#import "EZRecorder.h"
|
||||
#import "EZAudioUtilities.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Data Structures
|
||||
//------------------------------------------------------------------------------
|
||||
@interface EZRecorder (){
|
||||
ExtAudioFileRef _destinationFile;
|
||||
AudioFileTypeID _destinationFileTypeID;
|
||||
CFURLRef _destinationFileURL;
|
||||
AudioStreamBasicDescription _destinationFormat;
|
||||
AudioStreamBasicDescription _sourceFormat;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AudioFileTypeID audioFileTypeID;
|
||||
ExtAudioFileRef extAudioFileRef;
|
||||
AudioStreamBasicDescription clientFormat;
|
||||
BOOL closed;
|
||||
CFURLRef fileURL;
|
||||
AudioStreamBasicDescription fileFormat;
|
||||
} EZRecorderInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZRecorder (Interface Extension)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@interface EZRecorder ()
|
||||
@property (nonatomic, assign) EZRecorderInfo *info;
|
||||
@end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZRecorder (Implementation)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@implementation EZRecorder
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Dealloc
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (!self.info->closed)
|
||||
{
|
||||
[self closeAudioFile];
|
||||
}
|
||||
free(self.info);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
-(EZRecorder*)initWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType
|
||||
{
|
||||
return [self initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileType:fileType
|
||||
delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
delegate:(id<EZRecorderDelegate>)delegate
|
||||
{
|
||||
AudioStreamBasicDescription fileFormat = [EZRecorder formatForFileType:fileType
|
||||
withSourceFormat:clientFormat];
|
||||
AudioFileTypeID audioFileTypeID = [EZRecorder fileTypeIdForFileType:fileType
|
||||
withSourceFormat:clientFormat];
|
||||
return [self initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileFormat:fileFormat
|
||||
audioFileTypeID:audioFileTypeID
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
{
|
||||
return [self initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileFormat:fileFormat
|
||||
audioFileTypeID:audioFileTypeID
|
||||
delegate:nil];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
delegate:(id<EZRecorderDelegate>)delegate
|
||||
{
|
||||
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
// Set defaults
|
||||
self.info = (EZRecorderInfo *)calloc(1, sizeof(EZRecorderInfo));
|
||||
self.info->audioFileTypeID = audioFileTypeID;
|
||||
self.info->fileURL = (__bridge CFURLRef)url;
|
||||
self.info->clientFormat = clientFormat;
|
||||
self.info->fileFormat = fileFormat;
|
||||
self.delegate = delegate;
|
||||
[self setup];
|
||||
_destinationFile = NULL;
|
||||
_destinationFileURL = (__bridge CFURLRef)url;
|
||||
_sourceFormat = sourceFormat;
|
||||
_destinationFormat = [EZRecorder recorderFormatForFileType:destinationFileType
|
||||
withSourceFormat:_sourceFormat];
|
||||
_destinationFileTypeID = [EZRecorder recorderFileTypeIdForFileType:destinationFileType
|
||||
withSourceFormat:_sourceFormat];
|
||||
|
||||
// Initializer the recorder instance
|
||||
[self _initializeRecorder];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (instancetype)initWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType
|
||||
{
|
||||
return [self initWithURL:url
|
||||
clientFormat:sourceFormat
|
||||
fileType:destinationFileType];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Initializers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
{
|
||||
return [[self alloc] initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileType:fileType];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileType:(EZRecorderFileType)fileType
|
||||
delegate:(id<EZRecorderDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileType:fileType
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
{
|
||||
return [[self alloc] initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileFormat:fileFormat
|
||||
audioFileTypeID:audioFileTypeID];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithURL:(NSURL *)url
|
||||
clientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
fileFormat:(AudioStreamBasicDescription)fileFormat
|
||||
audioFileTypeID:(AudioFileTypeID)audioFileTypeID
|
||||
delegate:(id<EZRecorderDelegate>)delegate
|
||||
{
|
||||
return [[self alloc] initWithURL:url
|
||||
clientFormat:clientFormat
|
||||
fileFormat:fileFormat
|
||||
audioFileTypeID:audioFileTypeID
|
||||
delegate:delegate];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (instancetype)recorderWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType
|
||||
+(EZRecorder*)recorderWithDestinationURL:(NSURL*)url
|
||||
sourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
destinationFileType:(EZRecorderFileType)destinationFileType
|
||||
{
|
||||
return [[EZRecorder alloc] initWithDestinationURL:url
|
||||
sourceFormat:sourceFormat
|
||||
destinationFileType:destinationFileType];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Class Methods
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (AudioStreamBasicDescription)formatForFileType:(EZRecorderFileType)fileType
|
||||
withSourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
#pragma mark - Private Configuration
|
||||
+(AudioStreamBasicDescription)recorderFormatForFileType:(EZRecorderFileType)fileType
|
||||
withSourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
{
|
||||
AudioStreamBasicDescription asbd;
|
||||
switch (fileType)
|
||||
switch ( fileType)
|
||||
{
|
||||
case EZRecorderFileTypeAIFF:
|
||||
asbd = [EZAudioUtilities AIFFFormatWithNumberOfChannels:sourceFormat.mChannelsPerFrame
|
||||
sampleRate:sourceFormat.mSampleRate];
|
||||
sampleRate:sourceFormat.mSampleRate];
|
||||
break;
|
||||
case EZRecorderFileTypeM4A:
|
||||
asbd = [EZAudioUtilities M4AFormatWithNumberOfChannels:sourceFormat.mChannelsPerFrame
|
||||
sampleRate:sourceFormat.mSampleRate];
|
||||
sampleRate:sourceFormat.mSampleRate];
|
||||
break;
|
||||
|
||||
case EZRecorderFileTypeWAV:
|
||||
@@ -243,13 +98,11 @@ typedef struct
|
||||
return asbd;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
+ (AudioFileTypeID)fileTypeIdForFileType:(EZRecorderFileType)fileType
|
||||
withSourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
+(AudioFileTypeID)recorderFileTypeIdForFileType:(EZRecorderFileType)fileType
|
||||
withSourceFormat:(AudioStreamBasicDescription)sourceFormat
|
||||
{
|
||||
AudioFileTypeID audioFileTypeID;
|
||||
switch (fileType)
|
||||
switch ( fileType)
|
||||
{
|
||||
case EZRecorderFileTypeAIFF:
|
||||
audioFileTypeID = kAudioFileAIFFType;
|
||||
@@ -270,187 +123,70 @@ typedef struct
|
||||
return audioFileTypeID;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setup
|
||||
-(void)_initializeRecorder
|
||||
{
|
||||
// Finish filling out the destination format description
|
||||
UInt32 propSize = sizeof(self.info->fileFormat);
|
||||
UInt32 propSize = sizeof(_destinationFormat);
|
||||
[EZAudioUtilities checkResult:AudioFormatGetProperty(kAudioFormatProperty_FormatInfo,
|
||||
0,
|
||||
NULL,
|
||||
&propSize,
|
||||
&self.info->fileFormat)
|
||||
operation:"Failed to fill out rest of destination format"];
|
||||
0,
|
||||
NULL,
|
||||
&propSize,
|
||||
&_destinationFormat)
|
||||
operation:"Failed to fill out rest of destination format"];
|
||||
|
||||
//
|
||||
// Create the audio file
|
||||
//
|
||||
[EZAudioUtilities checkResult:ExtAudioFileCreateWithURL(self.info->fileURL,
|
||||
self.info->audioFileTypeID,
|
||||
&self.info->fileFormat,
|
||||
NULL,
|
||||
kAudioFileFlags_EraseFile,
|
||||
&self.info->extAudioFileRef)
|
||||
operation:"Failed to create audio file"];
|
||||
[EZAudioUtilities checkResult:ExtAudioFileCreateWithURL(_destinationFileURL,
|
||||
_destinationFileTypeID,
|
||||
&_destinationFormat,
|
||||
NULL,
|
||||
kAudioFileFlags_EraseFile,
|
||||
&_destinationFile)
|
||||
operation:"Failed to create audio file"];
|
||||
|
||||
// Set the client format (which should be equal to the source format)
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSetProperty(_destinationFile,
|
||||
kExtAudioFileProperty_ClientDataFormat,
|
||||
sizeof(_sourceFormat),
|
||||
&_sourceFormat)
|
||||
operation:"Failed to set client format on recorded audio file"];
|
||||
|
||||
//
|
||||
// Set the client format
|
||||
//
|
||||
[self setClientFormat:self.info->clientFormat];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Events
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)appendDataFromBufferList:(AudioBufferList *)bufferList
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
-(void)appendDataFromBufferList:(AudioBufferList *)bufferList
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
{
|
||||
//
|
||||
// Make sure the audio file is not closed
|
||||
//
|
||||
NSAssert(!self.info->closed, @"Cannot append data when EZRecorder has been closed. You must create a new instance.;");
|
||||
|
||||
//
|
||||
// Perform the write
|
||||
//
|
||||
[EZAudioUtilities checkResult:ExtAudioFileWrite(self.info->extAudioFileRef,
|
||||
if (_destinationFile)
|
||||
{
|
||||
[EZAudioUtilities checkResult:ExtAudioFileWriteAsync(_destinationFile,
|
||||
bufferSize,
|
||||
bufferList)
|
||||
operation:"Failed to write audio data to recorded audio file"];
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(recorderUpdatedCurrentTime:)])
|
||||
{
|
||||
[self.delegate recorderUpdatedCurrentTime:self];
|
||||
operation:"Failed to write audio data to recorded audio file"];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)closeAudioFile
|
||||
-(void)closeAudioFile
|
||||
{
|
||||
if (!self.info->closed)
|
||||
if (_destinationFile)
|
||||
{
|
||||
//
|
||||
// Close, audio file can no longer be written to
|
||||
//
|
||||
[EZAudioUtilities checkResult:ExtAudioFileDispose(self.info->extAudioFileRef)
|
||||
operation:"Failed to close audio file"];
|
||||
self.info->closed = YES;
|
||||
// Dispose of the audio file reference
|
||||
[EZAudioUtilities checkResult:ExtAudioFileDispose(_destinationFile)
|
||||
operation:"Failed to close audio file"];
|
||||
|
||||
//
|
||||
// Notify delegate
|
||||
//
|
||||
if ([self.delegate respondsToSelector:@selector(recorderDidClose:)])
|
||||
{
|
||||
[self.delegate recorderDidClose:self];
|
||||
}
|
||||
// Null out the file reference
|
||||
_destinationFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Getters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (AudioStreamBasicDescription)clientFormat
|
||||
-(NSURL *)url
|
||||
{
|
||||
return self.info->clientFormat;
|
||||
return (__bridge NSURL*)_destinationFileURL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)currentTime
|
||||
#pragma mark - Dealloc
|
||||
-(void)dealloc
|
||||
{
|
||||
NSTimeInterval currentTime = 0.0;
|
||||
NSTimeInterval duration = [self duration];
|
||||
if (duration != 0.0)
|
||||
{
|
||||
currentTime = (NSTimeInterval)[EZAudioUtilities MAP:(float)[self frameIndex]
|
||||
leftMin:0.0f
|
||||
leftMax:(float)[self totalFrames]
|
||||
rightMin:0.0f
|
||||
rightMax:duration];
|
||||
}
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSTimeInterval)duration
|
||||
{
|
||||
NSTimeInterval frames = (NSTimeInterval)[self totalFrames];
|
||||
return (NSTimeInterval) frames / self.info->fileFormat.mSampleRate;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (AudioStreamBasicDescription)fileFormat
|
||||
{
|
||||
return self.info->fileFormat;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedCurrentTime
|
||||
{
|
||||
return [EZAudioUtilities displayTimeStringFromSeconds:[self currentTime]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSString *)formattedDuration
|
||||
{
|
||||
return [EZAudioUtilities displayTimeStringFromSeconds:[self duration]];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)frameIndex
|
||||
{
|
||||
SInt64 frameIndex;
|
||||
[EZAudioUtilities checkResult:ExtAudioFileTell(self.info->extAudioFileRef,
|
||||
&frameIndex)
|
||||
operation:"Failed to get frame index"];
|
||||
return frameIndex;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (SInt64)totalFrames
|
||||
{
|
||||
SInt64 totalFrames;
|
||||
UInt32 propSize = sizeof(SInt64);
|
||||
[EZAudioUtilities checkResult:ExtAudioFileGetProperty(self.info->extAudioFileRef,
|
||||
kExtAudioFileProperty_FileLengthFrames,
|
||||
&propSize,
|
||||
&totalFrames)
|
||||
operation:"Recorder failed to get total frames."];
|
||||
return totalFrames;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (NSURL *)url
|
||||
{
|
||||
return (__bridge NSURL*)self.info->fileURL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Setters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setClientFormat:(AudioStreamBasicDescription)clientFormat
|
||||
{
|
||||
[EZAudioUtilities checkResult:ExtAudioFileSetProperty(self.info->extAudioFileRef,
|
||||
kExtAudioFileProperty_ClientDataFormat,
|
||||
sizeof(clientFormat),
|
||||
&clientFormat)
|
||||
operation:"Failed to set client format on recorded audio file"];
|
||||
self.info->clientFormat = clientFormat;
|
||||
[self closeAudioFile];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -30,29 +30,21 @@
|
||||
#include "TPCircularBuffer.h"
|
||||
#include <mach/mach.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define reportResult(result,operation) (_reportResult((result),(operation),strrchr(__FILE__, '/')+1,__LINE__))
|
||||
static inline bool _reportResult(kern_return_t result, const char *operation, const char* file, int line) {
|
||||
if ( result != ERR_SUCCESS ) {
|
||||
if (result != ERR_SUCCESS) {
|
||||
printf("%s:%d: %s: %s\n", file, line, operation, mach_error_string(result));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t structSize) {
|
||||
|
||||
assert(length > 0);
|
||||
|
||||
if ( structSize != sizeof(TPCircularBuffer) ) {
|
||||
fprintf(stderr, "TPCircularBuffer: Header version mismatch. Check for old versions of TPCircularBuffer in your project\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
bool TPCircularBufferInit(TPCircularBuffer *buffer, int length) {
|
||||
|
||||
// Keep trying until we get our buffer, needed to handle race conditions
|
||||
int retries = 3;
|
||||
while ( true ) {
|
||||
while ( true) {
|
||||
|
||||
buffer->length = (int32_t)round_page(length); // We need whole page sizes
|
||||
|
||||
@@ -63,8 +55,8 @@ bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t stru
|
||||
&bufferAddress,
|
||||
buffer->length * 2,
|
||||
VM_FLAGS_ANYWHERE); // allocate anywhere it'll fit
|
||||
if ( result != ERR_SUCCESS ) {
|
||||
if ( retries-- == 0 ) {
|
||||
if (result != ERR_SUCCESS) {
|
||||
if (retries-- == 0) {
|
||||
reportResult(result, "Buffer allocation");
|
||||
return false;
|
||||
}
|
||||
@@ -76,8 +68,8 @@ bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t stru
|
||||
result = vm_deallocate(mach_task_self(),
|
||||
bufferAddress + buffer->length,
|
||||
buffer->length);
|
||||
if ( result != ERR_SUCCESS ) {
|
||||
if ( retries-- == 0 ) {
|
||||
if (result != ERR_SUCCESS) {
|
||||
if (retries-- == 0) {
|
||||
reportResult(result, "Buffer deallocation");
|
||||
return false;
|
||||
}
|
||||
@@ -100,8 +92,8 @@ bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t stru
|
||||
&cur_prot, // unused protection struct
|
||||
&max_prot, // unused protection struct
|
||||
VM_INHERIT_DEFAULT);
|
||||
if ( result != ERR_SUCCESS ) {
|
||||
if ( retries-- == 0 ) {
|
||||
if (result != ERR_SUCCESS) {
|
||||
if (retries-- == 0) {
|
||||
reportResult(result, "Remap buffer memory");
|
||||
return false;
|
||||
}
|
||||
@@ -110,9 +102,9 @@ bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t stru
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( virtualAddress != bufferAddress+buffer->length ) {
|
||||
if (virtualAddress != bufferAddress+buffer->length) {
|
||||
// If the memory is not contiguous, clean up both allocated buffers and try again
|
||||
if ( retries-- == 0 ) {
|
||||
if (retries-- == 0) {
|
||||
printf("Couldn't map buffer memory to end of buffer\n");
|
||||
return false;
|
||||
}
|
||||
@@ -125,7 +117,6 @@ bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t stru
|
||||
buffer->buffer = (void*)bufferAddress;
|
||||
buffer->fillCount = 0;
|
||||
buffer->head = buffer->tail = 0;
|
||||
buffer->atomic = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -139,11 +130,7 @@ void TPCircularBufferCleanup(TPCircularBuffer *buffer) {
|
||||
|
||||
void TPCircularBufferClear(TPCircularBuffer *buffer) {
|
||||
int32_t fillCount;
|
||||
if ( TPCircularBufferTail(buffer, &fillCount) ) {
|
||||
if (TPCircularBufferTail(buffer, &fillCount)) {
|
||||
TPCircularBufferConsume(buffer, fillCount);
|
||||
}
|
||||
}
|
||||
|
||||
void TPCircularBufferSetAtomic(TPCircularBuffer *buffer, bool atomic) {
|
||||
buffer->atomic = atomic;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ typedef struct {
|
||||
int32_t tail;
|
||||
int32_t head;
|
||||
volatile int32_t fillCount;
|
||||
bool atomic;
|
||||
} TPCircularBuffer;
|
||||
|
||||
/*!
|
||||
@@ -69,9 +68,7 @@ typedef struct {
|
||||
* @param buffer Circular buffer
|
||||
* @param length Length of buffer
|
||||
*/
|
||||
#define TPCircularBufferInit(buffer, length) \
|
||||
_TPCircularBufferInit(buffer, length, sizeof(*buffer))
|
||||
bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t structSize);
|
||||
bool TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length);
|
||||
|
||||
/*!
|
||||
* Cleanup buffer
|
||||
@@ -89,22 +86,6 @@ void TPCircularBufferCleanup(TPCircularBuffer *buffer);
|
||||
* buffer.
|
||||
*/
|
||||
void TPCircularBufferClear(TPCircularBuffer *buffer);
|
||||
|
||||
/*!
|
||||
* Set the atomicity
|
||||
*
|
||||
* If you set the atomiticy to false using this method, the buffer will
|
||||
* not use atomic operations. This can be used to give the compiler a little
|
||||
* more optimisation opportunities when the buffer is only used on one thread.
|
||||
*
|
||||
* Important note: Only set this to false if you know what you're doing!
|
||||
*
|
||||
* The default value is true (the buffer will use atomic operations)
|
||||
*
|
||||
* @param buffer Circular buffer
|
||||
* @param atomic Whether the buffer is atomic (default true)
|
||||
*/
|
||||
void TPCircularBufferSetAtomic(TPCircularBuffer *buffer, bool atomic);
|
||||
|
||||
// Reading (consuming)
|
||||
|
||||
@@ -120,7 +101,7 @@ void TPCircularBufferSetAtomic(TPCircularBuffer *buffer, bool atomic);
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) void* TPCircularBufferTail(TPCircularBuffer *buffer, int32_t* availableBytes) {
|
||||
*availableBytes = buffer->fillCount;
|
||||
if ( *availableBytes == 0 ) return NULL;
|
||||
if (*availableBytes == 0) return NULL;
|
||||
return (void*)((char*)buffer->buffer + buffer->tail);
|
||||
}
|
||||
|
||||
@@ -134,11 +115,16 @@ static __inline__ __attribute__((always_inline)) void* TPCircularBufferTail(TPCi
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) void TPCircularBufferConsume(TPCircularBuffer *buffer, int32_t amount) {
|
||||
buffer->tail = (buffer->tail + amount) % buffer->length;
|
||||
if ( buffer->atomic ) {
|
||||
OSAtomicAdd32Barrier(-amount, &buffer->fillCount);
|
||||
} else {
|
||||
buffer->fillCount -= amount;
|
||||
}
|
||||
OSAtomicAdd32Barrier(-amount, &buffer->fillCount);
|
||||
assert(buffer->fillCount >= 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Version of TPCircularBufferConsume without the memory barrier, for more optimal use in single-threaded contexts
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) void TPCircularBufferConsumeNoBarrier(TPCircularBuffer *buffer, int32_t amount) {
|
||||
buffer->tail = (buffer->tail + amount) % buffer->length;
|
||||
buffer->fillCount -= amount;
|
||||
assert(buffer->fillCount >= 0);
|
||||
}
|
||||
|
||||
@@ -154,7 +140,7 @@ static __inline__ __attribute__((always_inline)) void TPCircularBufferConsume(TP
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) void* TPCircularBufferHead(TPCircularBuffer *buffer, int32_t* availableBytes) {
|
||||
*availableBytes = (buffer->length - buffer->fillCount);
|
||||
if ( *availableBytes == 0 ) return NULL;
|
||||
if (*availableBytes == 0) return NULL;
|
||||
return (void*)((char*)buffer->buffer + buffer->head);
|
||||
}
|
||||
|
||||
@@ -168,20 +154,25 @@ static __inline__ __attribute__((always_inline)) void* TPCircularBufferHead(TPCi
|
||||
* @param buffer Circular buffer
|
||||
* @param amount Number of bytes to produce
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) void TPCircularBufferProduce(TPCircularBuffer *buffer, int32_t amount) {
|
||||
static __inline__ __attribute__((always_inline)) void TPCircularBufferProduce(TPCircularBuffer *buffer, int amount) {
|
||||
buffer->head = (buffer->head + amount) % buffer->length;
|
||||
if ( buffer->atomic ) {
|
||||
OSAtomicAdd32Barrier(amount, &buffer->fillCount);
|
||||
} else {
|
||||
buffer->fillCount += amount;
|
||||
}
|
||||
OSAtomicAdd32Barrier(amount, &buffer->fillCount);
|
||||
assert(buffer->fillCount <= buffer->length);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Version of TPCircularBufferProduce without the memory barrier, for more optimal use in single-threaded contexts
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) void TPCircularBufferProduceNoBarrier(TPCircularBuffer *buffer, int amount) {
|
||||
buffer->head = (buffer->head + amount) % buffer->length;
|
||||
buffer->fillCount += amount;
|
||||
assert(buffer->fillCount <= buffer->length);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Helper routine to copy bytes to buffer
|
||||
*
|
||||
* This copies the given bytes to the buffer, and marks them ready for reading.
|
||||
* This copies the given bytes to the buffer, and marks them ready for writing.
|
||||
*
|
||||
* @param buffer Circular buffer
|
||||
* @param src Source buffer
|
||||
@@ -191,32 +182,12 @@ static __inline__ __attribute__((always_inline)) void TPCircularBufferProduce(TP
|
||||
static __inline__ __attribute__((always_inline)) bool TPCircularBufferProduceBytes(TPCircularBuffer *buffer, const void* src, int32_t len) {
|
||||
int32_t space;
|
||||
void *ptr = TPCircularBufferHead(buffer, &space);
|
||||
if ( space < len ) return false;
|
||||
if (space < len) return false;
|
||||
memcpy(ptr, src, len);
|
||||
TPCircularBufferProduce(buffer, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Deprecated method
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) __deprecated_msg("use TPCircularBufferSetAtomic(false) and TPCircularBufferConsume instead")
|
||||
void TPCircularBufferConsumeNoBarrier(TPCircularBuffer *buffer, int32_t amount) {
|
||||
buffer->tail = (buffer->tail + amount) % buffer->length;
|
||||
buffer->fillCount -= amount;
|
||||
assert(buffer->fillCount >= 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Deprecated method
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) __deprecated_msg("use TPCircularBufferSetAtomic(false) and TPCircularBufferProduce instead")
|
||||
void TPCircularBufferProduceNoBarrier(TPCircularBuffer *buffer, int32_t amount) {
|
||||
buffer->head = (buffer->head + amount) % buffer->length;
|
||||
buffer->fillCount += amount;
|
||||
assert(buffer->fillCount <= buffer->length);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
EZAudio
|
||||
|
||||
Created by Syed Haris Ali
|
||||
Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
==========================================================================================
|
||||
|
||||
0.0.1
|
||||
Initial release.
|
||||
Components include: EZAudioFile, EZAudioPlot, EZAudioPlotGL, EZMicrophone, EZOutput, and EZRecorder.
|
||||
Provided 6 example projects: CoreGraphicsWaveform, OpenGLWaveform, WaveformFromFile, PassThrough, Record, and PlayFile.
|
||||
|
||||
0.0.2
|
||||
Fix for Cocoapod spec. Forgot to include files with .c extension.
|
||||
|
||||
0.0.3
|
||||
Changing EZAudioPlot and EZAudioPlotGL to scroll for the EZPlotTypeRolling instead of wiping the screen clean when hitting the end
|
||||
Allowed EZMicrophone EZOutput to have custom AudioStreamBasicDescription setters
|
||||
Fixed bug in EZAudioFile's getWaveformData function where it was not exiting after sending back cached waveform data (rereading from the audio file)
|
||||
Added stereo support for EZMicrophone, EZAudioFile, EZRecorder, and EZOutput
|
||||
Added more memory cleanup for EZAudioFile
|
||||
Added adjustable rolling length for EZAudioPlot and EZAudioPlotGL so those rolling graphs can now range from 128 to 8192 whereas before it was fixed at 1024
|
||||
Added adjustable resolution for waveform data coming from the EZAudioFile so output from the getWaveformDataWithCompletionBlock: function can literally be of any size. Try 128 for a low resolution waveform or 8192 for a much higher resolution waveform.
|
||||
Added quick fix for EZOutput to properly route stereo data coming from a circular buffer datasource. Next version (0.0.4) needs to add EZConverter to allow quick conversions between non-interleaved and interleaved formats.
|
||||
|
||||
0.0.4
|
||||
Added ‘closeAudioFile’ to EZRecorder to properly dispose of internal audio file prior to trying to reload it using the EZAudioFile.
|
||||
Added new EZOutputDataSource method that provides pre-allocated AudioBufferList to fill instead of caller allocating and disposing on AudioBufferList. Much less errors.
|
||||
Added EZAudioPlayer for playback and visualization of local audio files (no network streaming yet).
|
||||
Merged bug fixes from community for EZAudio file.
|
||||
|
||||
0.0.5
|
||||
Added multiple destination recording formats to the EZRecorder (EZRecorderFileType)
|
||||
@@ -0,0 +1,26 @@
|
||||
EZAudio
|
||||
|
||||
Created by Syed Haris Ali
|
||||
Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
==========================================================================================
|
||||
|
||||
0.0.5
|
||||
@@ -1,356 +0,0 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
666062361C5421A400FB99FA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 666062351C5421A400FB99FA /* AppDelegate.m */; };
|
||||
666062391C5421A400FB99FA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 666062381C5421A400FB99FA /* main.m */; };
|
||||
6660623B1C5421A400FB99FA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6660623A1C5421A400FB99FA /* Assets.xcassets */; };
|
||||
6660623E1C5421A400FB99FA /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6660623C1C5421A400FB99FA /* MainMenu.xib */; };
|
||||
6660624B1C54242100FB99FA /* EZAudioOSX.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6660624A1C54242100FB99FA /* EZAudioOSX.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
66374DC41C54530A000B19D0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 66374DBF1C54530A000B19D0 /* EZAudio.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 469F4CF31B749F7800666A46;
|
||||
remoteInfo = EZAudioiOS;
|
||||
};
|
||||
66374DC61C54530A000B19D0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 66374DBF1C54530A000B19D0 /* EZAudio.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 8A5A4B9C1BBBDCB200A8A048;
|
||||
remoteInfo = EZAudioOSX;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
66374DBF1C54530A000B19D0 /* EZAudio.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = EZAudio.xcodeproj; path = ../../../EZAudio.xcodeproj; sourceTree = "<group>"; };
|
||||
666062311C5421A400FB99FA /* CoreGraphicsWaveform.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CoreGraphicsWaveform.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
666062341C5421A400FB99FA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
666062351C5421A400FB99FA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
666062381C5421A400FB99FA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
6660623A1C5421A400FB99FA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
6660623D1C5421A400FB99FA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
6660623F1C5421A400FB99FA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
6660624A1C54242100FB99FA /* EZAudioOSX.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EZAudioOSX.framework; path = ../../../build/Debug/EZAudioOSX.framework; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
6660622E1C5421A400FB99FA /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6660624B1C54242100FB99FA /* EZAudioOSX.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
66374DC01C54530A000B19D0 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
66374DC51C54530A000B19D0 /* EZAudioiOS.framework */,
|
||||
66374DC71C54530A000B19D0 /* EZAudioOSX.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
666062281C5421A400FB99FA = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
66374DBF1C54530A000B19D0 /* EZAudio.xcodeproj */,
|
||||
666062331C5421A400FB99FA /* CoreGraphicsWaveform */,
|
||||
6660624C1C54244900FB99FA /* Frameworks */,
|
||||
666062321C5421A400FB99FA /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
666062321C5421A400FB99FA /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
666062311C5421A400FB99FA /* CoreGraphicsWaveform.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
666062331C5421A400FB99FA /* CoreGraphicsWaveform */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
666062341C5421A400FB99FA /* AppDelegate.h */,
|
||||
666062351C5421A400FB99FA /* AppDelegate.m */,
|
||||
6660623A1C5421A400FB99FA /* Assets.xcassets */,
|
||||
6660623C1C5421A400FB99FA /* MainMenu.xib */,
|
||||
6660623F1C5421A400FB99FA /* Info.plist */,
|
||||
666062371C5421A400FB99FA /* Supporting Files */,
|
||||
);
|
||||
path = CoreGraphicsWaveform;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
666062371C5421A400FB99FA /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
666062381C5421A400FB99FA /* main.m */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6660624C1C54244900FB99FA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6660624A1C54242100FB99FA /* EZAudioOSX.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
666062301C5421A400FB99FA /* CoreGraphicsWaveform */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 666062421C5421A400FB99FA /* Build configuration list for PBXNativeTarget "CoreGraphicsWaveform" */;
|
||||
buildPhases = (
|
||||
6660622D1C5421A400FB99FA /* Sources */,
|
||||
6660622E1C5421A400FB99FA /* Frameworks */,
|
||||
6660622F1C5421A400FB99FA /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = CoreGraphicsWaveform;
|
||||
productName = CoreGraphicsWaveform;
|
||||
productReference = 666062311C5421A400FB99FA /* CoreGraphicsWaveform.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
666062291C5421A400FB99FA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0720;
|
||||
ORGANIZATIONNAME = "Syed Haris Ali";
|
||||
TargetAttributes = {
|
||||
666062301C5421A400FB99FA = {
|
||||
CreatedOnToolsVersion = 7.2;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 6660622C1C5421A400FB99FA /* Build configuration list for PBXProject "CoreGraphicsWaveform" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 666062281C5421A400FB99FA;
|
||||
productRefGroup = 666062321C5421A400FB99FA /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 66374DC01C54530A000B19D0 /* Products */;
|
||||
ProjectRef = 66374DBF1C54530A000B19D0 /* EZAudio.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
666062301C5421A400FB99FA /* CoreGraphicsWaveform */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
66374DC51C54530A000B19D0 /* EZAudioiOS.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
path = EZAudioiOS.framework;
|
||||
remoteRef = 66374DC41C54530A000B19D0 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
66374DC71C54530A000B19D0 /* EZAudioOSX.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
path = EZAudioOSX.framework;
|
||||
remoteRef = 66374DC61C54530A000B19D0 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
6660622F1C5421A400FB99FA /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6660623B1C5421A400FB99FA /* Assets.xcassets in Resources */,
|
||||
6660623E1C5421A400FB99FA /* MainMenu.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
6660622D1C5421A400FB99FA /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
666062391C5421A400FB99FA /* main.m in Sources */,
|
||||
666062361C5421A400FB99FA /* AppDelegate.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
6660623C1C5421A400FB99FA /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
6660623D1C5421A400FB99FA /* Base */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
666062401C5421A400FB99FA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
666062411C5421A400FB99FA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
666062431C5421A400FB99FA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../..\"";
|
||||
INFOPLIST_FILE = CoreGraphicsWaveform/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.sha.CoreGraphicsWaveform;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
666062441C5421A400FB99FA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../..\"";
|
||||
INFOPLIST_FILE = CoreGraphicsWaveform/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.sha.CoreGraphicsWaveform;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
6660622C1C5421A400FB99FA /* Build configuration list for PBXProject "CoreGraphicsWaveform" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
666062401C5421A400FB99FA /* Debug */,
|
||||
666062411C5421A400FB99FA /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
666062421C5421A400FB99FA /* Build configuration list for PBXNativeTarget "CoreGraphicsWaveform" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
666062431C5421A400FB99FA /* Debug */,
|
||||
666062441C5421A400FB99FA /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 666062291C5421A400FB99FA /* Project object */;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 400 B |
|
Before Width: | Height: | Size: 821 B |
|
Before Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 821 B |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 42 KiB |
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -1,790 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="audioPlot" destination="UKU-Zt-VNI" id="VZE-Q5-pWX"/>
|
||||
<outlet property="microphoneInputChannelPopUpButton" destination="eQn-G8-sEy" id="t6L-MA-Ir9"/>
|
||||
<outlet property="microphoneInputPopUpButton" destination="iw4-UD-y2x" id="u5y-KI-fWu"/>
|
||||
<outlet property="microphoneSwitch" destination="OcB-2r-09B" id="S6J-CM-twc"/>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<items>
|
||||
<menuItem title="CoreGraphicsWaveform" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="CoreGraphicsWaveform" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<items>
|
||||
<menuItem title="About CoreGraphicsWaveform" id="5kV-Vb-QxS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||
<menuItem title="Services" id="NMo-om-nkz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||
<menuItem title="Hide CoreGraphicsWaveform" keyEquivalent="h" id="Olw-nP-bQN">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||
<menuItem title="Quit CoreGraphicsWaveform" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="dMs-cI-mzQ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="File" id="bib-Uj-vzu">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="tXI-mr-wws">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="vNY-rz-j42">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
|
||||
<connections>
|
||||
<action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="KaW-ft-85H">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
|
||||
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
|
||||
<connections>
|
||||
<action selector="print:" target="-1" id="qaZ-4w-aoO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="5QF-Oa-p0T">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="M6e-cu-g7V"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="YJe-68-I9s"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="G1f-GL-Joy"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="pa3-QI-u2k">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
|
||||
<menuItem title="Find" id="4EN-yA-p0u">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Find" id="1b7-l0-nxx">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
|
||||
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="9ic-FL-obx">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
|
||||
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" id="cwL-P1-jid">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Data Detectors" id="tRr-pd-1PS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="2oI-Rn-ZJC">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="xrE-MZ-jX0">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="jxT-CU-nIS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
|
||||
<items>
|
||||
<menuItem title="Font" id="Gi5-1S-RQB">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="FYS-2b-JAY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
|
||||
<menuItem title="Kern" id="jBQ-r6-VK2">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="GUa-eO-cwY">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="cDB-IK-hbR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="46P-cB-AYj">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="ogc-rX-tC1">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="o6e-r0-MWq">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="agt-UL-0e3">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="J7y-lM-qPV">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="xQD-1f-W4t">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="OaQ-X3-Vso">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="3Om-Ey-2VK">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="Rqc-34-cIF">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="I0S-gh-46l">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="2h7-ER-AoG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="1tx-W0-xDw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="Fal-I4-PZk">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="d9c-me-L2H">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="J5U-5w-g23">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
|
||||
<menuItem title="Writing Direction" id="H1b-Si-o9J">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="YGs-j5-SAR">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="Lbh-J2-qVU">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="jFq-tB-4Kx">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
|
||||
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="Nop-cj-93Q">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="BgM-ve-c93">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="RB4-Sm-HuC">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
|
||||
<menuItem title="Show Ruler" id="vLm-3I-IUL">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="H8h-7b-M4v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="wpr-3q-Mcd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
|
||||
<items>
|
||||
<menuItem title="CoreGraphicsWaveform Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="CoreGraphicsWaveform" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="272"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="UKU-Zt-VNI" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<subviews>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="OcB-2r-09B">
|
||||
<rect key="frame" x="339" y="44" width="123" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="119" id="IYG-tU-wTC"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="check" title="Microphone On" bezelStyle="regularSquare" imagePosition="right" state="on" inset="2" id="nLI-9n-Lq4">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" target="Voe-Tx-rLC" id="owY-ee-pxT"/>
|
||||
</connections>
|
||||
</button>
|
||||
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vg4-nF-3aC">
|
||||
<rect key="frame" x="336" y="15" width="126" height="24"/>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="izG-Ud-yhj">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Buffer" selected="YES"/>
|
||||
<segment label="Rolling" tag="1"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="changePlotType:" target="Voe-Tx-rLC" id="tpI-pn-CXh"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iw4-UD-y2x" userLabel="microphoneInputPopUpButton">
|
||||
<rect key="frame" x="18" y="14" width="180" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="175" id="pXT-MN-bhv"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="NAH-si-Cz7" id="iUB-oI-R1w">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="qYP-H1-Bk6">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="NAH-si-Cz7"/>
|
||||
<menuItem title="Item 2" id="BXf-ml-R0L"/>
|
||||
<menuItem title="Item 3" id="K8l-2q-4fM"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eQn-G8-sEy" userLabel="microphoneInputChannelPopUpButton">
|
||||
<rect key="frame" x="204" y="14" width="79" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="74" id="YOF-2X-UV4"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="xFp-40-Dr9" id="BFV-5e-q9Y">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="iMm-fx-yJb">
|
||||
<items>
|
||||
<menuItem title="1" state="on" id="xFp-40-Dr9"/>
|
||||
<menuItem title="Item 2" id="h5D-tQ-aWj"/>
|
||||
<menuItem title="Item 3" id="KIX-gW-QNf"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hQY-oe-OzP">
|
||||
<rect key="frame" x="18" y="43" width="35" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Input" id="bY0-Zl-AT5">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ve4-EX-2la">
|
||||
<rect key="frame" x="204" y="43" width="54" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Channel" id="suO-Th-3jL">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="eQn-G8-sEy" secondAttribute="bottom" constant="17" id="3cy-PJ-m0Y"/>
|
||||
<constraint firstItem="vg4-nF-3aC" firstAttribute="top" secondItem="OcB-2r-09B" secondAttribute="bottom" constant="8" id="9k9-TY-Bjf"/>
|
||||
<constraint firstItem="vg4-nF-3aC" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="eQn-G8-sEy" secondAttribute="trailing" constant="11" id="M6I-rI-pcs"/>
|
||||
<constraint firstAttribute="bottom" secondItem="iw4-UD-y2x" secondAttribute="bottom" constant="17" id="NZe-J3-FGY"/>
|
||||
<constraint firstItem="eQn-G8-sEy" firstAttribute="leading" secondItem="ve4-EX-2la" secondAttribute="leading" id="URh-po-xQb"/>
|
||||
<constraint firstItem="iw4-UD-y2x" firstAttribute="leading" secondItem="UKU-Zt-VNI" secondAttribute="leading" constant="20" id="YeT-tO-rG3"/>
|
||||
<constraint firstAttribute="bottom" secondItem="vg4-nF-3aC" secondAttribute="bottom" constant="17" id="aid-He-3CY"/>
|
||||
<constraint firstAttribute="trailing" secondItem="OcB-2r-09B" secondAttribute="trailing" constant="20" id="ceh-Ub-H3g"/>
|
||||
<constraint firstItem="eQn-G8-sEy" firstAttribute="top" secondItem="ve4-EX-2la" secondAttribute="bottom" constant="5" id="enm-hh-fpR"/>
|
||||
<constraint firstAttribute="trailing" secondItem="vg4-nF-3aC" secondAttribute="trailing" constant="20" id="kkp-oh-PX1"/>
|
||||
<constraint firstItem="hQY-oe-OzP" firstAttribute="leading" secondItem="UKU-Zt-VNI" secondAttribute="leading" constant="20" id="ptg-v2-mao"/>
|
||||
<constraint firstItem="eQn-G8-sEy" firstAttribute="leading" secondItem="iw4-UD-y2x" secondAttribute="trailing" constant="11" id="waP-mh-dlK"/>
|
||||
<constraint firstItem="iw4-UD-y2x" firstAttribute="top" secondItem="hQY-oe-OzP" secondAttribute="bottom" constant="5" id="wzU-X6-aEB"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="UKU-Zt-VNI" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="AgR-SX-Oic"/>
|
||||
<constraint firstAttribute="bottom" secondItem="UKU-Zt-VNI" secondAttribute="bottom" id="XJr-UI-i7d"/>
|
||||
<constraint firstItem="UKU-Zt-VNI" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="gOP-bJ-FcC"/>
|
||||
<constraint firstAttribute="trailing" secondItem="UKU-Zt-VNI" secondAttribute="trailing" id="yV6-Vo-HHU"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<point key="canvasLocation" x="414" y="327"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,13 +0,0 @@
|
||||
//
|
||||
// main.m
|
||||
// CoreGraphicsWaveform
|
||||
//
|
||||
// Created by Syed Haris Ali on 1/23/16.
|
||||
// Copyright © 2016 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,690 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXAggregateTarget section */
|
||||
94F8DF4A18C84203005C4CBD /* Generate Documentation */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = 94F8DF4D18C84204005C4CBD /* Build configuration list for PBXAggregateTarget "Generate Documentation" */;
|
||||
buildPhases = (
|
||||
94F8DF4E18C8420C005C4CBD /* ShellScript */,
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "Generate Documentation";
|
||||
productName = "Generate Documentation";
|
||||
};
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
665956E81B38B256003E97A1 /* AEFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956C61B38B256003E97A1 /* AEFloatConverter.m */; };
|
||||
665956E91B38B256003E97A1 /* EZAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956C81B38B256003E97A1 /* EZAudio.m */; };
|
||||
665956EA1B38B256003E97A1 /* EZAudioDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956CA1B38B256003E97A1 /* EZAudioDevice.m */; };
|
||||
665956EB1B38B256003E97A1 /* EZAudioFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956CC1B38B256003E97A1 /* EZAudioFile.m */; };
|
||||
665956EC1B38B256003E97A1 /* EZAudioFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956CE1B38B256003E97A1 /* EZAudioFloatConverter.m */; };
|
||||
665956ED1B38B256003E97A1 /* EZAudioFloatData.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956D01B38B256003E97A1 /* EZAudioFloatData.m */; };
|
||||
665956EE1B38B256003E97A1 /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956D21B38B256003E97A1 /* EZAudioPlayer.m */; };
|
||||
665956EF1B38B256003E97A1 /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956D41B38B256003E97A1 /* EZAudioPlot.m */; };
|
||||
665956F01B38B256003E97A1 /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956D61B38B256003E97A1 /* EZAudioPlotGL.m */; };
|
||||
665956F11B38B256003E97A1 /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956D81B38B256003E97A1 /* EZAudioPlotGLKViewController.m */; };
|
||||
665956F21B38B256003E97A1 /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956DA1B38B256003E97A1 /* EZAudioUtilities.m */; };
|
||||
665956F31B38B256003E97A1 /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956DC1B38B256003E97A1 /* EZMicrophone.m */; };
|
||||
665956F41B38B256003E97A1 /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956DE1B38B256003E97A1 /* EZOutput.m */; };
|
||||
665956F51B38B256003E97A1 /* EZPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956E01B38B256003E97A1 /* EZPlot.m */; };
|
||||
665956F61B38B256003E97A1 /* EZRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 665956E21B38B256003E97A1 /* EZRecorder.m */; };
|
||||
665956F71B38B256003E97A1 /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 665956E31B38B256003E97A1 /* TPCircularBuffer.c */; };
|
||||
665956F81B38B256003E97A1 /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 665956E61B38B256003E97A1 /* CHANGELOG */; };
|
||||
665956F91B38B256003E97A1 /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 665956E71B38B256003E97A1 /* VERSION */; };
|
||||
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 */; };
|
||||
9437302F185B931C00F315F0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9437302D185B931C00F315F0 /* InfoPlist.strings */; };
|
||||
94373031185B931C00F315F0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 94373030185B931C00F315F0 /* main.m */; };
|
||||
94373035185B931C00F315F0 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 94373033185B931C00F315F0 /* Credits.rtf */; };
|
||||
94373038185B931C00F315F0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 94373037185B931C00F315F0 /* AppDelegate.m */; };
|
||||
9437303B185B931C00F315F0 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 94373039185B931C00F315F0 /* MainMenu.xib */; };
|
||||
9437303D185B931C00F315F0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9437303C185B931C00F315F0 /* Images.xcassets */; };
|
||||
94373044185B931C00F315F0 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94373043185B931C00F315F0 /* XCTest.framework */; };
|
||||
94373045185B931C00F315F0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94373024185B931C00F315F0 /* Cocoa.framework */; };
|
||||
9437304D185B931C00F315F0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9437304B185B931C00F315F0 /* InfoPlist.strings */; };
|
||||
9437304F185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9437304E185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests.m */; };
|
||||
94373080185B934900F315F0 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9437307D185B934900F315F0 /* AudioToolbox.framework */; };
|
||||
94373081185B934900F315F0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9437307E185B934900F315F0 /* AudioUnit.framework */; };
|
||||
94373082185B934900F315F0 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9437307F185B934900F315F0 /* CoreAudio.framework */; };
|
||||
94373084185B936B00F315F0 /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94373083185B936B00F315F0 /* GLKit.framework */; };
|
||||
94373086185B937100F315F0 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94373085185B937100F315F0 /* OpenGL.framework */; };
|
||||
94373088185B937E00F315F0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94373087185B937E00F315F0 /* QuartzCore.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
94373046185B931C00F315F0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 94373019185B931C00F315F0 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 94373020185B931C00F315F0;
|
||||
remoteInfo = EZAudioCoreGraphicsWaveformExample;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
665956C51B38B256003E97A1 /* AEFloatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEFloatConverter.h; sourceTree = "<group>"; };
|
||||
665956C61B38B256003E97A1 /* AEFloatConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AEFloatConverter.m; sourceTree = "<group>"; };
|
||||
665956C71B38B256003E97A1 /* EZAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudio.h; sourceTree = "<group>"; };
|
||||
665956C81B38B256003E97A1 /* EZAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudio.m; sourceTree = "<group>"; };
|
||||
665956C91B38B256003E97A1 /* EZAudioDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioDevice.h; sourceTree = "<group>"; };
|
||||
665956CA1B38B256003E97A1 /* EZAudioDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioDevice.m; sourceTree = "<group>"; };
|
||||
665956CB1B38B256003E97A1 /* EZAudioFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFile.h; sourceTree = "<group>"; };
|
||||
665956CC1B38B256003E97A1 /* EZAudioFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFile.m; sourceTree = "<group>"; };
|
||||
665956CD1B38B256003E97A1 /* EZAudioFloatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFloatConverter.h; sourceTree = "<group>"; };
|
||||
665956CE1B38B256003E97A1 /* EZAudioFloatConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFloatConverter.m; sourceTree = "<group>"; };
|
||||
665956CF1B38B256003E97A1 /* EZAudioFloatData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFloatData.h; sourceTree = "<group>"; };
|
||||
665956D01B38B256003E97A1 /* EZAudioFloatData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFloatData.m; sourceTree = "<group>"; };
|
||||
665956D11B38B256003E97A1 /* EZAudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlayer.h; sourceTree = "<group>"; };
|
||||
665956D21B38B256003E97A1 /* EZAudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlayer.m; sourceTree = "<group>"; };
|
||||
665956D31B38B256003E97A1 /* EZAudioPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlot.h; sourceTree = "<group>"; };
|
||||
665956D41B38B256003E97A1 /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
665956D51B38B256003E97A1 /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
665956D61B38B256003E97A1 /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
665956D71B38B256003E97A1 /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
665956D81B38B256003E97A1 /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
665956D91B38B256003E97A1 /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
665956DA1B38B256003E97A1 /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
665956DB1B38B256003E97A1 /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
665956DC1B38B256003E97A1 /* EZMicrophone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZMicrophone.m; sourceTree = "<group>"; };
|
||||
665956DD1B38B256003E97A1 /* EZOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZOutput.h; sourceTree = "<group>"; };
|
||||
665956DE1B38B256003E97A1 /* EZOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZOutput.m; sourceTree = "<group>"; };
|
||||
665956DF1B38B256003E97A1 /* EZPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZPlot.h; sourceTree = "<group>"; };
|
||||
665956E01B38B256003E97A1 /* EZPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZPlot.m; sourceTree = "<group>"; };
|
||||
665956E11B38B256003E97A1 /* EZRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZRecorder.h; sourceTree = "<group>"; };
|
||||
665956E21B38B256003E97A1 /* EZRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZRecorder.m; sourceTree = "<group>"; };
|
||||
665956E31B38B256003E97A1 /* TPCircularBuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = TPCircularBuffer.c; sourceTree = "<group>"; };
|
||||
665956E41B38B256003E97A1 /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
665956E61B38B256003E97A1 /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
665956E71B38B256003E97A1 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
94373021185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EZAudioCoreGraphicsWaveformExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94373024185B931C00F315F0 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
94373027185B931C00F315F0 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
94373028185B931C00F315F0 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
94373029185B931C00F315F0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
9437302C185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioCoreGraphicsWaveformExample-Info.plist"; sourceTree = "<group>"; };
|
||||
9437302E185B931C00F315F0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
94373030185B931C00F315F0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = main.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
94373032185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "EZAudioCoreGraphicsWaveformExample-Prefix.pch"; sourceTree = "<group>"; };
|
||||
94373034185B931C00F315F0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
94373036185B931C00F315F0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AppDelegate.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
94373037185B931C00F315F0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppDelegate.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
9437303A185B931C00F315F0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
9437303C185B931C00F315F0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
94373042185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EZAudioCoreGraphicsWaveformExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94373043185B931C00F315F0 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
9437304A185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioCoreGraphicsWaveformExampleTests-Info.plist"; sourceTree = "<group>"; };
|
||||
9437304C185B931C00F315F0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
9437304E185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = EZAudioCoreGraphicsWaveformExampleTests.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
9437307D185B934900F315F0 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
9437307E185B934900F315F0 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||
9437307F185B934900F315F0 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
||||
94373083185B936B00F315F0 /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
|
||||
94373085185B937100F315F0 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||
94373087185B937E00F315F0 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
9437301E185B931C00F315F0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
94373088185B937E00F315F0 /* QuartzCore.framework in Frameworks */,
|
||||
94373086185B937100F315F0 /* OpenGL.framework in Frameworks */,
|
||||
94373084185B936B00F315F0 /* GLKit.framework in Frameworks */,
|
||||
94373080185B934900F315F0 /* AudioToolbox.framework in Frameworks */,
|
||||
94373081185B934900F315F0 /* AudioUnit.framework in Frameworks */,
|
||||
94373082185B934900F315F0 /* CoreAudio.framework in Frameworks */,
|
||||
94373025185B931C00F315F0 /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9437303F185B931C00F315F0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
94373045185B931C00F315F0 /* Cocoa.framework in Frameworks */,
|
||||
94373044185B931C00F315F0 /* XCTest.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
665956C41B38B256003E97A1 /* EZAudio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
665956C51B38B256003E97A1 /* AEFloatConverter.h */,
|
||||
665956C61B38B256003E97A1 /* AEFloatConverter.m */,
|
||||
665956C71B38B256003E97A1 /* EZAudio.h */,
|
||||
665956C81B38B256003E97A1 /* EZAudio.m */,
|
||||
665956C91B38B256003E97A1 /* EZAudioDevice.h */,
|
||||
665956CA1B38B256003E97A1 /* EZAudioDevice.m */,
|
||||
665956CB1B38B256003E97A1 /* EZAudioFile.h */,
|
||||
665956CC1B38B256003E97A1 /* EZAudioFile.m */,
|
||||
665956CD1B38B256003E97A1 /* EZAudioFloatConverter.h */,
|
||||
665956CE1B38B256003E97A1 /* EZAudioFloatConverter.m */,
|
||||
665956CF1B38B256003E97A1 /* EZAudioFloatData.h */,
|
||||
665956D01B38B256003E97A1 /* EZAudioFloatData.m */,
|
||||
665956D11B38B256003E97A1 /* EZAudioPlayer.h */,
|
||||
665956D21B38B256003E97A1 /* EZAudioPlayer.m */,
|
||||
665956D31B38B256003E97A1 /* EZAudioPlot.h */,
|
||||
665956D41B38B256003E97A1 /* EZAudioPlot.m */,
|
||||
665956D51B38B256003E97A1 /* EZAudioPlotGL.h */,
|
||||
665956D61B38B256003E97A1 /* EZAudioPlotGL.m */,
|
||||
665956D71B38B256003E97A1 /* EZAudioPlotGLKViewController.h */,
|
||||
665956D81B38B256003E97A1 /* EZAudioPlotGLKViewController.m */,
|
||||
665956D91B38B256003E97A1 /* EZAudioUtilities.h */,
|
||||
665956DA1B38B256003E97A1 /* EZAudioUtilities.m */,
|
||||
665956DB1B38B256003E97A1 /* EZMicrophone.h */,
|
||||
665956DC1B38B256003E97A1 /* EZMicrophone.m */,
|
||||
665956DD1B38B256003E97A1 /* EZOutput.h */,
|
||||
665956DE1B38B256003E97A1 /* EZOutput.m */,
|
||||
665956DF1B38B256003E97A1 /* EZPlot.h */,
|
||||
665956E01B38B256003E97A1 /* EZPlot.m */,
|
||||
665956E11B38B256003E97A1 /* EZRecorder.h */,
|
||||
665956E21B38B256003E97A1 /* EZRecorder.m */,
|
||||
665956E31B38B256003E97A1 /* TPCircularBuffer.c */,
|
||||
665956E41B38B256003E97A1 /* TPCircularBuffer.h */,
|
||||
665956E51B38B256003E97A1 /* VERSION */,
|
||||
);
|
||||
name = EZAudio;
|
||||
path = ../../../../EZAudio;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
665956E51B38B256003E97A1 /* VERSION */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
665956E61B38B256003E97A1 /* CHANGELOG */,
|
||||
665956E71B38B256003E97A1 /* VERSION */,
|
||||
);
|
||||
path = VERSION;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94373018185B931C00F315F0 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9437302A185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample */,
|
||||
94373048185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests */,
|
||||
94373023185B931C00F315F0 /* Frameworks */,
|
||||
94373022185B931C00F315F0 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94373022185B931C00F315F0 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94373021185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample.app */,
|
||||
94373042185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94373023185B931C00F315F0 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94373087185B937E00F315F0 /* QuartzCore.framework */,
|
||||
94373085185B937100F315F0 /* OpenGL.framework */,
|
||||
94373083185B936B00F315F0 /* GLKit.framework */,
|
||||
9437307D185B934900F315F0 /* AudioToolbox.framework */,
|
||||
9437307E185B934900F315F0 /* AudioUnit.framework */,
|
||||
9437307F185B934900F315F0 /* CoreAudio.framework */,
|
||||
94373024185B931C00F315F0 /* Cocoa.framework */,
|
||||
94373043185B931C00F315F0 /* XCTest.framework */,
|
||||
94373026185B931C00F315F0 /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94373026185B931C00F315F0 /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94373027185B931C00F315F0 /* AppKit.framework */,
|
||||
94373028185B931C00F315F0 /* CoreData.framework */,
|
||||
94373029185B931C00F315F0 /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9437302A185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
665956C41B38B256003E97A1 /* EZAudio */,
|
||||
94373036185B931C00F315F0 /* AppDelegate.h */,
|
||||
94373037185B931C00F315F0 /* AppDelegate.m */,
|
||||
94056D85185B97E300EB94BA /* CoreGraphicsWaveformViewController.h */,
|
||||
94056D86185B97E300EB94BA /* CoreGraphicsWaveformViewController.m */,
|
||||
94056D87185B97E300EB94BA /* CoreGraphicsWaveformViewController.xib */,
|
||||
94373039185B931C00F315F0 /* MainMenu.xib */,
|
||||
9437303C185B931C00F315F0 /* Images.xcassets */,
|
||||
9437302B185B931C00F315F0 /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioCoreGraphicsWaveformExample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9437302B185B931C00F315F0 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9437302C185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample-Info.plist */,
|
||||
9437302D185B931C00F315F0 /* InfoPlist.strings */,
|
||||
94373030185B931C00F315F0 /* main.m */,
|
||||
94373032185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample-Prefix.pch */,
|
||||
94373033185B931C00F315F0 /* Credits.rtf */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94373048185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9437304E185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests.m */,
|
||||
94373049185B931C00F315F0 /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioCoreGraphicsWaveformExampleTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94373049185B931C00F315F0 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9437304A185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests-Info.plist */,
|
||||
9437304B185B931C00F315F0 /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
94373020185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 94373052185B931D00F315F0 /* Build configuration list for PBXNativeTarget "EZAudioCoreGraphicsWaveformExample" */;
|
||||
buildPhases = (
|
||||
9437301D185B931C00F315F0 /* Sources */,
|
||||
9437301E185B931C00F315F0 /* Frameworks */,
|
||||
9437301F185B931C00F315F0 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = EZAudioCoreGraphicsWaveformExample;
|
||||
productName = EZAudioCoreGraphicsWaveformExample;
|
||||
productReference = 94373021185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
94373041185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 94373055185B931D00F315F0 /* Build configuration list for PBXNativeTarget "EZAudioCoreGraphicsWaveformExampleTests" */;
|
||||
buildPhases = (
|
||||
9437303E185B931C00F315F0 /* Sources */,
|
||||
9437303F185B931C00F315F0 /* Frameworks */,
|
||||
94373040185B931C00F315F0 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
94373047185B931C00F315F0 /* PBXTargetDependency */,
|
||||
);
|
||||
name = EZAudioCoreGraphicsWaveformExampleTests;
|
||||
productName = EZAudioCoreGraphicsWaveformExampleTests;
|
||||
productReference = 94373042185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
94373019185B931C00F315F0 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Syed Haris Ali";
|
||||
TargetAttributes = {
|
||||
94373041185B931C00F315F0 = {
|
||||
TestTargetID = 94373020185B931C00F315F0;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 9437301C185B931C00F315F0 /* Build configuration list for PBXProject "EZAudioCoreGraphicsWaveformExample" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 94373018185B931C00F315F0;
|
||||
productRefGroup = 94373022185B931C00F315F0 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
94373020185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample */,
|
||||
94373041185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests */,
|
||||
94F8DF4A18C84203005C4CBD /* Generate Documentation */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
9437301F185B931C00F315F0 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9437302F185B931C00F315F0 /* InfoPlist.strings in Resources */,
|
||||
665956F91B38B256003E97A1 /* VERSION in Resources */,
|
||||
9437303D185B931C00F315F0 /* Images.xcassets in Resources */,
|
||||
94373035185B931C00F315F0 /* Credits.rtf in Resources */,
|
||||
94056D89185B97E300EB94BA /* CoreGraphicsWaveformViewController.xib in Resources */,
|
||||
9437303B185B931C00F315F0 /* MainMenu.xib in Resources */,
|
||||
665956F81B38B256003E97A1 /* CHANGELOG in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
94373040185B931C00F315F0 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9437304D185B931C00F315F0 /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
94F8DF4E18C8420C005C4CBD /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/usr/local/bin/appledoc \\\n--project-name \"EZAudio\" \\\n--project-company \"Syed Haris Ali\" \\\n--company-id \"com.sha\" \\\n--output documentation \\\n--create-docset \\\n--install-docset \\\n--create-html \\\n--exit-threshold 2 \\\n--no-repeat-first-par \\\n/../EZAudio";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
9437301D185B931C00F315F0 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
665956F61B38B256003E97A1 /* EZRecorder.m in Sources */,
|
||||
94056D88185B97E300EB94BA /* CoreGraphicsWaveformViewController.m in Sources */,
|
||||
665956EC1B38B256003E97A1 /* EZAudioFloatConverter.m in Sources */,
|
||||
665956ED1B38B256003E97A1 /* EZAudioFloatData.m in Sources */,
|
||||
665956E81B38B256003E97A1 /* AEFloatConverter.m in Sources */,
|
||||
665956EB1B38B256003E97A1 /* EZAudioFile.m in Sources */,
|
||||
665956F41B38B256003E97A1 /* EZOutput.m in Sources */,
|
||||
665956F01B38B256003E97A1 /* EZAudioPlotGL.m in Sources */,
|
||||
665956F71B38B256003E97A1 /* TPCircularBuffer.c in Sources */,
|
||||
665956EF1B38B256003E97A1 /* EZAudioPlot.m in Sources */,
|
||||
94373038185B931C00F315F0 /* AppDelegate.m in Sources */,
|
||||
665956F31B38B256003E97A1 /* EZMicrophone.m in Sources */,
|
||||
665956EE1B38B256003E97A1 /* EZAudioPlayer.m in Sources */,
|
||||
665956EA1B38B256003E97A1 /* EZAudioDevice.m in Sources */,
|
||||
94373031185B931C00F315F0 /* main.m in Sources */,
|
||||
665956F51B38B256003E97A1 /* EZPlot.m in Sources */,
|
||||
665956E91B38B256003E97A1 /* EZAudio.m in Sources */,
|
||||
665956F21B38B256003E97A1 /* EZAudioUtilities.m in Sources */,
|
||||
665956F11B38B256003E97A1 /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9437303E185B931C00F315F0 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9437304F185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExampleTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
94373047185B931C00F315F0 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 94373020185B931C00F315F0 /* EZAudioCoreGraphicsWaveformExample */;
|
||||
targetProxy = 94373046185B931C00F315F0 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
9437302D185B931C00F315F0 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9437302E185B931C00F315F0 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94373033185B931C00F315F0 /* Credits.rtf */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
94373034185B931C00F315F0 /* en */,
|
||||
);
|
||||
name = Credits.rtf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94373039185B931C00F315F0 /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9437303A185B931C00F315F0 /* Base */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9437304B185B931C00F315F0 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9437304C185B931C00F315F0 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
94373050185B931D00F315F0 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
94373051185B931D00F315F0 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
94373053185B931D00F315F0 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioCoreGraphicsWaveformExample/EZAudioCoreGraphicsWaveformExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioCoreGraphicsWaveformExample/EZAudioCoreGraphicsWaveformExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
94373054185B931D00F315F0 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioCoreGraphicsWaveformExample/EZAudioCoreGraphicsWaveformExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioCoreGraphicsWaveformExample/EZAudioCoreGraphicsWaveformExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
94373056185B931D00F315F0 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioCoreGraphicsWaveformExample.app/Contents/MacOS/EZAudioCoreGraphicsWaveformExample";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioCoreGraphicsWaveformExample/EZAudioCoreGraphicsWaveformExample-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "EZAudioCoreGraphicsWaveformExampleTests/EZAudioCoreGraphicsWaveformExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
94373057185B931D00F315F0 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioCoreGraphicsWaveformExample.app/Contents/MacOS/EZAudioCoreGraphicsWaveformExample";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioCoreGraphicsWaveformExample/EZAudioCoreGraphicsWaveformExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioCoreGraphicsWaveformExampleTests/EZAudioCoreGraphicsWaveformExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
94F8DF4B18C84204005C4CBD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
94F8DF4C18C84204005C4CBD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
9437301C185B931C00F315F0 /* Build configuration list for PBXProject "EZAudioCoreGraphicsWaveformExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
94373050185B931D00F315F0 /* Debug */,
|
||||
94373051185B931D00F315F0 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
94373052185B931D00F315F0 /* Build configuration list for PBXNativeTarget "EZAudioCoreGraphicsWaveformExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
94373053185B931D00F315F0 /* Debug */,
|
||||
94373054185B931D00F315F0 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
94373055185B931D00F315F0 /* Build configuration list for PBXNativeTarget "EZAudioCoreGraphicsWaveformExampleTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
94373056185B931D00F315F0 /* Debug */,
|
||||
94373057185B931D00F315F0 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
94F8DF4D18C84204005C4CBD /* Build configuration list for PBXAggregateTarget "Generate Documentation" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
94F8DF4B18C84204005C4CBD /* Debug */,
|
||||
94F8DF4C18C84204005C4CBD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 94373019185B931C00F315F0 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:EZAudioCoreGraphicsWaveformExample.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// EZAudioCoreGraphicsWaveformExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "CoreGraphicsWaveformViewController.h"
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
|
||||
/**
|
||||
Create our CoreGraphicsWaveformViewController
|
||||
*/
|
||||
@property (nonatomic,strong) CoreGraphicsWaveformViewController *coreGraphicsWaveformViewController;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// EZAudioCoreGraphicsWaveformExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
@synthesize coreGraphicsWaveformViewController;
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
// Swap in our view controller in the window's content view
|
||||
self.coreGraphicsWaveformViewController = [[CoreGraphicsWaveformViewController alloc] initWithNibName:NSStringFromClass(CoreGraphicsWaveformViewController.class) bundle:nil];
|
||||
// Resize view controller to content view's current size
|
||||
self.coreGraphicsWaveformViewController.view.frame = [self.window.contentView frame];
|
||||
// Add resizing flags to make the view controller resize with the window
|
||||
self.coreGraphicsWaveformViewController.view.autoresizingMask = (NSViewWidthSizable|NSViewHeightSizable);
|
||||
// Add in the core graphics view controller as subview
|
||||
[self.window.contentView addSubview:self.coreGraphicsWaveformViewController.view];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// CoreGraphicsWaveformViewController.h
|
||||
// EZAudioCoreGraphicsWaveformExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/13/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
// Import EZAudio header
|
||||
#import "EZAudio.h"
|
||||
|
||||
/**
|
||||
We will allow this view controller to act as an EZMicrophoneDelegate. This is how we listen for the microphone callback.
|
||||
*/
|
||||
@interface CoreGraphicsWaveformViewController : NSViewController <EZMicrophoneDelegate>
|
||||
|
||||
#pragma mark - Components
|
||||
/**
|
||||
The CoreGraphics based audio plot
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlot *audioPlot;
|
||||
|
||||
/**
|
||||
The microphone component
|
||||
*/
|
||||
@property (nonatomic,strong) EZMicrophone *microphone;
|
||||
|
||||
#pragma mark - Actions
|
||||
/**
|
||||
Toggles the microphone on and off. When the microphone is on it will send its delegate (aka this view controller) the audio data in various ways (check out the EZMicrophoneDelegate documentation for more details);
|
||||
*/
|
||||
-(IBAction)toggleMicrophone:(id)sender;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// CoreGraphicsWaveformViewController.m
|
||||
// EZAudioCoreGraphicsWaveformExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/13/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CoreGraphicsWaveformViewController.h"
|
||||
|
||||
@interface CoreGraphicsWaveformViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation CoreGraphicsWaveformViewController
|
||||
|
||||
#pragma mark - Initialization
|
||||
-(id)init {
|
||||
self = [super initWithNibName:NSStringFromClass(self.class) bundle:nibBundleOrNil];
|
||||
if(self){
|
||||
[self initializeViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithNibName:NSStringFromClass(self.class) bundle:nibBundleOrNil];
|
||||
if(self){
|
||||
[self initializeViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
||||
self = [super initWithNibName:NSStringFromClass(self.class) bundle:nibBundleOrNil];
|
||||
if(self){
|
||||
[self initializeViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Initialize View Controller
|
||||
-(void)initializeViewController {
|
||||
// Create an instance of the microphone
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self];
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13A603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="CoreGraphicsWaveformViewController">
|
||||
<connections>
|
||||
<outlet property="view" destination="1" id="2"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<customView id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BYN-Cr-ONS">
|
||||
<rect key="frame" x="199" y="119" width="82" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="kX8-uO-Adi">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
</subviews>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,347 +1,327 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="audioPlotFreq" destination="bYU-wY-hDo" id="GIp-Pk-HtM"/>
|
||||
<outlet property="audioPlotTime" destination="SUJ-Np-jlL" id="Dt9-qz-RbQ"/>
|
||||
<outlet property="maxFrequencyLabel" destination="Vjf-P4-Me7" id="5Lx-gm-QId"/>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="FFT" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="FFT" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<menuItem title="EZAudioCoreGraphicsWaveformExample" id="56">
|
||||
<menu key="submenu" title="EZAudioCoreGraphicsWaveformExample" systemMenu="apple" id="57">
|
||||
<items>
|
||||
<menuItem title="About FFT" id="5kV-Vb-QxS">
|
||||
<menuItem title="About EZAudioCoreGraphicsWaveformExample" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||
<menuItem title="Services" id="NMo-om-nkz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||
<menuItem title="Hide FFT" keyEquivalent="h" id="Olw-nP-bQN">
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
|
||||
<menuItem isSeparatorItem="YES" id="143">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Services" id="131">
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide EZAudioCoreGraphicsWaveformExample" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Show All" id="150">
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||
<menuItem title="Quit FFT" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit EZAudioCoreGraphicsWaveformExample" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
|
||||
<action selector="terminate:" target="-3" id="449"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="dMs-cI-mzQ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="File" id="bib-Uj-vzu">
|
||||
<menuItem title="File" id="83">
|
||||
<menu key="submenu" title="File" id="81">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
|
||||
<menuItem title="New" keyEquivalent="n" id="82">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
|
||||
<action selector="newDocument:" target="-1" id="373"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
|
||||
<action selector="openDocument:" target="-1" id="374"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="tXI-mr-wws">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
|
||||
<menuItem title="Open Recent" id="124">
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="vNY-rz-j42">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Clear Menu" id="126">
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="127"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
|
||||
<action selector="performClose:" target="-1" id="193"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
|
||||
<action selector="saveDocument:" target="-1" id="362"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
|
||||
<connections>
|
||||
<action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="KaW-ft-85H">
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
|
||||
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/>
|
||||
<action selector="runPageLayout:" target="-1" id="87"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78">
|
||||
<connections>
|
||||
<action selector="print:" target="-1" id="qaZ-4w-aoO"/>
|
||||
<action selector="print:" target="-1" id="86"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="5QF-Oa-p0T">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="M6e-cu-g7V"/>
|
||||
<action selector="undo:" target="-1" id="223"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
|
||||
<action selector="redo:" target="-1" id="231"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="YJe-68-I9s"/>
|
||||
<action selector="cut:" target="-1" id="228"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="G1f-GL-Joy"/>
|
||||
<action selector="copy:" target="-1" id="224"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
|
||||
<action selector="paste:" target="-1" id="226"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="486"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="pa3-QI-u2k">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Delete" id="202">
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
|
||||
<action selector="delete:" target="-1" id="235"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
|
||||
<action selector="selectAll:" target="-1" id="232"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
|
||||
<menuItem title="Find" id="4EN-yA-p0u">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Find" id="1b7-l0-nxx">
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
|
||||
<action selector="performFindPanelAction:" target="-1" id="241"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
|
||||
<action selector="performFindPanelAction:" target="-1" id="535"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
|
||||
<action selector="performFindPanelAction:" target="-1" id="487"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
|
||||
<action selector="performFindPanelAction:" target="-1" id="488"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
|
||||
<action selector="performFindPanelAction:" target="-1" id="489"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
|
||||
<menuItem title="Spelling and Grammar" id="216">
|
||||
<menu key="submenu" title="Spelling and Grammar" id="200">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
|
||||
<action selector="showGuessPanel:" target="-1" id="230"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
|
||||
<action selector="checkSpelling:" target="-1" id="225"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
|
||||
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
|
||||
<menuItem isSeparatorItem="YES" id="453"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219">
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="346">
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="454">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="456"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="9ic-FL-obx">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
|
||||
<menuItem title="Substitutions" id="348">
|
||||
<menu key="submenu" title="Substitutions" id="349">
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
|
||||
<menuItem title="Show Substitutions" id="457">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="458"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
|
||||
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
|
||||
<menuItem title="Smart Dashes" id="460">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="461"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" id="cwL-P1-jid">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Data Detectors" id="tRr-pd-1PS">
|
||||
<menuItem title="Text Replacement" id="462">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="463"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="2oI-Rn-ZJC">
|
||||
<menuItem title="Transformations" id="450">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
|
||||
<menu key="submenu" title="Transformations" id="451">
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
|
||||
<menuItem title="Make Upper Case" id="452">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
|
||||
<action selector="uppercaseWord:" target="-1" id="464"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
|
||||
<menuItem title="Make Lower Case" id="465">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
|
||||
<action selector="lowercaseWord:" target="-1" id="468"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
|
||||
<menuItem title="Capitalize" id="466">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
|
||||
<action selector="capitalizeWord:" target="-1" id="467"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="xrE-MZ-jX0">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Start Speaking" id="196">
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
|
||||
<action selector="startSpeaking:" target="-1" id="233"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Stop Speaking" id="195">
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
|
||||
<action selector="stopSpeaking:" target="-1" id="227"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -350,260 +330,260 @@
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="jxT-CU-nIS">
|
||||
<menuItem title="Format" id="375">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
|
||||
<menu key="submenu" title="Format" id="376">
|
||||
<items>
|
||||
<menuItem title="Font" id="Gi5-1S-RQB">
|
||||
<menuItem title="Font" id="377">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
|
||||
<action selector="orderFrontFontPanel:" target="420" id="424"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
|
||||
<action selector="addFontTrait:" target="420" id="421"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
|
||||
<action selector="addFontTrait:" target="420" id="422"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="FYS-2b-JAY"/>
|
||||
<action selector="underline:" target="-1" id="432"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
|
||||
<menuItem isSeparatorItem="YES" id="393"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
|
||||
<action selector="modifyFont:" target="420" id="425"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
|
||||
<action selector="modifyFont:" target="420" id="423"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
|
||||
<menuItem title="Kern" id="jBQ-r6-VK2">
|
||||
<menuItem isSeparatorItem="YES" id="396"/>
|
||||
<menuItem title="Kern" id="397">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
|
||||
<menu key="submenu" title="Kern" id="415">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="GUa-eO-cwY">
|
||||
<menuItem title="Use Default" id="416">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
|
||||
<action selector="useStandardKerning:" target="-1" id="438"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="cDB-IK-hbR">
|
||||
<menuItem title="Use None" id="417">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
|
||||
<action selector="turnOffKerning:" target="-1" id="441"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="46P-cB-AYj">
|
||||
<menuItem title="Tighten" id="418">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
|
||||
<action selector="tightenKerning:" target="-1" id="431"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="ogc-rX-tC1">
|
||||
<menuItem title="Loosen" id="419">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
|
||||
<action selector="loosenKerning:" target="-1" id="435"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="o6e-r0-MWq">
|
||||
<menuItem title="Ligatures" id="398">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
|
||||
<menu key="submenu" title="Ligatures" id="411">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="agt-UL-0e3">
|
||||
<menuItem title="Use Default" id="412">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
|
||||
<action selector="useStandardLigatures:" target="-1" id="439"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="J7y-lM-qPV">
|
||||
<menuItem title="Use None" id="413">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
|
||||
<action selector="turnOffLigatures:" target="-1" id="440"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="xQD-1f-W4t">
|
||||
<menuItem title="Use All" id="414">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
|
||||
<action selector="useAllLigatures:" target="-1" id="434"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="OaQ-X3-Vso">
|
||||
<menuItem title="Baseline" id="399">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
|
||||
<menu key="submenu" title="Baseline" id="405">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="3Om-Ey-2VK">
|
||||
<menuItem title="Use Default" id="406">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
|
||||
<action selector="unscript:" target="-1" id="437"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="Rqc-34-cIF">
|
||||
<menuItem title="Superscript" id="407">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
|
||||
<action selector="superscript:" target="-1" id="430"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="I0S-gh-46l">
|
||||
<menuItem title="Subscript" id="408">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
|
||||
<action selector="subscript:" target="-1" id="429"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="2h7-ER-AoG">
|
||||
<menuItem title="Raise" id="409">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
|
||||
<action selector="raiseBaseline:" target="-1" id="426"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="1tx-W0-xDw">
|
||||
<menuItem title="Lower" id="410">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
|
||||
<action selector="lowerBaseline:" target="-1" id="427"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
|
||||
<menuItem isSeparatorItem="YES" id="400"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
|
||||
<menuItem isSeparatorItem="YES" id="402"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
|
||||
<action selector="copyFont:" target="-1" id="428"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
|
||||
<action selector="pasteFont:" target="-1" id="436"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="Fal-I4-PZk">
|
||||
<menuItem title="Text" id="496">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="d9c-me-L2H">
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
|
||||
<action selector="alignLeft:" target="-1" id="524"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
|
||||
<menuItem title="Center" keyEquivalent="|" id="499">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
|
||||
<action selector="alignCenter:" target="-1" id="518"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="J5U-5w-g23">
|
||||
<menuItem title="Justify" id="500">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
|
||||
<action selector="alignJustified:" target="-1" id="523"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
|
||||
<action selector="alignRight:" target="-1" id="521"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
|
||||
<menuItem title="Writing Direction" id="H1b-Si-o9J">
|
||||
<menuItem isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
|
||||
<menu key="submenu" title="Writing Direction" id="508">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
|
||||
<menuItem title="Paragraph" enabled="NO" id="509">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="YGs-j5-SAR">
|
||||
<menuItem id="510">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="Lbh-J2-qVU">
|
||||
<menuItem id="511">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="jFq-tB-4Kx">
|
||||
<menuItem id="512">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="527"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
|
||||
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
|
||||
<menuItem isSeparatorItem="YES" id="513"/>
|
||||
<menuItem title="Selection" enabled="NO" id="514">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="Nop-cj-93Q">
|
||||
<menuItem id="515">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="BgM-ve-c93">
|
||||
<menuItem id="516">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="RB4-Sm-HuC">
|
||||
<menuItem id="517">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="530"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
|
||||
<menuItem title="Show Ruler" id="vLm-3I-IUL">
|
||||
<menuItem isSeparatorItem="YES" id="504"/>
|
||||
<menuItem title="Show Ruler" id="505">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
|
||||
<action selector="toggleRuler:" target="-1" id="520"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
|
||||
<action selector="copyRuler:" target="-1" id="522"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
|
||||
<action selector="pasteRuler:" target="-1" id="519"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -612,57 +592,54 @@
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="H8h-7b-M4v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||
<menuItem title="View" id="295">
|
||||
<menu key="submenu" title="View" id="296">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Customize Toolbar…" id="298">
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
|
||||
<action selector="performMiniaturize:" target="-1" id="37"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Zoom" id="239">
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
|
||||
<action selector="performZoom:" target="-1" id="240"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="wpr-3q-Mcd">
|
||||
<menuItem title="Help" id="490">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="FFT Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<menuItem title="EZAudioCoreGraphicsWaveformExample Help" keyEquivalent="?" id="492">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -670,63 +647,21 @@
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="FFT" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<window title="EZAudioCoreGraphicsWaveformExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="272"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="bYU-wY-hDo" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<subviews>
|
||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="SUJ-Np-jlL" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="18" y="190" width="444" height="64"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="64" id="0kl-Pj-Sge"/>
|
||||
</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="Vjf-P4-Me7">
|
||||
<rect key="frame" x="16" y="159" width="4" height="22"/>
|
||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="V1O-MR-dks">
|
||||
<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>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="SUJ-Np-jlL" secondAttribute="trailing" constant="18" id="8e6-wa-2iS"/>
|
||||
<constraint firstItem="Vjf-P4-Me7" firstAttribute="leading" secondItem="bYU-wY-hDo" secondAttribute="leading" constant="18" id="8iO-u0-Hif"/>
|
||||
<constraint firstItem="Vjf-P4-Me7" firstAttribute="top" secondItem="SUJ-Np-jlL" secondAttribute="bottom" constant="9" id="IoR-eV-hfX"/>
|
||||
<constraint firstItem="SUJ-Np-jlL" firstAttribute="leading" secondItem="bYU-wY-hDo" secondAttribute="leading" constant="18" id="cjI-VW-eMW"/>
|
||||
<constraint firstItem="SUJ-Np-jlL" firstAttribute="top" secondItem="bYU-wY-hDo" secondAttribute="top" constant="18" id="m9C-bU-rjo"/>
|
||||
</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>
|
||||
</customView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="bYU-wY-hDo" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="5z4-1k-1AB"/>
|
||||
<constraint firstItem="bYU-wY-hDo" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="DTD-Tg-LKd"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bYU-wY-hDo" secondAttribute="trailing" id="dXG-Z8-3Xu"/>
|
||||
<constraint firstAttribute="bottom" secondItem="bYU-wY-hDo" secondAttribute="bottom" id="tJa-lp-h1P"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<point key="canvasLocation" x="252" y="239"/>
|
||||
</window>
|
||||
<customObject id="494" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager"/>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,9 +1,8 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// CoreGraphicsWaveform
|
||||
// CoreGraphicsWaveformViewController.h
|
||||
// EZAudioCoreGraphicsWaveformExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Updated by Syed Haris Ali on 1/23/16.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -26,70 +25,50 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
//
|
||||
// First import the EZAudio header
|
||||
//
|
||||
#include <EZAudio/EZAudio.h>
|
||||
// Import EZAudio header
|
||||
#import "EZAudio.h"
|
||||
|
||||
/**
|
||||
We will allow this view controller to act as an EZMicrophoneDelegate. This is how we listen for the microphone callback.
|
||||
*/
|
||||
@interface CoreGraphicsWaveformViewController : NSViewController <EZMicrophoneDelegate>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - AppDelegate
|
||||
#pragma mark - Components
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@interface AppDelegate : NSObject <EZMicrophoneDelegate, NSApplicationDelegate>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Properties
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// The CoreGraphics based audio plot
|
||||
//
|
||||
/**
|
||||
The CoreGraphics based audio plot
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet EZAudioPlot *audioPlot;
|
||||
|
||||
//
|
||||
// The microphone
|
||||
//
|
||||
/**
|
||||
The microphone component
|
||||
*/
|
||||
@property (nonatomic, strong) EZMicrophone *microphone;
|
||||
|
||||
//
|
||||
// The microphone pop up button (contains the menu for choosing a microphone
|
||||
// input)
|
||||
//
|
||||
/**
|
||||
The microphone pop up button (contains the menu for choosing a microphone input)
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSPopUpButton *microphoneInputPopUpButton;
|
||||
|
||||
//
|
||||
// The microphone input channel pop up button (contains the menu for choosing a
|
||||
// microphone input channel)
|
||||
//
|
||||
/**
|
||||
The microphone input channel pop up button (contains the menu for choosing a microphone input channel)
|
||||
*/
|
||||
@property (nonatomic, weak) IBOutlet NSPopUpButton *microphoneInputChannelPopUpButton;
|
||||
|
||||
//
|
||||
// The checkbox button used to turn the microphone off/on
|
||||
//
|
||||
@property (nonatomic, weak) IBOutlet NSButton *microphoneSwitch;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Actions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Switches the plot drawing type between a buffer plot (visualizes the current
|
||||
// stream of audio data from the update function) or a rolling plot (visualizes
|
||||
// the audio data over time, this is the classic waveform look)
|
||||
//
|
||||
/**
|
||||
Switches the plot drawing type between a buffer plot (visualizes the current stream of audio data from the update function) or a rolling plot (visualizes the audio data over time, this is the classic waveform look)
|
||||
*/
|
||||
-(IBAction)changePlotType:(id)sender;
|
||||
|
||||
//
|
||||
// Toggles the microphone on and off. When the microphone is on it will send its
|
||||
// delegate (aka this view controller) the audio data in various ways (check out
|
||||
// the EZMicrophoneDelegate documentation for more details)
|
||||
//
|
||||
/**
|
||||
Toggles the microphone on and off. When the microphone is on it will send its delegate (aka this view controller) the audio data in various ways (check out the EZMicrophoneDelegate documentation for more details);
|
||||
*/
|
||||
-(IBAction)toggleMicrophone:(id)sender;
|
||||
|
||||
@end
|
||||
@@ -1,9 +1,8 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// CoreGraphicsWaveform
|
||||
// CoreGraphicsWaveformViewController.m
|
||||
// EZAudioCoreGraphicsWaveformExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Updated by Syed Haris Ali on 1/23/16.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -24,31 +23,28 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "CoreGraphicsWaveformViewController.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
@implementation CoreGraphicsWaveformViewController
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Customize The Plot's Appearance
|
||||
#pragma mark - Customize the Audio Plot
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
//
|
||||
// Set plot's background color
|
||||
// Customizing the audio plot's look
|
||||
//
|
||||
// Background color
|
||||
self.audioPlot.backgroundColor = [NSColor colorWithCalibratedRed: 0.984 green: 0.471 blue: 0.525 alpha: 1];
|
||||
|
||||
//
|
||||
// Set plot's waveform color
|
||||
//
|
||||
// Waveform color
|
||||
self.audioPlot.color = [NSColor colorWithCalibratedRed: 1.000 green: 1.000 blue: 1.000 alpha: 1];
|
||||
|
||||
//
|
||||
// Plot type (buffer means real-time, rolling is over time)
|
||||
//
|
||||
// Plot type
|
||||
self.audioPlot.plotType = EZPlotTypeBuffer;
|
||||
|
||||
|
||||
//
|
||||
// Create the microphone
|
||||
//
|
||||
@@ -106,8 +102,10 @@
|
||||
for (int i = 0; i < self.microphone.device.inputChannelCount; i++)
|
||||
{
|
||||
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@(i).stringValue
|
||||
action:nil
|
||||
action:@selector(changedInputChannel:)
|
||||
keyEquivalent:@""];
|
||||
item.representedObject = @(i);
|
||||
item.target = self;
|
||||
[menu addItem:item];
|
||||
}
|
||||
self.microphoneInputChannelPopUpButton.menu = menu;
|
||||
@@ -126,6 +124,12 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)changedInputChannel:(id)sender
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)changePlotType:(id)sender
|
||||
{
|
||||
NSInteger selectedSegment = [sender selectedSegment];
|
||||
@@ -159,10 +163,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Action Extensions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Give the visualization of the current buffer (this is almost exactly the openFrameworks audio input eample)
|
||||
*/
|
||||
@@ -187,31 +188,16 @@
|
||||
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
#warning Thread Safety
|
||||
//
|
||||
// Note that any callback that provides streamed audio data (like streaming
|
||||
// microphone input) happens on a separate audio thread that should not be
|
||||
// blocked. When we feed audio data into any of the UI components we need to
|
||||
// explicity create a GCD block on the main thread to properly get the UI to
|
||||
// work.
|
||||
//
|
||||
- (void) microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
// Note that any callback that provides streamed audio data (like streaming microphone input) happens on a separate audio thread that should not be blocked. When we feed audio data into any of the UI components we need to explicity create a GCD block on the main thread to properly get the UI to work.
|
||||
- (void)microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
//
|
||||
// See the Thread Safety warning above, but in a nutshell these callbacks
|
||||
// happen on a separate audio thread. We wrap any UI updating in a GCD block
|
||||
// on the main thread to avoid blocking that audio flow.
|
||||
//
|
||||
// See the Thread Safety warning above, but in a nutshell these callbacks happen on a separate audio thread. We wrap any UI updating in a GCD block on the main thread to avoid blocking that audio flow.
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(),^{
|
||||
//
|
||||
// All the audio plot needs is the buffer data (float *) and the size.
|
||||
// Internally the audio plot will handle all the drawing related code,
|
||||
// history management, and freeing its own resources. Hence, one badass
|
||||
// line of code gets you a pretty plot :)
|
||||
//
|
||||
// All the audio plot needs is the buffer data (float*) and the size. Internally the audio plot will handle all the drawing related code, history management, and freeing its own resources. Hence, one badass line of code gets you a pretty plot :)
|
||||
NSInteger channel = [weakSelf.microphoneInputChannelPopUpButton indexOfSelectedItem];
|
||||
[weakSelf.audioPlot updateBuffer:buffer[channel] withBufferSize:bufferSize];
|
||||
});
|
||||
@@ -221,13 +207,8 @@
|
||||
|
||||
- (void)microphone:(EZMicrophone *)microphone hasAudioStreamBasicDescription:(AudioStreamBasicDescription)audioStreamBasicDescription
|
||||
{
|
||||
// The AudioStreamBasicDescription of the microphone stream. This is useful
|
||||
// when configuring the EZRecorder or telling another component what audio
|
||||
// format type to expect.
|
||||
|
||||
//
|
||||
// Here's a print function to allow you to inspect it a little easier.
|
||||
//
|
||||
// The AudioStreamBasicDescription of the microphone stream. This is useful when configuring the EZRecorder or telling another component what audio format type to expect.
|
||||
// Here's a print function to allow you to inspect it a little easier
|
||||
[EZAudioUtilities printASBD:audioStreamBasicDescription];
|
||||
}
|
||||
|
||||
@@ -238,10 +219,7 @@
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
//
|
||||
// Getting audio data as a buffer list that can be directly fed into
|
||||
// the EZRecorder or EZOutput. Say whattt...
|
||||
//
|
||||
// Getting audio data as a buffer list that can be directly fed into the EZRecorder or EZOutput. Say whattt...
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -249,43 +227,21 @@ withNumberOfChannels:(UInt32)numberOfChannels
|
||||
- (void)microphone:(EZMicrophone *)microphone
|
||||
changedDevice:(EZAudioDevice *)device
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
//
|
||||
// Set up the microphone input popup button's items to select
|
||||
// between different microphone inputs
|
||||
//
|
||||
[weakSelf reloadMicrophoneInputPopUpButtonMenu];
|
||||
[self reloadMicrophoneInputPopUpButtonMenu];
|
||||
|
||||
//
|
||||
// Set up the microphone input popup button's items to select
|
||||
// between different microphone input channels
|
||||
//
|
||||
[weakSelf reloadMicrophoneInputChannelPopUpButtonMenu];
|
||||
[self reloadMicrophoneInputChannelPopUpButtonMenu];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)microphone:(EZMicrophone *)microphone changedPlayingState:(BOOL)isPlaying
|
||||
{
|
||||
NSString *title = isPlaying ? @"Microphone On" : @"Microphone Off";
|
||||
[self setTitle:title forButton:self.microphoneSwitch];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - Utility
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)setTitle:(NSString *)title forButton:(NSButton *)button
|
||||
{
|
||||
NSDictionary *attributes = @{ NSForegroundColorAttributeName : [NSColor whiteColor] };
|
||||
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:title
|
||||
attributes:attributes];
|
||||
button.attributedTitle = attributedTitle;
|
||||
button.attributedAlternateTitle = attributedTitle;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
@end
|
||||
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="CoreGraphicsWaveformViewController">
|
||||
<connections>
|
||||
<outlet property="audioPlot" destination="wpL-Ou-GSb" id="OME-Hf-I27"/>
|
||||
<outlet property="microphoneInputChannelPopUpButton" destination="Yi6-fS-Cob" id="pLg-4c-klV"/>
|
||||
<outlet property="microphoneInputPopUpButton" destination="SjR-qx-mWV" id="NuN-SS-ESg"/>
|
||||
<outlet property="view" destination="wpL-Ou-GSb" id="oxJ-iT-SKO"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="wpL-Ou-GSb" customClass="EZAudioPlot">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<button translatesAutoresizingMaskIntoConstraints="NO" id="kAI-gs-c31">
|
||||
<rect key="frame" x="339" y="44" width="123" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="119" id="FP4-Wg-HAb"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="check" title="Microphone On" bezelStyle="regularSquare" imagePosition="right" state="on" inset="2" id="Aml-Gg-JmL">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleMicrophone:" target="-2" id="sFe-vk-GLb"/>
|
||||
</connections>
|
||||
</button>
|
||||
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HTa-6n-EPo">
|
||||
<rect key="frame" x="335" y="15" width="127" height="24"/>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="bLT-tl-mJ6">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Buffer" selected="YES"/>
|
||||
<segment label="Rolling" tag="1"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="changePlotType:" target="-2" id="JTN-f7-xiC"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SjR-qx-mWV" userLabel="microphoneInputPopUpButton">
|
||||
<rect key="frame" x="18" y="14" width="180" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="175" id="qhz-1c-cOR"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="4Kz-CU-9wA" id="Ifz-u8-4sz">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="si8-Yh-kZX">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="4Kz-CU-9wA"/>
|
||||
<menuItem title="Item 2" id="XbC-Uc-PrQ"/>
|
||||
<menuItem title="Item 3" id="aao-3c-s5T"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Yi6-fS-Cob" userLabel="microphoneInputChannelPopUpButton">
|
||||
<rect key="frame" x="204" y="14" width="79" height="26"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="74" id="w4n-SY-B3n"/>
|
||||
</constraints>
|
||||
<popUpButtonCell key="cell" type="push" title="1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="K3K-bf-PA5" id="mM3-bX-3dm">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="u3a-FE-6Wo">
|
||||
<items>
|
||||
<menuItem title="1" state="on" id="K3K-bf-PA5"/>
|
||||
<menuItem title="Item 2" id="gAP-8p-hIp"/>
|
||||
<menuItem title="Item 3" id="5ds-DC-X9S"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fi6-Uh-bvr">
|
||||
<rect key="frame" x="18" y="43" width="31" height="14"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Input" id="Png-Pk-fMc">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HVN-Im-3J1">
|
||||
<rect key="frame" x="204" y="43" width="48" height="14"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Channel" id="lkh-zp-WCY">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="SjR-qx-mWV" secondAttribute="bottom" constant="17" id="1kd-d1-9WR"/>
|
||||
<constraint firstAttribute="bottom" secondItem="HTa-6n-EPo" secondAttribute="bottom" constant="17" id="47V-Zg-MD0"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Yi6-fS-Cob" secondAttribute="bottom" constant="17" id="B2R-Tc-cz7"/>
|
||||
<constraint firstItem="Yi6-fS-Cob" firstAttribute="top" secondItem="HVN-Im-3J1" secondAttribute="bottom" constant="5" id="DoN-81-ICT"/>
|
||||
<constraint firstItem="HTa-6n-EPo" firstAttribute="top" secondItem="kAI-gs-c31" secondAttribute="bottom" constant="8" id="GLf-f7-seC"/>
|
||||
<constraint firstItem="Yi6-fS-Cob" firstAttribute="leading" secondItem="SjR-qx-mWV" secondAttribute="trailing" constant="11" id="Pqx-7E-osx"/>
|
||||
<constraint firstItem="Yi6-fS-Cob" firstAttribute="leading" secondItem="HVN-Im-3J1" secondAttribute="leading" id="Ux9-Kd-07J"/>
|
||||
<constraint firstItem="SjR-qx-mWV" firstAttribute="leading" secondItem="wpL-Ou-GSb" secondAttribute="leading" constant="20" id="b29-6j-MdI"/>
|
||||
<constraint firstAttribute="trailing" secondItem="kAI-gs-c31" secondAttribute="trailing" constant="20" id="bR5-ru-Lto"/>
|
||||
<constraint firstItem="fi6-Uh-bvr" firstAttribute="leading" secondItem="wpL-Ou-GSb" secondAttribute="leading" constant="20" id="gqn-qW-0CY"/>
|
||||
<constraint firstItem="HTa-6n-EPo" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Yi6-fS-Cob" secondAttribute="trailing" constant="11" id="qGD-Te-9IQ"/>
|
||||
<constraint firstItem="SjR-qx-mWV" firstAttribute="top" secondItem="fi6-Uh-bvr" secondAttribute="bottom" constant="5" id="qkS-wp-O0d"/>
|
||||
<constraint firstAttribute="trailing" secondItem="HTa-6n-EPo" secondAttribute="trailing" constant="20" id="rGZ-5W-ZDN"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="178" y="314"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -5,15 +5,15 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<string>com.sha.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
@@ -23,9 +23,9 @@
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016 Syed Haris Ali. All rights reserved.</string>
|
||||
<string>Copyright © 2013 Syed Haris Ali. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
@@ -1,63 +1,53 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_16x16.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_16x16@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_32x32.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_32x32@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_128x128.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_128x128@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_256x256.png",
|
||||
"size" : "256x256",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_256x256@2x.png",
|
||||
"size" : "256x256",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_512x512.png",
|
||||
"size" : "512x512",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_512x512@2x.png",
|
||||
"size" : "512x512",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
@@ -0,0 +1,29 @@
|
||||
{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\paperw9840\paperh8400
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
|
||||
|
||||
\f0\b\fs24 \cf0 Engineering:
|
||||
\b0 \
|
||||
Some people\
|
||||
\
|
||||
|
||||
\b Human Interface Design:
|
||||
\b0 \
|
||||
Some other people\
|
||||
\
|
||||
|
||||
\b Testing:
|
||||
\b0 \
|
||||
Hopefully not nobody\
|
||||
\
|
||||
|
||||
\b Documentation:
|
||||
\b0 \
|
||||
Whoever\
|
||||
\
|
||||
|
||||
\b With special thanks to:
|
||||
\b0 \
|
||||
Mom\
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// RecordFile
|
||||
// main.m
|
||||
// EZAudioCoreGraphicsWaveformExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Updated by Syed Haris Ali on 1/23/16.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -23,14 +22,10 @@
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
|
||||
@end
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
@@ -5,22 +5,18 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<string>com.sha.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// EZAudioCoreGraphicsWaveformExampleTests.m
|
||||
// EZAudioCoreGraphicsWaveformExampleTests
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface EZAudioCoreGraphicsWaveformExampleTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation EZAudioCoreGraphicsWaveformExampleTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testExample
|
||||
{
|
||||
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:EZAudioCoreGraphicsWaveformExample/EZAudioCoreGraphicsWaveformExample.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:EZAudioPlayFileExample/EZAudioPlayFileExample.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:EZAudioRecordExample/EZAudioRecordExample.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:EZAudioWaveformFromFileExample/EZAudioWaveformFromFileExample.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:EZAudioPassThroughExample/EZAudioPassThroughExample.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:EZAudioFFTExample/EZAudioFFTExample.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,640 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
6628E2C61B3A1CCE00020E56 /* AEFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2A41B3A1CCE00020E56 /* AEFloatConverter.m */; };
|
||||
6628E2C71B3A1CCE00020E56 /* EZAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2A61B3A1CCE00020E56 /* EZAudio.m */; };
|
||||
6628E2C81B3A1CCE00020E56 /* EZAudioDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2A81B3A1CCE00020E56 /* EZAudioDevice.m */; };
|
||||
6628E2C91B3A1CCE00020E56 /* EZAudioFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2AA1B3A1CCE00020E56 /* EZAudioFile.m */; };
|
||||
6628E2CA1B3A1CCE00020E56 /* EZAudioFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2AC1B3A1CCE00020E56 /* EZAudioFloatConverter.m */; };
|
||||
6628E2CB1B3A1CCE00020E56 /* EZAudioFloatData.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2AE1B3A1CCE00020E56 /* EZAudioFloatData.m */; };
|
||||
6628E2CC1B3A1CCE00020E56 /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2B01B3A1CCE00020E56 /* EZAudioPlayer.m */; };
|
||||
6628E2CD1B3A1CCE00020E56 /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2B21B3A1CCE00020E56 /* EZAudioPlot.m */; };
|
||||
6628E2CE1B3A1CCE00020E56 /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2B41B3A1CCE00020E56 /* EZAudioPlotGL.m */; };
|
||||
6628E2CF1B3A1CCE00020E56 /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2B61B3A1CCE00020E56 /* EZAudioPlotGLKViewController.m */; };
|
||||
6628E2D01B3A1CCE00020E56 /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2B81B3A1CCE00020E56 /* EZAudioUtilities.m */; };
|
||||
6628E2D11B3A1CCE00020E56 /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2BA1B3A1CCE00020E56 /* EZMicrophone.m */; };
|
||||
6628E2D21B3A1CCE00020E56 /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2BC1B3A1CCE00020E56 /* EZOutput.m */; };
|
||||
6628E2D31B3A1CCE00020E56 /* EZPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2BE1B3A1CCE00020E56 /* EZPlot.m */; };
|
||||
6628E2D41B3A1CCE00020E56 /* EZRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2C01B3A1CCE00020E56 /* EZRecorder.m */; };
|
||||
6628E2D51B3A1CCE00020E56 /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 6628E2C11B3A1CCE00020E56 /* TPCircularBuffer.c */; };
|
||||
6628E2D61B3A1CCE00020E56 /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 6628E2C41B3A1CCE00020E56 /* CHANGELOG */; };
|
||||
6628E2D71B3A1CCE00020E56 /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 6628E2C51B3A1CCE00020E56 /* VERSION */; };
|
||||
9417A8F71871492000D9D37B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A8F61871492000D9D37B /* Cocoa.framework */; };
|
||||
9417A9011871492000D9D37B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9417A8FF1871492000D9D37B /* InfoPlist.strings */; };
|
||||
9417A9031871492000D9D37B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9021871492000D9D37B /* main.m */; };
|
||||
9417A9071871492100D9D37B /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9051871492100D9D37B /* Credits.rtf */; };
|
||||
9417A90A1871492100D9D37B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9091871492100D9D37B /* AppDelegate.m */; };
|
||||
9417A90D1871492100D9D37B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9417A90B1871492100D9D37B /* MainMenu.xib */; };
|
||||
9417A90F1871492100D9D37B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9417A90E1871492100D9D37B /* Images.xcassets */; };
|
||||
9417A9161871492100D9D37B /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A9151871492100D9D37B /* XCTest.framework */; };
|
||||
9417A9171871492100D9D37B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A8F61871492000D9D37B /* Cocoa.framework */; };
|
||||
9417A91F1871492100D9D37B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9417A91D1871492100D9D37B /* InfoPlist.strings */; };
|
||||
9417A9211871492100D9D37B /* EZAudioFFTExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9201871492100D9D37B /* EZAudioFFTExampleTests.m */; };
|
||||
9417A954187149EA00D9D37B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A951187149EA00D9D37B /* AudioToolbox.framework */; };
|
||||
9417A955187149EA00D9D37B /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A952187149EA00D9D37B /* AudioUnit.framework */; };
|
||||
9417A956187149EA00D9D37B /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A953187149EA00D9D37B /* CoreAudio.framework */; };
|
||||
9417A959187149F000D9D37B /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A957187149F000D9D37B /* GLKit.framework */; };
|
||||
9417A95A187149F000D9D37B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A958187149F000D9D37B /* OpenGL.framework */; };
|
||||
9417A95C18714A1000D9D37B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A95B18714A1000D9D37B /* QuartzCore.framework */; };
|
||||
9417A95E18714A2A00D9D37B /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A95D18714A2A00D9D37B /* Accelerate.framework */; };
|
||||
9417A9D61872130200D9D37B /* FFTViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9417A9D41872130200D9D37B /* FFTViewController.m */; };
|
||||
9417A9D71872130200D9D37B /* FFTViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9417A9D51872130200D9D37B /* FFTViewController.xib */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
9417A9181871492100D9D37B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9417A8EB1871492000D9D37B /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 9417A8F21871492000D9D37B;
|
||||
remoteInfo = EZAudioFFTExample;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
6628E2A31B3A1CCE00020E56 /* AEFloatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEFloatConverter.h; sourceTree = "<group>"; };
|
||||
6628E2A41B3A1CCE00020E56 /* AEFloatConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AEFloatConverter.m; sourceTree = "<group>"; };
|
||||
6628E2A51B3A1CCE00020E56 /* EZAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudio.h; sourceTree = "<group>"; };
|
||||
6628E2A61B3A1CCE00020E56 /* EZAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudio.m; sourceTree = "<group>"; };
|
||||
6628E2A71B3A1CCE00020E56 /* EZAudioDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioDevice.h; sourceTree = "<group>"; };
|
||||
6628E2A81B3A1CCE00020E56 /* EZAudioDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioDevice.m; sourceTree = "<group>"; };
|
||||
6628E2A91B3A1CCE00020E56 /* EZAudioFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFile.h; sourceTree = "<group>"; };
|
||||
6628E2AA1B3A1CCE00020E56 /* EZAudioFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFile.m; sourceTree = "<group>"; };
|
||||
6628E2AB1B3A1CCE00020E56 /* EZAudioFloatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFloatConverter.h; sourceTree = "<group>"; };
|
||||
6628E2AC1B3A1CCE00020E56 /* EZAudioFloatConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFloatConverter.m; sourceTree = "<group>"; };
|
||||
6628E2AD1B3A1CCE00020E56 /* EZAudioFloatData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFloatData.h; sourceTree = "<group>"; };
|
||||
6628E2AE1B3A1CCE00020E56 /* EZAudioFloatData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFloatData.m; sourceTree = "<group>"; };
|
||||
6628E2AF1B3A1CCE00020E56 /* EZAudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlayer.h; sourceTree = "<group>"; };
|
||||
6628E2B01B3A1CCE00020E56 /* EZAudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlayer.m; sourceTree = "<group>"; };
|
||||
6628E2B11B3A1CCE00020E56 /* EZAudioPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlot.h; sourceTree = "<group>"; };
|
||||
6628E2B21B3A1CCE00020E56 /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
6628E2B31B3A1CCE00020E56 /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
6628E2B41B3A1CCE00020E56 /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
6628E2B51B3A1CCE00020E56 /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
6628E2B61B3A1CCE00020E56 /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
6628E2B71B3A1CCE00020E56 /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
6628E2B81B3A1CCE00020E56 /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
6628E2B91B3A1CCE00020E56 /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
6628E2BA1B3A1CCE00020E56 /* EZMicrophone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZMicrophone.m; sourceTree = "<group>"; };
|
||||
6628E2BB1B3A1CCE00020E56 /* EZOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZOutput.h; sourceTree = "<group>"; };
|
||||
6628E2BC1B3A1CCE00020E56 /* EZOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZOutput.m; sourceTree = "<group>"; };
|
||||
6628E2BD1B3A1CCE00020E56 /* EZPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZPlot.h; sourceTree = "<group>"; };
|
||||
6628E2BE1B3A1CCE00020E56 /* EZPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZPlot.m; sourceTree = "<group>"; };
|
||||
6628E2BF1B3A1CCE00020E56 /* EZRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZRecorder.h; sourceTree = "<group>"; };
|
||||
6628E2C01B3A1CCE00020E56 /* EZRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZRecorder.m; sourceTree = "<group>"; };
|
||||
6628E2C11B3A1CCE00020E56 /* TPCircularBuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = TPCircularBuffer.c; sourceTree = "<group>"; };
|
||||
6628E2C21B3A1CCE00020E56 /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
6628E2C41B3A1CCE00020E56 /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
6628E2C51B3A1CCE00020E56 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; 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; };
|
||||
9417A8FA1871492000D9D37B /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
9417A8FB1871492000D9D37B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
9417A8FE1871492000D9D37B /* EZAudioFFTExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioFFTExample-Info.plist"; sourceTree = "<group>"; };
|
||||
9417A9001871492000D9D37B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
9417A9021871492000D9D37B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
9417A9041871492000D9D37B /* EZAudioFFTExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "EZAudioFFTExample-Prefix.pch"; sourceTree = "<group>"; };
|
||||
9417A9061871492100D9D37B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
9417A9081871492100D9D37B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
9417A9091871492100D9D37B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
9417A90C1871492100D9D37B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
9417A90E1871492100D9D37B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
9417A9141871492100D9D37B /* EZAudioFFTExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EZAudioFFTExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9417A9151871492100D9D37B /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
9417A91C1871492100D9D37B /* EZAudioFFTExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioFFTExampleTests-Info.plist"; sourceTree = "<group>"; };
|
||||
9417A91E1871492100D9D37B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
9417A9201871492100D9D37B /* EZAudioFFTExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZAudioFFTExampleTests.m; sourceTree = "<group>"; };
|
||||
9417A951187149EA00D9D37B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
9417A952187149EA00D9D37B /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||
9417A953187149EA00D9D37B /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
||||
9417A957187149F000D9D37B /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
|
||||
9417A958187149F000D9D37B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||
9417A95B18714A1000D9D37B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
9417A95D18714A2A00D9D37B /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
9417A9D31872130200D9D37B /* FFTViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FFTViewController.h; sourceTree = "<group>"; };
|
||||
9417A9D41872130200D9D37B /* FFTViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FFTViewController.m; sourceTree = "<group>"; };
|
||||
9417A9D51872130200D9D37B /* FFTViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FFTViewController.xib; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
9417A8F01871492000D9D37B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A95E18714A2A00D9D37B /* Accelerate.framework in Frameworks */,
|
||||
9417A95C18714A1000D9D37B /* QuartzCore.framework in Frameworks */,
|
||||
9417A959187149F000D9D37B /* GLKit.framework in Frameworks */,
|
||||
9417A95A187149F000D9D37B /* OpenGL.framework in Frameworks */,
|
||||
9417A954187149EA00D9D37B /* AudioToolbox.framework in Frameworks */,
|
||||
9417A955187149EA00D9D37B /* AudioUnit.framework in Frameworks */,
|
||||
9417A956187149EA00D9D37B /* CoreAudio.framework in Frameworks */,
|
||||
9417A8F71871492000D9D37B /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9417A9111871492100D9D37B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9171871492100D9D37B /* Cocoa.framework in Frameworks */,
|
||||
9417A9161871492100D9D37B /* XCTest.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
6628E2A21B3A1CCE00020E56 /* EZAudio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6628E2A31B3A1CCE00020E56 /* AEFloatConverter.h */,
|
||||
6628E2A41B3A1CCE00020E56 /* AEFloatConverter.m */,
|
||||
6628E2A51B3A1CCE00020E56 /* EZAudio.h */,
|
||||
6628E2A61B3A1CCE00020E56 /* EZAudio.m */,
|
||||
6628E2A71B3A1CCE00020E56 /* EZAudioDevice.h */,
|
||||
6628E2A81B3A1CCE00020E56 /* EZAudioDevice.m */,
|
||||
6628E2A91B3A1CCE00020E56 /* EZAudioFile.h */,
|
||||
6628E2AA1B3A1CCE00020E56 /* EZAudioFile.m */,
|
||||
6628E2AB1B3A1CCE00020E56 /* EZAudioFloatConverter.h */,
|
||||
6628E2AC1B3A1CCE00020E56 /* EZAudioFloatConverter.m */,
|
||||
6628E2AD1B3A1CCE00020E56 /* EZAudioFloatData.h */,
|
||||
6628E2AE1B3A1CCE00020E56 /* EZAudioFloatData.m */,
|
||||
6628E2AF1B3A1CCE00020E56 /* EZAudioPlayer.h */,
|
||||
6628E2B01B3A1CCE00020E56 /* EZAudioPlayer.m */,
|
||||
6628E2B11B3A1CCE00020E56 /* EZAudioPlot.h */,
|
||||
6628E2B21B3A1CCE00020E56 /* EZAudioPlot.m */,
|
||||
6628E2B31B3A1CCE00020E56 /* EZAudioPlotGL.h */,
|
||||
6628E2B41B3A1CCE00020E56 /* EZAudioPlotGL.m */,
|
||||
6628E2B51B3A1CCE00020E56 /* EZAudioPlotGLKViewController.h */,
|
||||
6628E2B61B3A1CCE00020E56 /* EZAudioPlotGLKViewController.m */,
|
||||
6628E2B71B3A1CCE00020E56 /* EZAudioUtilities.h */,
|
||||
6628E2B81B3A1CCE00020E56 /* EZAudioUtilities.m */,
|
||||
6628E2B91B3A1CCE00020E56 /* EZMicrophone.h */,
|
||||
6628E2BA1B3A1CCE00020E56 /* EZMicrophone.m */,
|
||||
6628E2BB1B3A1CCE00020E56 /* EZOutput.h */,
|
||||
6628E2BC1B3A1CCE00020E56 /* EZOutput.m */,
|
||||
6628E2BD1B3A1CCE00020E56 /* EZPlot.h */,
|
||||
6628E2BE1B3A1CCE00020E56 /* EZPlot.m */,
|
||||
6628E2BF1B3A1CCE00020E56 /* EZRecorder.h */,
|
||||
6628E2C01B3A1CCE00020E56 /* EZRecorder.m */,
|
||||
6628E2C11B3A1CCE00020E56 /* TPCircularBuffer.c */,
|
||||
6628E2C21B3A1CCE00020E56 /* TPCircularBuffer.h */,
|
||||
6628E2C31B3A1CCE00020E56 /* VERSION */,
|
||||
);
|
||||
name = EZAudio;
|
||||
path = ../../../../EZAudio;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6628E2C31B3A1CCE00020E56 /* VERSION */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6628E2C41B3A1CCE00020E56 /* CHANGELOG */,
|
||||
6628E2C51B3A1CCE00020E56 /* VERSION */,
|
||||
);
|
||||
path = VERSION;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8EA1871492000D9D37B = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A8FC1871492000D9D37B /* EZAudioFFTExample */,
|
||||
9417A91A1871492100D9D37B /* EZAudioFFTExampleTests */,
|
||||
9417A8F51871492000D9D37B /* Frameworks */,
|
||||
9417A8F41871492000D9D37B /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8F41871492000D9D37B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A8F31871492000D9D37B /* EZAudioFFTExample.app */,
|
||||
9417A9141871492100D9D37B /* EZAudioFFTExampleTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8F51871492000D9D37B /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A95D18714A2A00D9D37B /* Accelerate.framework */,
|
||||
9417A95B18714A1000D9D37B /* QuartzCore.framework */,
|
||||
9417A957187149F000D9D37B /* GLKit.framework */,
|
||||
9417A958187149F000D9D37B /* OpenGL.framework */,
|
||||
9417A951187149EA00D9D37B /* AudioToolbox.framework */,
|
||||
9417A952187149EA00D9D37B /* AudioUnit.framework */,
|
||||
9417A953187149EA00D9D37B /* CoreAudio.framework */,
|
||||
9417A8F61871492000D9D37B /* Cocoa.framework */,
|
||||
9417A9151871492100D9D37B /* XCTest.framework */,
|
||||
9417A8F81871492000D9D37B /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8F81871492000D9D37B /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A8F91871492000D9D37B /* AppKit.framework */,
|
||||
9417A8FA1871492000D9D37B /* CoreData.framework */,
|
||||
9417A8FB1871492000D9D37B /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8FC1871492000D9D37B /* EZAudioFFTExample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6628E2A21B3A1CCE00020E56 /* EZAudio */,
|
||||
9417A9081871492100D9D37B /* AppDelegate.h */,
|
||||
9417A9091871492100D9D37B /* AppDelegate.m */,
|
||||
9417A9D31872130200D9D37B /* FFTViewController.h */,
|
||||
9417A9D41872130200D9D37B /* FFTViewController.m */,
|
||||
9417A9D51872130200D9D37B /* FFTViewController.xib */,
|
||||
9417A90B1871492100D9D37B /* MainMenu.xib */,
|
||||
9417A90E1871492100D9D37B /* Images.xcassets */,
|
||||
9417A8FD1871492000D9D37B /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioFFTExample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A8FD1871492000D9D37B /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A8FE1871492000D9D37B /* EZAudioFFTExample-Info.plist */,
|
||||
9417A8FF1871492000D9D37B /* InfoPlist.strings */,
|
||||
9417A9021871492000D9D37B /* main.m */,
|
||||
9417A9041871492000D9D37B /* EZAudioFFTExample-Prefix.pch */,
|
||||
9417A9051871492100D9D37B /* Credits.rtf */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A91A1871492100D9D37B /* EZAudioFFTExampleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A9201871492100D9D37B /* EZAudioFFTExampleTests.m */,
|
||||
9417A91B1871492100D9D37B /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioFFTExampleTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A91B1871492100D9D37B /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9417A91C1871492100D9D37B /* EZAudioFFTExampleTests-Info.plist */,
|
||||
9417A91D1871492100D9D37B /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
9417A8F21871492000D9D37B /* EZAudioFFTExample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9417A9241871492100D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExample" */;
|
||||
buildPhases = (
|
||||
9417A8EF1871492000D9D37B /* Sources */,
|
||||
9417A8F01871492000D9D37B /* Frameworks */,
|
||||
9417A8F11871492000D9D37B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = EZAudioFFTExample;
|
||||
productName = EZAudioFFTExample;
|
||||
productReference = 9417A8F31871492000D9D37B /* EZAudioFFTExample.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
9417A9131871492100D9D37B /* EZAudioFFTExampleTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9417A9271871492100D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExampleTests" */;
|
||||
buildPhases = (
|
||||
9417A9101871492100D9D37B /* Sources */,
|
||||
9417A9111871492100D9D37B /* Frameworks */,
|
||||
9417A9121871492100D9D37B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
9417A9191871492100D9D37B /* PBXTargetDependency */,
|
||||
);
|
||||
name = EZAudioFFTExampleTests;
|
||||
productName = EZAudioFFTExampleTests;
|
||||
productReference = 9417A9141871492100D9D37B /* EZAudioFFTExampleTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
9417A8EB1871492000D9D37B /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Syed Haris Ali";
|
||||
TargetAttributes = {
|
||||
9417A9131871492100D9D37B = {
|
||||
TestTargetID = 9417A8F21871492000D9D37B;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 9417A8EE1871492000D9D37B /* Build configuration list for PBXProject "EZAudioFFTExample" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 9417A8EA1871492000D9D37B;
|
||||
productRefGroup = 9417A8F41871492000D9D37B /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
9417A8F21871492000D9D37B /* EZAudioFFTExample */,
|
||||
9417A9131871492100D9D37B /* EZAudioFFTExampleTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
9417A8F11871492000D9D37B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9011871492000D9D37B /* InfoPlist.strings in Resources */,
|
||||
6628E2D71B3A1CCE00020E56 /* VERSION in Resources */,
|
||||
9417A9D71872130200D9D37B /* FFTViewController.xib in Resources */,
|
||||
9417A90F1871492100D9D37B /* Images.xcassets in Resources */,
|
||||
9417A9071871492100D9D37B /* Credits.rtf in Resources */,
|
||||
9417A90D1871492100D9D37B /* MainMenu.xib in Resources */,
|
||||
6628E2D61B3A1CCE00020E56 /* CHANGELOG in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9417A9121871492100D9D37B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A91F1871492100D9D37B /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
9417A8EF1871492000D9D37B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6628E2D41B3A1CCE00020E56 /* EZRecorder.m in Sources */,
|
||||
9417A9D61872130200D9D37B /* FFTViewController.m in Sources */,
|
||||
6628E2CA1B3A1CCE00020E56 /* EZAudioFloatConverter.m in Sources */,
|
||||
6628E2CB1B3A1CCE00020E56 /* EZAudioFloatData.m in Sources */,
|
||||
6628E2C61B3A1CCE00020E56 /* AEFloatConverter.m in Sources */,
|
||||
6628E2C91B3A1CCE00020E56 /* EZAudioFile.m in Sources */,
|
||||
6628E2D21B3A1CCE00020E56 /* EZOutput.m in Sources */,
|
||||
6628E2CE1B3A1CCE00020E56 /* EZAudioPlotGL.m in Sources */,
|
||||
6628E2D51B3A1CCE00020E56 /* TPCircularBuffer.c in Sources */,
|
||||
6628E2CD1B3A1CCE00020E56 /* EZAudioPlot.m in Sources */,
|
||||
9417A90A1871492100D9D37B /* AppDelegate.m in Sources */,
|
||||
6628E2D11B3A1CCE00020E56 /* EZMicrophone.m in Sources */,
|
||||
6628E2CC1B3A1CCE00020E56 /* EZAudioPlayer.m in Sources */,
|
||||
6628E2C81B3A1CCE00020E56 /* EZAudioDevice.m in Sources */,
|
||||
9417A9031871492000D9D37B /* main.m in Sources */,
|
||||
6628E2D31B3A1CCE00020E56 /* EZPlot.m in Sources */,
|
||||
6628E2C71B3A1CCE00020E56 /* EZAudio.m in Sources */,
|
||||
6628E2D01B3A1CCE00020E56 /* EZAudioUtilities.m in Sources */,
|
||||
6628E2CF1B3A1CCE00020E56 /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9417A9101871492100D9D37B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9417A9211871492100D9D37B /* EZAudioFFTExampleTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
9417A9191871492100D9D37B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 9417A8F21871492000D9D37B /* EZAudioFFTExample */;
|
||||
targetProxy = 9417A9181871492100D9D37B /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
9417A8FF1871492000D9D37B /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A9001871492000D9D37B /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A9051871492100D9D37B /* Credits.rtf */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A9061871492100D9D37B /* en */,
|
||||
);
|
||||
name = Credits.rtf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A90B1871492100D9D37B /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A90C1871492100D9D37B /* Base */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9417A91D1871492100D9D37B /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
9417A91E1871492100D9D37B /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
9417A9221871492100D9D37B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9417A9231871492100D9D37B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9417A9251871492100D9D37B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExample/EZAudioFFTExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9417A9261871492100D9D37B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExample/EZAudioFFTExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9417A9281871492100D9D37B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioFFTExample.app/Contents/MacOS/EZAudioFFTExample";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "EZAudioFFTExampleTests/EZAudioFFTExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9417A9291871492100D9D37B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioFFTExample.app/Contents/MacOS/EZAudioFFTExample";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioFFTExample/EZAudioFFTExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioFFTExampleTests/EZAudioFFTExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
9417A8EE1871492000D9D37B /* Build configuration list for PBXProject "EZAudioFFTExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9417A9221871492100D9D37B /* Debug */,
|
||||
9417A9231871492100D9D37B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9417A9241871492100D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9417A9251871492100D9D37B /* Debug */,
|
||||
9417A9261871492100D9D37B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9417A9271871492100D9D37B /* Build configuration list for PBXNativeTarget "EZAudioFFTExampleTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9417A9281871492100D9D37B /* Debug */,
|
||||
9417A9291871492100D9D37B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 9417A8EB1871492000D9D37B /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "FFTViewController.h"
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
|
||||
/**
|
||||
The FFTViewController
|
||||
*/
|
||||
@property (nonatomic,strong) FFTViewController *fftViewController;
|
||||
|
||||
@end
|
||||
@@ -1,9 +1,8 @@
|
||||
//
|
||||
// main.m
|
||||
// CoreGraphicsWaveform
|
||||
// AppDelegate.m
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Updated by Syed Haris Ali on 1/23/16.
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -23,13 +22,22 @@
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
@implementation AppDelegate
|
||||
@synthesize fftViewController;
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
// Swap in our view controller in the window's content view
|
||||
self.fftViewController = [[FFTViewController alloc] init];
|
||||
// Resize view controller to content view's current size
|
||||
self.fftViewController.view.frame = [self.window.contentView frame];
|
||||
// Add resizing flags to make the view controller resize with the window
|
||||
self.fftViewController.view.autoresizingMask = (NSViewWidthSizable|NSViewHeightSizable);
|
||||
// Add in the core graphics view controller as subview
|
||||
[self.window.contentView addSubview:self.fftViewController.view];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -5,15 +5,15 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<string>com.sha.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
@@ -23,9 +23,9 @@
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016 Syed Haris Ali. All rights reserved.</string>
|
||||
<string>Copyright © 2013 Syed Haris Ali. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// FFTViewController.h
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
/**
|
||||
EZAudio
|
||||
*/
|
||||
#import "EZAudio.h"
|
||||
|
||||
/**
|
||||
Accelerate
|
||||
*/
|
||||
#import <Accelerate/Accelerate.h>
|
||||
|
||||
/**
|
||||
The FFTViewController demonstrates how to use the Accelerate framework to calculate the real-time FFT of audio data provided by an EZAudioMicrophone.
|
||||
*/
|
||||
@interface FFTViewController : NSViewController <EZMicrophoneDelegate>
|
||||
|
||||
#pragma mark - Components
|
||||
/**
|
||||
EZAudioPlot for frequency plot
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlotGL *audioPlotFreq;
|
||||
|
||||
/**
|
||||
EZAudioPlot for time plot
|
||||
*/
|
||||
@property (nonatomic,weak) IBOutlet EZAudioPlot *audioPlotTime;
|
||||
|
||||
/**
|
||||
Microphone
|
||||
*/
|
||||
@property (nonatomic,strong) EZMicrophone *microphone;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,204 @@
|
||||
//
|
||||
// FFTViewController.m
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/30/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "FFTViewController.h"
|
||||
|
||||
@interface FFTViewController ()
|
||||
@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
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
//
|
||||
// Setup time domain audio plot
|
||||
//
|
||||
self.audioPlotTime.backgroundColor = [NSColor colorWithCalibratedRed: 0.569 green: 0.82 blue: 0.478 alpha: 1];
|
||||
self.audioPlotTime.color = [NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
self.audioPlotTime.shouldFill = YES;
|
||||
self.audioPlotTime.shouldMirror = YES;
|
||||
self.audioPlotTime.plotType = EZPlotTypeRolling;
|
||||
|
||||
//
|
||||
// Setup frequency domain audio plot
|
||||
//
|
||||
self.audioPlotFreq.backgroundColor = [NSColor colorWithCalibratedRed: 0.984 green: 0.471 blue: 0.525 alpha: 1];
|
||||
self.audioPlotFreq.color = [NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0];
|
||||
self.audioPlotFreq.shouldFill = YES;
|
||||
self.audioPlotFreq.plotType = EZPlotTypeBuffer;
|
||||
|
||||
//
|
||||
// Create an instance of the microphone and tell it to use this view controller instance as the delegate
|
||||
//
|
||||
self.microphone = [EZMicrophone microphoneWithDelegate:self
|
||||
startsImmediately:YES];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - FFT
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Adapted from http://batmobile.blogs.ilrt.org/fourier-transforms-on-an-iphone/
|
||||
*/
|
||||
- (void)createFFTWithBufferSize:(float)bufferSize
|
||||
withAudioData:(float *)data
|
||||
{
|
||||
//
|
||||
// Setup the length
|
||||
//
|
||||
self.log2n = log2f(bufferSize);
|
||||
|
||||
//
|
||||
// Calculate the weights array. This is a one-off operation.
|
||||
//
|
||||
_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];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma mark - EZMicrophoneDelegate
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
-(void) microphone:(EZMicrophone *)microphone
|
||||
hasAudioReceived:(float **)buffer
|
||||
withBufferSize:(UInt32)bufferSize
|
||||
withNumberOfChannels:(UInt32)numberOfChannels
|
||||
{
|
||||
__weak typeof (self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
//
|
||||
// Update time domain plot
|
||||
//
|
||||
[weakSelf.audioPlotTime updateBuffer:buffer[0]
|
||||
withBufferSize:bufferSize];
|
||||
|
||||
//
|
||||
// Lazily perform the FFT setup
|
||||
//
|
||||
if (!weakSelf.isFFTSetup)
|
||||
{
|
||||
[weakSelf createFFTWithBufferSize:bufferSize withAudioData:buffer[0]];
|
||||
weakSelf.isFFTSetup = YES;
|
||||
}
|
||||
|
||||
//
|
||||
// Perform FFT and update FFT graph
|
||||
//
|
||||
[weakSelf updateFFTWithBufferSize:bufferSize
|
||||
withAudioData:buffer[0]];
|
||||
});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1070" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="FFTViewController">
|
||||
<connections>
|
||||
<outlet property="audioPlotFreq" destination="4V2-1I-w64" id="SkA-7R-4V8"/>
|
||||
<outlet property="audioPlotTime" destination="Zcc-CT-67u" id="lE0-d7-KUs"/>
|
||||
<outlet property="view" destination="1" id="2"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<splitView dividerStyle="thin" translatesAutoresizingMaskIntoConstraints="NO" id="78b-rz-Bpl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
|
||||
<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="EZAudioPlotGL">
|
||||
<rect key="frame" x="0.0" y="133" width="480" height="139"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
<holdingPriorities>
|
||||
<real value="250"/>
|
||||
<real value="250"/>
|
||||
</holdingPriorities>
|
||||
</splitView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="78b-rz-Bpl" secondAttribute="bottom" id="CZL-aU-xpy"/>
|
||||
<constraint firstAttribute="trailing" secondItem="78b-rz-Bpl" secondAttribute="trailing" id="eXt-EL-upz"/>
|
||||
<constraint firstItem="78b-rz-Bpl" firstAttribute="top" secondItem="1" secondAttribute="top" id="lFP-vc-nHC"/>
|
||||
<constraint firstItem="78b-rz-Bpl" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="lWl-1T-nHB"/>
|
||||
</constraints>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,63 +1,53 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_16x16.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_16x16@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_32x32.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_32x32@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_128x128.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_128x128@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_256x256.png",
|
||||
"size" : "256x256",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_256x256@2x.png",
|
||||
"size" : "256x256",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_512x512.png",
|
||||
"size" : "512x512",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "icon_512x512@2x.png",
|
||||
"size" : "512x512",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
@@ -0,0 +1,29 @@
|
||||
{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\paperw9840\paperh8400
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
|
||||
|
||||
\f0\b\fs24 \cf0 Engineering:
|
||||
\b0 \
|
||||
Some people\
|
||||
\
|
||||
|
||||
\b Human Interface Design:
|
||||
\b0 \
|
||||
Some other people\
|
||||
\
|
||||
|
||||
\b Testing:
|
||||
\b0 \
|
||||
Hopefully not nobody\
|
||||
\
|
||||
|
||||
\b Documentation:
|
||||
\b0 \
|
||||
Whoever\
|
||||
\
|
||||
|
||||
\b With special thanks to:
|
||||
\b0 \
|
||||
Mom\
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// main.m
|
||||
// EZAudioFFTExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/29/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.sha.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// EZAudioFFTExampleTests.m
|
||||
// EZAudioFFTExampleTests
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/29/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface EZAudioFFTExampleTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation EZAudioFFTExampleTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testExample
|
||||
{
|
||||
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -0,0 +1,636 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
665957541B38B2B4003E97A1 /* AEFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 665957321B38B2B4003E97A1 /* AEFloatConverter.m */; };
|
||||
665957551B38B2B4003E97A1 /* EZAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 665957341B38B2B4003E97A1 /* EZAudio.m */; };
|
||||
665957561B38B2B4003E97A1 /* EZAudioDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 665957361B38B2B4003E97A1 /* EZAudioDevice.m */; };
|
||||
665957571B38B2B4003E97A1 /* EZAudioFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 665957381B38B2B4003E97A1 /* EZAudioFile.m */; };
|
||||
665957581B38B2B4003E97A1 /* EZAudioFloatConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6659573A1B38B2B4003E97A1 /* EZAudioFloatConverter.m */; };
|
||||
665957591B38B2B4003E97A1 /* EZAudioFloatData.m in Sources */ = {isa = PBXBuildFile; fileRef = 6659573C1B38B2B4003E97A1 /* EZAudioFloatData.m */; };
|
||||
6659575A1B38B2B4003E97A1 /* EZAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6659573E1B38B2B4003E97A1 /* EZAudioPlayer.m */; };
|
||||
6659575B1B38B2B4003E97A1 /* EZAudioPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 665957401B38B2B4003E97A1 /* EZAudioPlot.m */; };
|
||||
6659575C1B38B2B4003E97A1 /* EZAudioPlotGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 665957421B38B2B4003E97A1 /* EZAudioPlotGL.m */; };
|
||||
6659575D1B38B2B4003E97A1 /* EZAudioPlotGLKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 665957441B38B2B4003E97A1 /* EZAudioPlotGLKViewController.m */; };
|
||||
6659575E1B38B2B4003E97A1 /* EZAudioUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 665957461B38B2B4003E97A1 /* EZAudioUtilities.m */; };
|
||||
6659575F1B38B2B4003E97A1 /* EZMicrophone.m in Sources */ = {isa = PBXBuildFile; fileRef = 665957481B38B2B4003E97A1 /* EZMicrophone.m */; };
|
||||
665957601B38B2B4003E97A1 /* EZOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 6659574A1B38B2B4003E97A1 /* EZOutput.m */; };
|
||||
665957611B38B2B4003E97A1 /* EZPlot.m in Sources */ = {isa = PBXBuildFile; fileRef = 6659574C1B38B2B4003E97A1 /* EZPlot.m */; };
|
||||
665957621B38B2B4003E97A1 /* EZRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 6659574E1B38B2B4003E97A1 /* EZRecorder.m */; };
|
||||
665957631B38B2B4003E97A1 /* TPCircularBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 6659574F1B38B2B4003E97A1 /* TPCircularBuffer.c */; };
|
||||
665957641B38B2B4003E97A1 /* CHANGELOG in Resources */ = {isa = PBXBuildFile; fileRef = 665957521B38B2B4003E97A1 /* CHANGELOG */; };
|
||||
665957651B38B2B4003E97A1 /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 665957531B38B2B4003E97A1 /* VERSION */; };
|
||||
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 */; };
|
||||
94056DA7185BB0BC00EB94BA /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 94056DA5185BB0BC00EB94BA /* Credits.rtf */; };
|
||||
94056DAA185BB0BC00EB94BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 94056DA9185BB0BC00EB94BA /* AppDelegate.m */; };
|
||||
94056DAD185BB0BC00EB94BA /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 94056DAB185BB0BC00EB94BA /* MainMenu.xib */; };
|
||||
94056DAF185BB0BC00EB94BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 94056DAE185BB0BC00EB94BA /* Images.xcassets */; };
|
||||
94056DB6185BB0BC00EB94BA /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056DB5185BB0BC00EB94BA /* XCTest.framework */; };
|
||||
94056DB7185BB0BC00EB94BA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056D96185BB0BC00EB94BA /* Cocoa.framework */; };
|
||||
94056DBF185BB0BC00EB94BA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 94056DBD185BB0BC00EB94BA /* InfoPlist.strings */; };
|
||||
94056DC1185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 94056DC0185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests.m */; };
|
||||
94056DCD185BB0D600EB94BA /* OpenGLWaveformViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 94056DCB185BB0D600EB94BA /* OpenGLWaveformViewController.m */; };
|
||||
94056DCE185BB0D600EB94BA /* OpenGLWaveformViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 94056DCC185BB0D600EB94BA /* OpenGLWaveformViewController.xib */; };
|
||||
94056DD0185BB0E200EB94BA /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056DCF185BB0E200EB94BA /* GLKit.framework */; };
|
||||
94056DD2185BB0E900EB94BA /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056DD1185BB0E900EB94BA /* OpenGL.framework */; };
|
||||
94056DD4185BB0EF00EB94BA /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056DD3185BB0EF00EB94BA /* QuartzCore.framework */; };
|
||||
94056DD8185BB0F400EB94BA /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056DD5185BB0F400EB94BA /* AudioToolbox.framework */; };
|
||||
94056DD9185BB0F400EB94BA /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056DD6185BB0F400EB94BA /* AudioUnit.framework */; };
|
||||
94056DDA185BB0F400EB94BA /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94056DD7185BB0F400EB94BA /* CoreAudio.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
94056DB8185BB0BC00EB94BA /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 94056D8B185BB0BC00EB94BA /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 94056D92185BB0BC00EB94BA;
|
||||
remoteInfo = EZAudioOpenGLWaveformExample;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
665957311B38B2B4003E97A1 /* AEFloatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEFloatConverter.h; sourceTree = "<group>"; };
|
||||
665957321B38B2B4003E97A1 /* AEFloatConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AEFloatConverter.m; sourceTree = "<group>"; };
|
||||
665957331B38B2B4003E97A1 /* EZAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudio.h; sourceTree = "<group>"; };
|
||||
665957341B38B2B4003E97A1 /* EZAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudio.m; sourceTree = "<group>"; };
|
||||
665957351B38B2B4003E97A1 /* EZAudioDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioDevice.h; sourceTree = "<group>"; };
|
||||
665957361B38B2B4003E97A1 /* EZAudioDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioDevice.m; sourceTree = "<group>"; };
|
||||
665957371B38B2B4003E97A1 /* EZAudioFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFile.h; sourceTree = "<group>"; };
|
||||
665957381B38B2B4003E97A1 /* EZAudioFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFile.m; sourceTree = "<group>"; };
|
||||
665957391B38B2B4003E97A1 /* EZAudioFloatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFloatConverter.h; sourceTree = "<group>"; };
|
||||
6659573A1B38B2B4003E97A1 /* EZAudioFloatConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFloatConverter.m; sourceTree = "<group>"; };
|
||||
6659573B1B38B2B4003E97A1 /* EZAudioFloatData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioFloatData.h; sourceTree = "<group>"; };
|
||||
6659573C1B38B2B4003E97A1 /* EZAudioFloatData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioFloatData.m; sourceTree = "<group>"; };
|
||||
6659573D1B38B2B4003E97A1 /* EZAudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlayer.h; sourceTree = "<group>"; };
|
||||
6659573E1B38B2B4003E97A1 /* EZAudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlayer.m; sourceTree = "<group>"; };
|
||||
6659573F1B38B2B4003E97A1 /* EZAudioPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlot.h; sourceTree = "<group>"; };
|
||||
665957401B38B2B4003E97A1 /* EZAudioPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlot.m; sourceTree = "<group>"; };
|
||||
665957411B38B2B4003E97A1 /* EZAudioPlotGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGL.h; sourceTree = "<group>"; };
|
||||
665957421B38B2B4003E97A1 /* EZAudioPlotGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGL.m; sourceTree = "<group>"; };
|
||||
665957431B38B2B4003E97A1 /* EZAudioPlotGLKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioPlotGLKViewController.h; sourceTree = "<group>"; };
|
||||
665957441B38B2B4003E97A1 /* EZAudioPlotGLKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioPlotGLKViewController.m; sourceTree = "<group>"; };
|
||||
665957451B38B2B4003E97A1 /* EZAudioUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZAudioUtilities.h; sourceTree = "<group>"; };
|
||||
665957461B38B2B4003E97A1 /* EZAudioUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZAudioUtilities.m; sourceTree = "<group>"; };
|
||||
665957471B38B2B4003E97A1 /* EZMicrophone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZMicrophone.h; sourceTree = "<group>"; };
|
||||
665957481B38B2B4003E97A1 /* EZMicrophone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZMicrophone.m; sourceTree = "<group>"; };
|
||||
665957491B38B2B4003E97A1 /* EZOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZOutput.h; sourceTree = "<group>"; };
|
||||
6659574A1B38B2B4003E97A1 /* EZOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZOutput.m; sourceTree = "<group>"; };
|
||||
6659574B1B38B2B4003E97A1 /* EZPlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZPlot.h; sourceTree = "<group>"; };
|
||||
6659574C1B38B2B4003E97A1 /* EZPlot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZPlot.m; sourceTree = "<group>"; };
|
||||
6659574D1B38B2B4003E97A1 /* EZRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZRecorder.h; sourceTree = "<group>"; };
|
||||
6659574E1B38B2B4003E97A1 /* EZRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZRecorder.m; sourceTree = "<group>"; };
|
||||
6659574F1B38B2B4003E97A1 /* TPCircularBuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = TPCircularBuffer.c; sourceTree = "<group>"; };
|
||||
665957501B38B2B4003E97A1 /* TPCircularBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPCircularBuffer.h; sourceTree = "<group>"; };
|
||||
665957521B38B2B4003E97A1 /* CHANGELOG */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG; sourceTree = "<group>"; };
|
||||
665957531B38B2B4003E97A1 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = "<group>"; };
|
||||
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; };
|
||||
94056D9A185BB0BC00EB94BA /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
94056D9B185BB0BC00EB94BA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
94056D9E185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioOpenGLWaveformExample-Info.plist"; sourceTree = "<group>"; };
|
||||
94056DA0185BB0BC00EB94BA /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
94056DA2185BB0BC00EB94BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = main.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
94056DA4185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "EZAudioOpenGLWaveformExample-Prefix.pch"; sourceTree = "<group>"; };
|
||||
94056DA6185BB0BC00EB94BA /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
94056DA8185BB0BC00EB94BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AppDelegate.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
94056DA9185BB0BC00EB94BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppDelegate.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
94056DAC185BB0BC00EB94BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
94056DAE185BB0BC00EB94BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
94056DB4185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EZAudioOpenGLWaveformExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
94056DB5185BB0BC00EB94BA /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
94056DBC185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "EZAudioOpenGLWaveformExampleTests-Info.plist"; sourceTree = "<group>"; };
|
||||
94056DBE185BB0BC00EB94BA /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
94056DC0185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = EZAudioOpenGLWaveformExampleTests.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
94056DCA185BB0D600EB94BA /* OpenGLWaveformViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = OpenGLWaveformViewController.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
94056DCB185BB0D600EB94BA /* OpenGLWaveformViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = OpenGLWaveformViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
94056DCC185BB0D600EB94BA /* OpenGLWaveformViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OpenGLWaveformViewController.xib; sourceTree = "<group>"; };
|
||||
94056DCF185BB0E200EB94BA /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
|
||||
94056DD1185BB0E900EB94BA /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||
94056DD3185BB0EF00EB94BA /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
94056DD5185BB0F400EB94BA /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
94056DD6185BB0F400EB94BA /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||
94056DD7185BB0F400EB94BA /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
94056D90185BB0BC00EB94BA /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
94056DD8185BB0F400EB94BA /* AudioToolbox.framework in Frameworks */,
|
||||
94056DD9185BB0F400EB94BA /* AudioUnit.framework in Frameworks */,
|
||||
94056DDA185BB0F400EB94BA /* CoreAudio.framework in Frameworks */,
|
||||
94056DD4185BB0EF00EB94BA /* QuartzCore.framework in Frameworks */,
|
||||
94056DD2185BB0E900EB94BA /* OpenGL.framework in Frameworks */,
|
||||
94056DD0185BB0E200EB94BA /* GLKit.framework in Frameworks */,
|
||||
94056D97185BB0BC00EB94BA /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
94056DB1185BB0BC00EB94BA /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
94056DB7185BB0BC00EB94BA /* Cocoa.framework in Frameworks */,
|
||||
94056DB6185BB0BC00EB94BA /* XCTest.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
665957301B38B2B4003E97A1 /* EZAudio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
665957311B38B2B4003E97A1 /* AEFloatConverter.h */,
|
||||
665957321B38B2B4003E97A1 /* AEFloatConverter.m */,
|
||||
665957331B38B2B4003E97A1 /* EZAudio.h */,
|
||||
665957341B38B2B4003E97A1 /* EZAudio.m */,
|
||||
665957351B38B2B4003E97A1 /* EZAudioDevice.h */,
|
||||
665957361B38B2B4003E97A1 /* EZAudioDevice.m */,
|
||||
665957371B38B2B4003E97A1 /* EZAudioFile.h */,
|
||||
665957381B38B2B4003E97A1 /* EZAudioFile.m */,
|
||||
665957391B38B2B4003E97A1 /* EZAudioFloatConverter.h */,
|
||||
6659573A1B38B2B4003E97A1 /* EZAudioFloatConverter.m */,
|
||||
6659573B1B38B2B4003E97A1 /* EZAudioFloatData.h */,
|
||||
6659573C1B38B2B4003E97A1 /* EZAudioFloatData.m */,
|
||||
6659573D1B38B2B4003E97A1 /* EZAudioPlayer.h */,
|
||||
6659573E1B38B2B4003E97A1 /* EZAudioPlayer.m */,
|
||||
6659573F1B38B2B4003E97A1 /* EZAudioPlot.h */,
|
||||
665957401B38B2B4003E97A1 /* EZAudioPlot.m */,
|
||||
665957411B38B2B4003E97A1 /* EZAudioPlotGL.h */,
|
||||
665957421B38B2B4003E97A1 /* EZAudioPlotGL.m */,
|
||||
665957431B38B2B4003E97A1 /* EZAudioPlotGLKViewController.h */,
|
||||
665957441B38B2B4003E97A1 /* EZAudioPlotGLKViewController.m */,
|
||||
665957451B38B2B4003E97A1 /* EZAudioUtilities.h */,
|
||||
665957461B38B2B4003E97A1 /* EZAudioUtilities.m */,
|
||||
665957471B38B2B4003E97A1 /* EZMicrophone.h */,
|
||||
665957481B38B2B4003E97A1 /* EZMicrophone.m */,
|
||||
665957491B38B2B4003E97A1 /* EZOutput.h */,
|
||||
6659574A1B38B2B4003E97A1 /* EZOutput.m */,
|
||||
6659574B1B38B2B4003E97A1 /* EZPlot.h */,
|
||||
6659574C1B38B2B4003E97A1 /* EZPlot.m */,
|
||||
6659574D1B38B2B4003E97A1 /* EZRecorder.h */,
|
||||
6659574E1B38B2B4003E97A1 /* EZRecorder.m */,
|
||||
6659574F1B38B2B4003E97A1 /* TPCircularBuffer.c */,
|
||||
665957501B38B2B4003E97A1 /* TPCircularBuffer.h */,
|
||||
665957511B38B2B4003E97A1 /* VERSION */,
|
||||
);
|
||||
name = EZAudio;
|
||||
path = ../../../../EZAudio;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
665957511B38B2B4003E97A1 /* VERSION */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
665957521B38B2B4003E97A1 /* CHANGELOG */,
|
||||
665957531B38B2B4003E97A1 /* VERSION */,
|
||||
);
|
||||
path = VERSION;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056D8A185BB0BC00EB94BA = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94056D9C185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample */,
|
||||
94056DBA185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests */,
|
||||
94056D95185BB0BC00EB94BA /* Frameworks */,
|
||||
94056D94185BB0BC00EB94BA /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056D94185BB0BC00EB94BA /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94056D93185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample.app */,
|
||||
94056DB4185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056D95185BB0BC00EB94BA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94056DD5185BB0F400EB94BA /* AudioToolbox.framework */,
|
||||
94056DD6185BB0F400EB94BA /* AudioUnit.framework */,
|
||||
94056DD7185BB0F400EB94BA /* CoreAudio.framework */,
|
||||
94056DD3185BB0EF00EB94BA /* QuartzCore.framework */,
|
||||
94056DD1185BB0E900EB94BA /* OpenGL.framework */,
|
||||
94056DCF185BB0E200EB94BA /* GLKit.framework */,
|
||||
94056D96185BB0BC00EB94BA /* Cocoa.framework */,
|
||||
94056DB5185BB0BC00EB94BA /* XCTest.framework */,
|
||||
94056D98185BB0BC00EB94BA /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056D98185BB0BC00EB94BA /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94056D99185BB0BC00EB94BA /* AppKit.framework */,
|
||||
94056D9A185BB0BC00EB94BA /* CoreData.framework */,
|
||||
94056D9B185BB0BC00EB94BA /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056D9C185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
665957301B38B2B4003E97A1 /* EZAudio */,
|
||||
94056DA8185BB0BC00EB94BA /* AppDelegate.h */,
|
||||
94056DA9185BB0BC00EB94BA /* AppDelegate.m */,
|
||||
94056DCA185BB0D600EB94BA /* OpenGLWaveformViewController.h */,
|
||||
94056DCB185BB0D600EB94BA /* OpenGLWaveformViewController.m */,
|
||||
94056DCC185BB0D600EB94BA /* OpenGLWaveformViewController.xib */,
|
||||
94056DAB185BB0BC00EB94BA /* MainMenu.xib */,
|
||||
94056DAE185BB0BC00EB94BA /* Images.xcassets */,
|
||||
94056D9D185BB0BC00EB94BA /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioOpenGLWaveformExample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056D9D185BB0BC00EB94BA /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94056D9E185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample-Info.plist */,
|
||||
94056D9F185BB0BC00EB94BA /* InfoPlist.strings */,
|
||||
94056DA2185BB0BC00EB94BA /* main.m */,
|
||||
94056DA4185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample-Prefix.pch */,
|
||||
94056DA5185BB0BC00EB94BA /* Credits.rtf */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056DBA185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94056DC0185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests.m */,
|
||||
94056DBB185BB0BC00EB94BA /* Supporting Files */,
|
||||
);
|
||||
path = EZAudioOpenGLWaveformExampleTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056DBB185BB0BC00EB94BA /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94056DBC185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests-Info.plist */,
|
||||
94056DBD185BB0BC00EB94BA /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
94056D92185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 94056DC4185BB0BC00EB94BA /* Build configuration list for PBXNativeTarget "EZAudioOpenGLWaveformExample" */;
|
||||
buildPhases = (
|
||||
94056D8F185BB0BC00EB94BA /* Sources */,
|
||||
94056D90185BB0BC00EB94BA /* Frameworks */,
|
||||
94056D91185BB0BC00EB94BA /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = EZAudioOpenGLWaveformExample;
|
||||
productName = EZAudioOpenGLWaveformExample;
|
||||
productReference = 94056D93185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
94056DB3185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 94056DC7185BB0BC00EB94BA /* Build configuration list for PBXNativeTarget "EZAudioOpenGLWaveformExampleTests" */;
|
||||
buildPhases = (
|
||||
94056DB0185BB0BC00EB94BA /* Sources */,
|
||||
94056DB1185BB0BC00EB94BA /* Frameworks */,
|
||||
94056DB2185BB0BC00EB94BA /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
94056DB9185BB0BC00EB94BA /* PBXTargetDependency */,
|
||||
);
|
||||
name = EZAudioOpenGLWaveformExampleTests;
|
||||
productName = EZAudioOpenGLWaveformExampleTests;
|
||||
productReference = 94056DB4185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
94056D8B185BB0BC00EB94BA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Syed Haris Ali";
|
||||
TargetAttributes = {
|
||||
94056DB3185BB0BC00EB94BA = {
|
||||
TestTargetID = 94056D92185BB0BC00EB94BA;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 94056D8E185BB0BC00EB94BA /* Build configuration list for PBXProject "EZAudioOpenGLWaveformExample" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 94056D8A185BB0BC00EB94BA;
|
||||
productRefGroup = 94056D94185BB0BC00EB94BA /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
94056D92185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample */,
|
||||
94056DB3185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
94056D91185BB0BC00EB94BA /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
94056DA1185BB0BC00EB94BA /* InfoPlist.strings in Resources */,
|
||||
665957651B38B2B4003E97A1 /* VERSION in Resources */,
|
||||
94056DAF185BB0BC00EB94BA /* Images.xcassets in Resources */,
|
||||
94056DA7185BB0BC00EB94BA /* Credits.rtf in Resources */,
|
||||
94056DCE185BB0D600EB94BA /* OpenGLWaveformViewController.xib in Resources */,
|
||||
94056DAD185BB0BC00EB94BA /* MainMenu.xib in Resources */,
|
||||
665957641B38B2B4003E97A1 /* CHANGELOG in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
94056DB2185BB0BC00EB94BA /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
94056DBF185BB0BC00EB94BA /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
94056D8F185BB0BC00EB94BA /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
665957621B38B2B4003E97A1 /* EZRecorder.m in Sources */,
|
||||
94056DAA185BB0BC00EB94BA /* AppDelegate.m in Sources */,
|
||||
665957581B38B2B4003E97A1 /* EZAudioFloatConverter.m in Sources */,
|
||||
665957591B38B2B4003E97A1 /* EZAudioFloatData.m in Sources */,
|
||||
665957541B38B2B4003E97A1 /* AEFloatConverter.m in Sources */,
|
||||
665957571B38B2B4003E97A1 /* EZAudioFile.m in Sources */,
|
||||
665957601B38B2B4003E97A1 /* EZOutput.m in Sources */,
|
||||
6659575C1B38B2B4003E97A1 /* EZAudioPlotGL.m in Sources */,
|
||||
665957631B38B2B4003E97A1 /* TPCircularBuffer.c in Sources */,
|
||||
6659575B1B38B2B4003E97A1 /* EZAudioPlot.m in Sources */,
|
||||
94056DA3185BB0BC00EB94BA /* main.m in Sources */,
|
||||
6659575F1B38B2B4003E97A1 /* EZMicrophone.m in Sources */,
|
||||
6659575A1B38B2B4003E97A1 /* EZAudioPlayer.m in Sources */,
|
||||
665957561B38B2B4003E97A1 /* EZAudioDevice.m in Sources */,
|
||||
94056DCD185BB0D600EB94BA /* OpenGLWaveformViewController.m in Sources */,
|
||||
665957611B38B2B4003E97A1 /* EZPlot.m in Sources */,
|
||||
665957551B38B2B4003E97A1 /* EZAudio.m in Sources */,
|
||||
6659575E1B38B2B4003E97A1 /* EZAudioUtilities.m in Sources */,
|
||||
6659575D1B38B2B4003E97A1 /* EZAudioPlotGLKViewController.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
94056DB0185BB0BC00EB94BA /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
94056DC1185BB0BC00EB94BA /* EZAudioOpenGLWaveformExampleTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
94056DB9185BB0BC00EB94BA /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 94056D92185BB0BC00EB94BA /* EZAudioOpenGLWaveformExample */;
|
||||
targetProxy = 94056DB8185BB0BC00EB94BA /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
94056D9F185BB0BC00EB94BA /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
94056DA0185BB0BC00EB94BA /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056DA5185BB0BC00EB94BA /* Credits.rtf */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
94056DA6185BB0BC00EB94BA /* en */,
|
||||
);
|
||||
name = Credits.rtf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056DAB185BB0BC00EB94BA /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
94056DAC185BB0BC00EB94BA /* Base */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
94056DBD185BB0BC00EB94BA /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
94056DBE185BB0BC00EB94BA /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
94056DC2185BB0BC00EB94BA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
94056DC3185BB0BC00EB94BA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
94056DC5185BB0BC00EB94BA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
94056DC6185BB0BC00EB94BA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
94056DC8185BB0BC00EB94BA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioOpenGLWaveformExample.app/Contents/MacOS/EZAudioOpenGLWaveformExample";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "EZAudioOpenGLWaveformExampleTests/EZAudioOpenGLWaveformExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
94056DC9185BB0BC00EB94BA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/EZAudioOpenGLWaveformExample.app/Contents/MacOS/EZAudioOpenGLWaveformExample";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "EZAudioOpenGLWaveformExample/EZAudioOpenGLWaveformExample-Prefix.pch";
|
||||
INFOPLIST_FILE = "EZAudioOpenGLWaveformExampleTests/EZAudioOpenGLWaveformExampleTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
94056D8E185BB0BC00EB94BA /* Build configuration list for PBXProject "EZAudioOpenGLWaveformExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
94056DC2185BB0BC00EB94BA /* Debug */,
|
||||
94056DC3185BB0BC00EB94BA /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
94056DC4185BB0BC00EB94BA /* Build configuration list for PBXNativeTarget "EZAudioOpenGLWaveformExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
94056DC5185BB0BC00EB94BA /* Debug */,
|
||||
94056DC6185BB0BC00EB94BA /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
94056DC7185BB0BC00EB94BA /* Build configuration list for PBXNativeTarget "EZAudioOpenGLWaveformExampleTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
94056DC8185BB0BC00EB94BA /* Debug */,
|
||||
94056DC9185BB0BC00EB94BA /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 94056D8B185BB0BC00EB94BA /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:EZAudioOpenGLWaveformExample.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// EZAudioOpenGLWaveformExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "OpenGLWaveformViewController.h"
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
|
||||
/**
|
||||
Create our OpenGLWaveformViewController
|
||||
*/
|
||||
@property (nonatomic,strong) OpenGLWaveformViewController *openGLWaveformViewController;
|
||||
|
||||
@end
|
||||
@@ -1,9 +1,8 @@
|
||||
//
|
||||
// main.m
|
||||
// PassThrough
|
||||
// AppDelegate.m
|
||||
// EZAudioOpenGLWaveformExample
|
||||
//
|
||||
// Created by Syed Haris Ali on 12/1/13.
|
||||
// Updated by Syed Haris Ali on 1/23/16.
|
||||
// Copyright (c) 2013 Syed Haris Ali. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -23,13 +22,22 @@
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
@implementation AppDelegate
|
||||
@synthesize openGLWaveformViewController;
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
// Swap in our view controller in the window's content view
|
||||
self.openGLWaveformViewController = [[OpenGLWaveformViewController alloc] init];
|
||||
// Resize view controller to content view's current size
|
||||
self.openGLWaveformViewController.view.frame = [self.window.contentView frame];
|
||||
// Add resizing flags to make the view controller resize with the window
|
||||
self.openGLWaveformViewController.view.autoresizingMask = (NSViewWidthSizable|NSViewHeightSizable);
|
||||
// Add in the core graphics view controller as subview
|
||||
[self.window.contentView addSubview:self.openGLWaveformViewController.view];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,467 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4439" systemVersion="13A451" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4439"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" destination="58" id="142"/>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder">
|
||||
<connections>
|
||||
<action selector="alignCenter:" destination="499" id="518"/>
|
||||
<action selector="alignJustified:" destination="500" id="523"/>
|
||||
<action selector="alignLeft:" destination="498" id="524"/>
|
||||
<action selector="alignRight:" destination="501" id="521"/>
|
||||
<action selector="arrangeInFront:" destination="5" id="39"/>
|
||||
<action selector="capitalizeWord:" destination="466" id="467"/>
|
||||
<action selector="centerSelectionInVisibleArea:" destination="210" id="245"/>
|
||||
<action selector="checkSpelling:" destination="201" id="225"/>
|
||||
<action selector="clearRecentDocuments:" destination="126" id="127"/>
|
||||
<action selector="copy:" destination="197" id="224"/>
|
||||
<action selector="copyFont:" destination="403" id="428"/>
|
||||
<action selector="copyRuler:" destination="506" id="522"/>
|
||||
<action selector="cut:" destination="199" id="228"/>
|
||||
<action selector="delete:" destination="202" id="235"/>
|
||||
<action selector="hide:" destination="134" id="367"/>
|
||||
<action selector="hideOtherApplications:" destination="145" id="368"/>
|
||||
<action selector="loosenKerning:" destination="419" id="435"/>
|
||||
<action selector="lowerBaseline:" destination="410" id="427"/>
|
||||
<action selector="lowercaseWord:" destination="465" id="468"/>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" destination="511" id="526"/>
|
||||
<action selector="makeBaseWritingDirectionNatural:" destination="510" id="525"/>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" destination="512" id="527"/>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" destination="516" id="529"/>
|
||||
<action selector="makeTextWritingDirectionNatural:" destination="515" id="528"/>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" destination="517" id="530"/>
|
||||
<action selector="newDocument:" destination="82" id="373"/>
|
||||
<action selector="openDocument:" destination="72" id="374"/>
|
||||
<action selector="orderFrontColorPanel:" destination="401" id="433"/>
|
||||
<action selector="orderFrontSubstitutionsPanel:" destination="457" id="458"/>
|
||||
<action selector="paste:" destination="203" id="226"/>
|
||||
<action selector="pasteAsPlainText:" destination="485" id="486"/>
|
||||
<action selector="pasteFont:" destination="404" id="436"/>
|
||||
<action selector="pasteRuler:" destination="507" id="519"/>
|
||||
<action selector="performClose:" destination="73" id="193"/>
|
||||
<action selector="performFindPanelAction:" destination="209" id="241"/>
|
||||
<action selector="performFindPanelAction:" destination="208" id="487"/>
|
||||
<action selector="performFindPanelAction:" destination="213" id="488"/>
|
||||
<action selector="performFindPanelAction:" destination="221" id="489"/>
|
||||
<action selector="performFindPanelAction:" destination="534" id="535"/>
|
||||
<action selector="performMiniaturize:" destination="23" id="37"/>
|
||||
<action selector="performZoom:" destination="239" id="240"/>
|
||||
<action selector="print:" destination="78" id="86"/>
|
||||
<action selector="raiseBaseline:" destination="409" id="426"/>
|
||||
<action selector="redo:" destination="215" id="231"/>
|
||||
<action selector="revertDocumentToSaved:" destination="112" id="364"/>
|
||||
<action selector="runPageLayout:" destination="77" id="87"/>
|
||||
<action selector="runToolbarCustomizationPalette:" destination="298" id="365"/>
|
||||
<action selector="saveDocument:" destination="75" id="362"/>
|
||||
<action selector="selectAll:" destination="198" id="232"/>
|
||||
<action selector="showGuessPanel:" destination="204" id="230"/>
|
||||
<action selector="showHelp:" destination="492" id="493"/>
|
||||
<action selector="startSpeaking:" destination="196" id="233"/>
|
||||
<action selector="stopSpeaking:" destination="195" id="227"/>
|
||||
<action selector="subscript:" destination="408" id="429"/>
|
||||
<action selector="superscript:" destination="407" id="430"/>
|
||||
<action selector="tightenKerning:" destination="418" id="431"/>
|
||||
<action selector="toggleAutomaticDashSubstitution:" destination="460" id="461"/>
|
||||
<action selector="toggleAutomaticLinkDetection:" destination="354" id="357"/>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" destination="351" id="356"/>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" destination="454" id="456"/>
|
||||
<action selector="toggleAutomaticTextReplacement:" destination="462" id="463"/>
|
||||
<action selector="toggleContinuousSpellChecking:" destination="219" id="222"/>
|
||||
<action selector="toggleGrammarChecking:" destination="346" id="347"/>
|
||||
<action selector="toggleRuler:" destination="505" id="520"/>
|
||||
<action selector="toggleSmartInsertDelete:" destination="350" id="355"/>
|
||||
<action selector="toggleToolbarShown:" destination="297" id="366"/>
|
||||
<action selector="turnOffKerning:" destination="417" id="441"/>
|
||||
<action selector="turnOffLigatures:" destination="413" id="440"/>
|
||||
<action selector="underline:" destination="392" id="432"/>
|
||||
<action selector="undo:" destination="207" id="223"/>
|
||||
<action selector="unhideAllApplications:" destination="150" id="370"/>
|
||||
<action selector="unscript:" destination="406" id="437"/>
|
||||
<action selector="uppercaseWord:" destination="452" id="464"/>
|
||||
<action selector="useAllLigatures:" destination="414" id="434"/>
|
||||
<action selector="useStandardKerning:" destination="416" id="438"/>
|
||||
<action selector="useStandardLigatures:" destination="412" id="439"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-3" userLabel="Application">
|
||||
<connections>
|
||||
<action selector="terminate:" destination="136" id="449"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="EZAudioOpenGLWaveformExample" id="56">
|
||||
<menu key="submenu" title="EZAudioOpenGLWaveformExample" systemMenu="apple" id="57">
|
||||
<items>
|
||||
<menuItem title="About EZAudioOpenGLWaveformExample" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
|
||||
<menuItem isSeparatorItem="YES" id="143">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Services" id="131">
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide EZAudioOpenGLWaveformExample" keyEquivalent="h" id="134"/>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150"/>
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit EZAudioOpenGLWaveformExample" keyEquivalent="q" id="136"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="83">
|
||||
<menu key="submenu" title="File" id="81">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="82"/>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72"/>
|
||||
<menuItem title="Open Recent" id="124">
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="126"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73"/>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75"/>
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207"/>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199"/>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197"/>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203"/>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202"/>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198"/>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209"/>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208"/>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221"/>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="216">
|
||||
<menu key="submenu" title="Spelling and Grammar" id="200">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204"/>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201"/>
|
||||
<menuItem isSeparatorItem="YES" id="453"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219"/>
|
||||
<menuItem title="Check Grammar With Spelling" id="346"/>
|
||||
<menuItem title="Correct Spelling Automatically" id="454">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="348">
|
||||
<menu key="submenu" title="Substitutions" id="349">
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="457">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350"/>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351"/>
|
||||
<menuItem title="Smart Dashes" id="460">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="462">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="450">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="451">
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="452">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="465">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="466">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="196"/>
|
||||
<menuItem title="Stop Speaking" id="195"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="375">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="376">
|
||||
<items>
|
||||
<menuItem title="Font" id="377">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389"/>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390"/>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391"/>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392"/>
|
||||
<menuItem isSeparatorItem="YES" id="393"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394"/>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395"/>
|
||||
<menuItem isSeparatorItem="YES" id="396"/>
|
||||
<menuItem title="Kern" id="397">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Kern" id="415">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="416">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="417">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="418">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="419">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="398">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="411">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="412">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="413">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="414">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="399">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="405">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="406">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="407">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="408">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="409">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="410">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="400"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401"/>
|
||||
<menuItem isSeparatorItem="YES" id="402"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="496">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498"/>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499"/>
|
||||
<menuItem title="Justify" id="500">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501"/>
|
||||
<menuItem isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="508">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="509">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="510">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="511">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="512">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="513"/>
|
||||
<menuItem title="Selection" enabled="NO" id="514">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="515">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="516">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="517">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="504"/>
|
||||
<menuItem title="Show Ruler" id="505">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="295">
|
||||
<menu key="submenu" title="View" id="296">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23"/>
|
||||
<menuItem title="Zoom" id="239"/>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="490">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="EZAudioOpenGLWaveformExample Help" keyEquivalent="?" id="492"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="EZAudioOpenGLWaveformExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</view>
|
||||
</window>
|
||||
<customObject id="494" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" destination="390" id="421"/>
|
||||
<action selector="addFontTrait:" destination="391" id="422"/>
|
||||
<action selector="modifyFont:" destination="395" id="423"/>
|
||||
<action selector="modifyFont:" destination="394" id="425"/>
|
||||
<action selector="orderFrontFontPanel:" destination="389" id="424"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -5,15 +5,15 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<string>com.sha.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
@@ -23,9 +23,9 @@
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016 Syed Haris Ali. All rights reserved.</string>
|
||||
<string>Copyright © 2013 Syed Haris Ali. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||