| @@ -806,6 +806,7 @@ EXCLUDE = ../modules/juce_graphics/image_formats \ | |||||
| ../modules/juce_audio_formats/juce_audio_formats.h \ | ../modules/juce_audio_formats/juce_audio_formats.h \ | ||||
| ../modules/juce_audio_formats/juce_audio_formats.cpp \ | ../modules/juce_audio_formats/juce_audio_formats.cpp \ | ||||
| ../modules/juce_audio_plugin_client/juce_audio_plugin_client.h \ | ../modules/juce_audio_plugin_client/juce_audio_plugin_client.h \ | ||||
| ../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses \ | |||||
| ../modules/juce_audio_processors/juce_audio_processors.h \ | ../modules/juce_audio_processors/juce_audio_processors.h \ | ||||
| ../modules/juce_audio_processors/juce_audio_processors.cpp \ | ../modules/juce_audio_processors/juce_audio_processors.cpp \ | ||||
| ../modules/juce_audio_utils/juce_audio_utils.h \ | ../modules/juce_audio_utils/juce_audio_utils.h \ | ||||
| @@ -21,27 +21,26 @@ | |||||
| B003460B11C0B7C1CC07E666 = {isa = PBXBuildFile; fileRef = 0926E36205F4D676343AB6E7; }; | B003460B11C0B7C1CC07E666 = {isa = PBXBuildFile; fileRef = 0926E36205F4D676343AB6E7; }; | ||||
| 8265E59547F2C5DDD10F58BF = {isa = PBXBuildFile; fileRef = 682D51082D9FE9859F364A10; }; | 8265E59547F2C5DDD10F58BF = {isa = PBXBuildFile; fileRef = 682D51082D9FE9859F364A10; }; | ||||
| E32999B782F688D3746FEB08 = {isa = PBXBuildFile; fileRef = 9EC0C4C02099C656EEF39DA9; }; | E32999B782F688D3746FEB08 = {isa = PBXBuildFile; fileRef = 9EC0C4C02099C656EEF39DA9; }; | ||||
| F04FAA69AC50147EA624EC1F = {isa = PBXBuildFile; fileRef = 2B2D54521D69CF4407471A56; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| BE7B7AD7F8A22C21CE836999 = {isa = PBXBuildFile; fileRef = 5E90DDA49E067C3DF60891AA; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 03978B040325C64F1A301026 = {isa = PBXBuildFile; fileRef = 6A593B7ADFAC09D547EA809D; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 64CC64872B50899D0C1965A4 = {isa = PBXBuildFile; fileRef = E08045246EF1A84C7A4D9DF5; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| B3C70DEC14A0F3C68BFABAB3 = {isa = PBXBuildFile; fileRef = 5631EA8ECD79655B6BEDF8A3; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 672ABA87BCE2AC50A10DEC8B = {isa = PBXBuildFile; fileRef = 374740EFBC17343E10F66F4C; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| AAAF1BFC19F4CE7BBD8FA43A = {isa = PBXBuildFile; fileRef = 969CF69D90AC73918B9BB0CD; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| F075907E84874848BF0BB205 = {isa = PBXBuildFile; fileRef = E0A48CA97D4C946F632C0DB7; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| A1AF669E9F10B2BE0FE3ECD8 = {isa = PBXBuildFile; fileRef = 2E19A0C6793FD28085F7A256; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 64AD03BB3A52EC9E2C030B8E = {isa = PBXBuildFile; fileRef = 0906F59C839873ADC151A188; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 7B4173581D4B03969E995CA5 = {isa = PBXBuildFile; fileRef = 4A6A465D7BC825BB91F562C3; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| F979285E6636E6CD0669E164 = {isa = PBXBuildFile; fileRef = ED5C52722B9653FA3B009C01; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 5677D9A2B913014EB1B3E3B3 = {isa = PBXBuildFile; fileRef = 3031159E3E89066250B1D48A; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| C74F334B15AD60AC06A086B7 = {isa = PBXBuildFile; fileRef = 534561E5F94B5D7A093485DF; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| CB8698D8E9F64AD71C0608E4 = {isa = PBXBuildFile; fileRef = A5985F8B03893AA7EFD0273A; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| A5C8DB9F33F2934B307C105C = {isa = PBXBuildFile; fileRef = 3C003D01B67D75E4D745A9B0; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| E42B91C4C0B68D26493D8586 = {isa = PBXBuildFile; fileRef = F7AF91E09A9EB00EA5438730; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 8DBCF6059F7B99ED17E39C3A = {isa = PBXBuildFile; fileRef = BC369095BAEED8707D12F63B; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 71BEA1E8715EC77F3BA35BAE = {isa = PBXBuildFile; fileRef = 79B958A028493E0DB0133E2B; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 4E76293207C599EF3F0E9D66 = {isa = PBXBuildFile; fileRef = 71CDD3C8D311F7994DD5CC8F; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 899A05A18F62ABBFF66B554E = {isa = PBXBuildFile; fileRef = EFCF0633FF23B5F88112A200; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 05D1398458CDB00C236D7553 = {isa = PBXBuildFile; fileRef = 3AA0960DF09414DBA0A2255B; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| EDC1CED5C7F88E1142F4A46A = {isa = PBXBuildFile; fileRef = AABC1F4E7D9DA3C6B6DC0F05; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| B02F742C6DE19F5415457993 = {isa = PBXBuildFile; fileRef = 95FF785BAEC4F2799A75D2FF; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| B89DA74BC8384D744F20B8CB = {isa = PBXBuildFile; fileRef = E0657C5A5A08F4B5BE55034A; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| BF903CF8AFDA8D74E3A9D023 = {isa = PBXBuildFile; fileRef = 5DAA9288D1FC19812E6ABA3D; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 9EDD2E63820FA844B4237F1F = {isa = PBXBuildFile; fileRef = 2051F23DC1B2A76D3B110616; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 65EF022632E1E7967860DD5E = {isa = PBXBuildFile; fileRef = 88F2FC5C63F1BA3184DC38BD; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 15885D9F3F3CB8EFDC29A40F = {isa = PBXBuildFile; fileRef = 31E15E7A0FBD027D83A28DFF; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| C9C1F85E79851CE3F2EA0560 = {isa = PBXBuildFile; fileRef = E42198F571F1BB1C5203F3D2; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 10803DD1A2511511C9A2CEC5 = {isa = PBXBuildFile; fileRef = 739336D279C585C749F3039A; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| EDE82B3320CC03F38226AA50 = {isa = PBXBuildFile; fileRef = B6394C38B7A283DE86213FAE; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| C3C922FB2D069BB6DE3ECAA1 = {isa = PBXBuildFile; fileRef = AFE00126A5FEF419332CD2B9; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 48D94EBEB2D48D0DCC1394C9 = {isa = PBXBuildFile; fileRef = EB38777DCA28E40FF364EAE1; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| D2B29F3448FA79AB8C47B3D8 = {isa = PBXBuildFile; fileRef = 0D4E3861B5EE21765BDEE2A3; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| D5E7114B2C484F13A51DCBC3 = {isa = PBXBuildFile; fileRef = 28FD98C78FE1E918553D4C3D; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 9B39F1EE70A26791804DA55E = {isa = PBXBuildFile; fileRef = 87DBD7450AE0FDD762712620; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 0A7276E46524FC5FD796F27D = {isa = PBXBuildFile; fileRef = 3AA5D4AF03A0689BF8385319; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 9EA2528254AA35DBDDFEA601 = {isa = PBXBuildFile; fileRef = AC4612F7E064ECEC2E95B129; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 68B259347BBF52B12FD6900D = {isa = PBXBuildFile; fileRef = E521DD6592FA0F7828161360; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 91CCE2D40B3D71F3126A1043 = {isa = PBXBuildFile; fileRef = A8BA67A9567A51069D275EBB; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 74CF5671532851FFA52E9D0C = {isa = PBXBuildFile; fileRef = 1BAAB47A9C5B1D76D28FA282; }; | 74CF5671532851FFA52E9D0C = {isa = PBXBuildFile; fileRef = 1BAAB47A9C5B1D76D28FA282; }; | ||||
| E20B98D0BD4CB959779121EF = {isa = PBXBuildFile; fileRef = DCF6DECFAD7F4D907C0458A5; }; | E20B98D0BD4CB959779121EF = {isa = PBXBuildFile; fileRef = DCF6DECFAD7F4D907C0458A5; }; | ||||
| BF6B9A47774C03C34559CAFE = {isa = PBXBuildFile; fileRef = 8F59D489139F78A729CED9E5; }; | BF6B9A47774C03C34559CAFE = {isa = PBXBuildFile; fileRef = 8F59D489139F78A729CED9E5; }; | ||||
| @@ -67,6 +66,7 @@ | |||||
| BCFB9D694F4DD8A76C6B9878 = {isa = PBXBuildFile; fileRef = 8EB324480D60B3E3A81541E5; }; | BCFB9D694F4DD8A76C6B9878 = {isa = PBXBuildFile; fileRef = 8EB324480D60B3E3A81541E5; }; | ||||
| 080999E86692B638CD108D70 = {isa = PBXBuildFile; fileRef = 6CEFF94C7852DB3BFA5E29EB; }; | 080999E86692B638CD108D70 = {isa = PBXBuildFile; fileRef = 6CEFF94C7852DB3BFA5E29EB; }; | ||||
| BFD65DA4F2FE24DF532304DA = {isa = PBXBuildFile; fileRef = 7D08D5465E74DF02EA4E7410; }; | BFD65DA4F2FE24DF532304DA = {isa = PBXBuildFile; fileRef = 7D08D5465E74DF02EA4E7410; }; | ||||
| A4996F8A30110B5EDB801516 = {isa = PBXBuildFile; fileRef = 1CF9C794D7A955EA89D8B5CB; settings = {COMPILER_FLAGS = "-w"; }; }; | |||||
| 002643D66417E4FFF5CC516A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../../../modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; }; | 002643D66417E4FFF5CC516A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../../../modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 0045658D26F88B490908C99B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryIterator.cpp"; path = "../../../../modules/juce_core/files/juce_DirectoryIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; | 0045658D26F88B490908C99B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryIterator.cpp"; path = "../../../../modules/juce_core/files/juce_DirectoryIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 00A45583A3FEF005232FE1BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UndoManager.cpp"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoManager.cpp"; sourceTree = "SOURCE_ROOT"; }; | 00A45583A3FEF005232FE1BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UndoManager.cpp"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoManager.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -108,7 +108,6 @@ | |||||
| 07C4AC0C62F94DDFA1FA0E31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CarbonViewWrapperComponent.h"; path = "../../../../modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 07C4AC0C62F94DDFA1FA0E31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CarbonViewWrapperComponent.h"; path = "../../../../modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 07FBBCECF4C212D67AD71FFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SpinLock.h"; path = "../../../../modules/juce_core/threads/juce_SpinLock.h"; sourceTree = "SOURCE_ROOT"; }; | 07FBBCECF4C212D67AD71FFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SpinLock.h"; path = "../../../../modules/juce_core/threads/juce_SpinLock.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 080D19E24AE4FDC135F58B86 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModalComponentManager.h"; path = "../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.h"; sourceTree = "SOURCE_ROOT"; }; | 080D19E24AE4FDC135F58B86 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModalComponentManager.h"; path = "../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 0906F59C839873ADC151A188 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUMIDIEffectBase.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 090E68CDF051FAE89936CF61 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionListener.h"; path = "../../../../modules/juce_events/broadcasters/juce_ActionListener.h"; sourceTree = "SOURCE_ROOT"; }; | 090E68CDF051FAE89936CF61 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionListener.h"; path = "../../../../modules/juce_events/broadcasters/juce_ActionListener.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 0926E36205F4D676343AB6E7 = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; }; | 0926E36205F4D676343AB6E7 = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; }; | ||||
| 0977400450E451AD1BE80E77 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; | 0977400450E451AD1BE80E77 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -128,6 +127,7 @@ | |||||
| 0CD474E9C69F05868EF8D9EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_CommonFile.cpp"; path = "../../../../modules/juce_core/native/juce_linux_CommonFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | 0CD474E9C69F05868EF8D9EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_CommonFile.cpp"; path = "../../../../modules/juce_core/native/juce_linux_CommonFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 0CF861C9A12A38A47B7BC43C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LagrangeInterpolator.h"; path = "../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h"; sourceTree = "SOURCE_ROOT"; }; | 0CF861C9A12A38A47B7BC43C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LagrangeInterpolator.h"; path = "../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 0D06541766ED7D5D99E403C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.h"; sourceTree = "SOURCE_ROOT"; }; | 0D06541766ED7D5D99E403C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 0D4E3861B5EE21765BDEE2A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAAudioChannelLayout.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/CAAudioChannelLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 0D7BAB3BA700850A464A9F83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreMidi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp"; sourceTree = "SOURCE_ROOT"; }; | 0D7BAB3BA700850A464A9F83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreMidi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 0E87CC46EB3070AD4D904EF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CustomTypeface.h"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.h"; sourceTree = "SOURCE_ROOT"; }; | 0E87CC46EB3070AD4D904EF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CustomTypeface.h"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 0ED9A27A7166BC016CB8909C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableComposite.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.h"; sourceTree = "SOURCE_ROOT"; }; | 0ED9A27A7166BC016CB8909C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableComposite.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -137,7 +137,6 @@ | |||||
| 0FFE9DEC94D4019882CE3F85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Base64.h"; path = "../../../../modules/juce_core/text/juce_Base64.h"; sourceTree = "SOURCE_ROOT"; }; | 0FFE9DEC94D4019882CE3F85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Base64.h"; path = "../../../../modules/juce_core/text/juce_Base64.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 100EFA05982C05972AC7861B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_processors.mm"; path = "../../../../modules/juce_audio_processors/juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; }; | 100EFA05982C05972AC7861B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_processors.mm"; path = "../../../../modules/juce_audio_processors/juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 103C7BCDA3ABA3AD615794F0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableHeaderComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 103C7BCDA3ABA3AD615794F0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableHeaderComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 103FA4C6C505052C818A4829 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUTimestampGenerator.h; path = Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUTimestampGenerator.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 104CC5F094E0B3D1D3055D04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioUnitPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; | 104CC5F094E0B3D1D3055D04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioUnitPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 10A49DD74F3FB9E69FC989B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; | 10A49DD74F3FB9E69FC989B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 10C46E275C321A3974729DA6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; }; | 10C46E275C321A3974729DA6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -151,7 +150,6 @@ | |||||
| 1345DCB37CEF3DCB146FE70F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatWriter.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"; sourceTree = "SOURCE_ROOT"; }; | 1345DCB37CEF3DCB146FE70F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatWriter.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 137EEC7324A15E7724AEB4C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageCache.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageCache.cpp"; sourceTree = "SOURCE_ROOT"; }; | 137EEC7324A15E7724AEB4C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageCache.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageCache.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 13EACB731E5573BC68744B5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; | 13EACB731E5573BC68744B5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 141FD2E7828F2F2BE0EE9506 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUInputElement.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUInputElement.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 1460DF86692852CBB0840F87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyboardFocusTraverser.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp"; sourceTree = "SOURCE_ROOT"; }; | 1460DF86692852CBB0840F87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyboardFocusTraverser.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 14A221649E68BA8FD0EADAE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SplashScreen.h"; path = "../../../../modules/juce_gui_extra/misc/juce_SplashScreen.h"; sourceTree = "SOURCE_ROOT"; }; | 14A221649E68BA8FD0EADAE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SplashScreen.h"; path = "../../../../modules/juce_gui_extra/misc/juce_SplashScreen.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 1519F1DAEF1445EEBC1D75DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 1519F1DAEF1445EEBC1D75DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -183,7 +181,7 @@ | |||||
| 1BE2A39FBE87B3DA36C02468 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDirectoryScanner.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp"; sourceTree = "SOURCE_ROOT"; }; | 1BE2A39FBE87B3DA36C02468 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDirectoryScanner.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 1C7E45B063CBDED867290BE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LeakedObjectDetector.h"; path = "../../../../modules/juce_core/memory/juce_LeakedObjectDetector.h"; sourceTree = "SOURCE_ROOT"; }; | 1C7E45B063CBDED867290BE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LeakedObjectDetector.h"; path = "../../../../modules/juce_core/memory/juce_LeakedObjectDetector.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 1CC63825EF38EC63EE2196E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PlatformDefs.h"; path = "../../../../modules/juce_core/system/juce_PlatformDefs.h"; sourceTree = "SOURCE_ROOT"; }; | 1CC63825EF38EC63EE2196E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PlatformDefs.h"; path = "../../../../modules/juce_core/system/juce_PlatformDefs.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 1D133744B523A61401D587D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CAVectorUnit.h; path = Extras/CoreAudio/PublicUtility/CAVectorUnit.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 1CF9C794D7A955EA89D8B5CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MusicDeviceBase.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/MusicDeviceBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 1D3A49572FAAB491744428C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | 1D3A49572FAAB491744428C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 1D4AFBEC703C6F373B292D9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RTAS_Wrapper.cpp"; path = "../../../../modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp"; sourceTree = "SOURCE_ROOT"; }; | 1D4AFBEC703C6F373B292D9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RTAS_Wrapper.cpp"; path = "../../../../modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 1DBB870CC15ABC104A9AA5C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; }; | 1DBB870CC15ABC104A9AA5C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -197,7 +195,7 @@ | |||||
| 1FBFF2D9043296E1E09DE156 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BigInteger.cpp"; path = "../../../../modules/juce_core/maths/juce_BigInteger.cpp"; sourceTree = "SOURCE_ROOT"; }; | 1FBFF2D9043296E1E09DE156 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BigInteger.cpp"; path = "../../../../modules/juce_core/maths/juce_BigInteger.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 201F62BBDF90DC3F1C9684C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileOutputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | 201F62BBDF90DC3F1C9684C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileOutputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2036975FC5AA528303B4E837 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IPAddress.cpp"; path = "../../../../modules/juce_core/network/juce_IPAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; | 2036975FC5AA528303B4E837 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IPAddress.cpp"; path = "../../../../modules/juce_core/network/juce_IPAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 206544B2ADA604E3A68FEF85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUBuffer.h; path = Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUBuffer.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 2051F23DC1B2A76D3B110616 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUDispatch.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUDispatch.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 20881BC337B715DEC96E7976 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_formats/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | 20881BC337B715DEC96E7976 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_formats/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 20E3F95E25915E7F53F37113 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colour.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colour.cpp"; sourceTree = "SOURCE_ROOT"; }; | 20E3F95E25915E7F53F37113 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colour.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colour.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 210FC90993B49F9206A62F02 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Logger.cpp"; path = "../../../../modules/juce_core/logging/juce_Logger.cpp"; sourceTree = "SOURCE_ROOT"; }; | 210FC90993B49F9206A62F02 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Logger.cpp"; path = "../../../../modules/juce_core/logging/juce_Logger.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -219,6 +217,7 @@ | |||||
| 27C9A17C04B5426D28A92DF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyListener.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"; sourceTree = "SOURCE_ROOT"; }; | 27C9A17C04B5426D28A92DF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyListener.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 28C68586E6A2C95B2BC007DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsSoftwareRenderer.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"; sourceTree = "SOURCE_ROOT"; }; | 28C68586E6A2C95B2BC007DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsSoftwareRenderer.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 28F65EEAFB3B971E8EDB10F3 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; }; | 28F65EEAFB3B971E8EDB10F3 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; }; | ||||
| 28FD98C78FE1E918553D4C3D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAAUParameter.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/CAAUParameter.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 291947B7C7CCCF7029BA0C78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPathListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 291947B7C7CCCF7029BA0C78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPathListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2956FA046400383FC705C1CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_WebBrowserComponent.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm"; sourceTree = "SOURCE_ROOT"; }; | 2956FA046400383FC705C1CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_WebBrowserComponent.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 29917AAA580F21BF2798D071 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 29917AAA580F21BF2798D071 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -226,12 +225,10 @@ | |||||
| 2A073A793701BE742D5D8CA9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioThumbnailBase.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailBase.h"; sourceTree = "SOURCE_ROOT"; }; | 2A073A793701BE742D5D8CA9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioThumbnailBase.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioThumbnailBase.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2AA4939A70E1E1D6B907DA87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageConvolutionKernel.h"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.h"; sourceTree = "SOURCE_ROOT"; }; | 2AA4939A70E1E1D6B907DA87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageConvolutionKernel.h"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2AA92DC1171DAF0BA4BB0E63 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_formats.h"; path = "../../../../modules/juce_audio_formats/juce_audio_formats.h"; sourceTree = "SOURCE_ROOT"; }; | 2AA92DC1171DAF0BA4BB0E63 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_formats.h"; path = "../../../../modules/juce_audio_formats/juce_audio_formats.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2B2D54521D69CF4407471A56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUBase.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUBase.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 2BEBB7EB22A689648A381ECA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 2BEBB7EB22A689648A381ECA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2CAFB89BC62E47429CC04AEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V1.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp"; sourceTree = "SOURCE_ROOT"; }; | 2CAFB89BC62E47429CC04AEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V1.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2D4B766DA1C66FA2857D80F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RTAS_DigiCode3.cpp"; path = "../../../../modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode3.cpp"; sourceTree = "SOURCE_ROOT"; }; | 2D4B766DA1C66FA2857D80F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RTAS_DigiCode3.cpp"; path = "../../../../modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode3.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2D799F4BCA83847DEACB505D = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = "SOURCE_ROOT"; }; | 2D799F4BCA83847DEACB505D = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2E19A0C6793FD28085F7A256 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUMIDIBase.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 2E57B46569DAD42A3E53460E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandInfo.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"; sourceTree = "SOURCE_ROOT"; }; | 2E57B46569DAD42A3E53460E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandInfo.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2E58109147CCFC780F10C23D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; | 2E58109147CCFC780F10C23D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; | ||||
| 2E742E5F322F63D5E8C48C0D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JSON.cpp"; path = "../../../../modules/juce_core/javascript/juce_JSON.cpp"; sourceTree = "SOURCE_ROOT"; }; | 2E742E5F322F63D5E8C48C0D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JSON.cpp"; path = "../../../../modules/juce_core/javascript/juce_JSON.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -242,12 +239,12 @@ | |||||
| 2F7B9CC35EEC12DF96E43229 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; }; | 2F7B9CC35EEC12DF96E43229 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2FADC0AA0043A3C87DF25E0D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IncludeModuleHeaders.h"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h"; sourceTree = "SOURCE_ROOT"; }; | 2FADC0AA0043A3C87DF25E0D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IncludeModuleHeaders.h"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 2FBEA375F39FFA44911F043B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPCompressorOutputStream.cpp"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | 2FBEA375F39FFA44911F043B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPCompressorOutputStream.cpp"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3031159E3E89066250B1D48A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUScopeElement.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUScopeElement.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 30351F38509A67AC97C51072 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FillType.cpp"; path = "../../../../modules/juce_graphics/colour/juce_FillType.cpp"; sourceTree = "SOURCE_ROOT"; }; | 30351F38509A67AC97C51072 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FillType.cpp"; path = "../../../../modules/juce_graphics/colour/juce_FillType.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 30789700DDE033623673B969 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToggleButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.cpp"; sourceTree = "SOURCE_ROOT"; }; | 30789700DDE033623673B969 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToggleButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 318F416CA5367D312EDEB440 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SelectedItemSet.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"; sourceTree = "SOURCE_ROOT"; }; | 318F416CA5367D312EDEB440 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SelectedItemSet.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 31ACD81C791C0D6A394B7602 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyPanel.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | 31ACD81C791C0D6A394B7602 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyPanel.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 31CF7913899F89982EFBFE3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextLayout.h"; path = "../../../../modules/juce_graphics/fonts/juce_TextLayout.h"; sourceTree = "SOURCE_ROOT"; }; | 31CF7913899F89982EFBFE3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextLayout.h"; path = "../../../../modules/juce_graphics/fonts/juce_TextLayout.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 31E15E7A0FBD027D83A28DFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUInputElement.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUInputElement.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 32080C8AC923C34CCE673F1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormat.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; | 32080C8AC923C34CCE673F1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormat.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 322A19A7DAB9F2840598D2E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationBase.h"; path = "../../../../modules/juce_events/messages/juce_ApplicationBase.h"; sourceTree = "SOURCE_ROOT"; }; | 322A19A7DAB9F2840598D2E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationBase.h"; path = "../../../../modules/juce_events/messages/juce_ApplicationBase.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 322DE76903F886C1711EB272 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_freetype_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_freetype_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; | 322DE76903F886C1711EB272 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_freetype_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_freetype_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -264,9 +261,7 @@ | |||||
| 35F57A1FB7A15A5374251F97 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; | 35F57A1FB7A15A5374251F97 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 36EDB9DCF2D5260319028905 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_String.cpp"; path = "../../../../modules/juce_core/text/juce_String.cpp"; sourceTree = "SOURCE_ROOT"; }; | 36EDB9DCF2D5260319028905 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_String.cpp"; path = "../../../../modules/juce_core/text/juce_String.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 371CABFCE28A273E9150F537 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; }; | 371CABFCE28A273E9150F537 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 374740EFBC17343E10F66F4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUDispatch.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUDispatch.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 3755479207D218969425F91F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_RTAS_MacUtilities.mm"; path = "../../../../modules/juce_audio_plugin_client/RTAS/juce_RTAS_MacUtilities.mm"; sourceTree = "SOURCE_ROOT"; }; | 3755479207D218969425F91F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_RTAS_MacUtilities.mm"; path = "../../../../modules/juce_audio_plugin_client/RTAS/juce_RTAS_MacUtilities.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 375A031244EED3B21A609984 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CAStreamBasicDescription.h; path = Extras/CoreAudio/PublicUtility/CAStreamBasicDescription.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 376742758A9CEDA05995AF51 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Logger.h"; path = "../../../../modules/juce_core/logging/juce_Logger.h"; sourceTree = "SOURCE_ROOT"; }; | 376742758A9CEDA05995AF51 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Logger.h"; path = "../../../../modules/juce_core/logging/juce_Logger.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 379E6C7C71E680936EF723F4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; }; | 379E6C7C71E680936EF723F4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 37A7FEF55D2A1043B57E076F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; }; | 37A7FEF55D2A1043B57E076F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -280,6 +275,8 @@ | |||||
| 39AD51EB5E59758E6FC4F313 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; | 39AD51EB5E59758E6FC4F313 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 39D0873583E797FEA1F40BBD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; | 39D0873583E797FEA1F40BBD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3A6A7BBEB5E04AE75D24BAF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDReader.h"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h"; sourceTree = "SOURCE_ROOT"; }; | 3A6A7BBEB5E04AE75D24BAF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDReader.h"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3AA0960DF09414DBA0A2255B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUBase.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 3AA5D4AF03A0689BF8385319 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CarbonEventHandler.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/CarbonEventHandler.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 3AA84EBD59A4CBE7E32FB0F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDescription.h"; path = "../../../../modules/juce_audio_processors/processors/juce_PluginDescription.h"; sourceTree = "SOURCE_ROOT"; }; | 3AA84EBD59A4CBE7E32FB0F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDescription.h"; path = "../../../../modules/juce_audio_processors/processors/juce_PluginDescription.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3ABB924AB5490C97118B8CE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDBurner.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp"; sourceTree = "SOURCE_ROOT"; }; | 3ABB924AB5490C97118B8CE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDBurner.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3AD4F35998A668F9C4D585B2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinate.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h"; sourceTree = "SOURCE_ROOT"; }; | 3AD4F35998A668F9C4D585B2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinate.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -288,7 +285,6 @@ | |||||
| 3B22E720E83CBDCC315A038F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_InputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | 3B22E720E83CBDCC315A038F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_InputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3B6F2FAF5ADD1BE0014C7952 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageEffectFilter.h"; path = "../../../../modules/juce_graphics/effects/juce_ImageEffectFilter.h"; sourceTree = "SOURCE_ROOT"; }; | 3B6F2FAF5ADD1BE0014C7952 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageEffectFilter.h"; path = "../../../../modules/juce_graphics/effects/juce_ImageEffectFilter.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3B9EA2905AC4A9924B9AC3FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RecentlyOpenedFilesList.h"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"; sourceTree = "SOURCE_ROOT"; }; | 3B9EA2905AC4A9924B9AC3FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RecentlyOpenedFilesList.h"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3C003D01B67D75E4D745A9B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAMutex.cpp; path = Extras/CoreAudio/PublicUtility/CAMutex.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 3C00BD826FCACC11EC9CF6D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginListComponent.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 3C00BD826FCACC11EC9CF6D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginListComponent.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3C3B97E53D481B74892572D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_android_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; | 3C3B97E53D481B74892572D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_android_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 3C6E8B705C53294638807FC4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IncludeSystemHeaders.h"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_IncludeSystemHeaders.h"; sourceTree = "SOURCE_ROOT"; }; | 3C6E8B705C53294638807FC4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IncludeSystemHeaders.h"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_IncludeSystemHeaders.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -305,7 +301,6 @@ | |||||
| 3FE7F76D4D023295BCEC0E65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandTarget.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h"; sourceTree = "SOURCE_ROOT"; }; | 3FE7F76D4D023295BCEC0E65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandTarget.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4010F841656A5089C77590C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnection.h"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnection.h"; sourceTree = "SOURCE_ROOT"; }; | 4010F841656A5089C77590C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnection.h"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnection.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 40C5B7300EBBF52E3B7FD402 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CriticalSection.h"; path = "../../../../modules/juce_core/threads/juce_CriticalSection.h"; sourceTree = "SOURCE_ROOT"; }; | 40C5B7300EBBF52E3B7FD402 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CriticalSection.h"; path = "../../../../modules/juce_core/threads/juce_CriticalSection.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 416D1E80C31864739829BBD3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MusicDeviceBase.h; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 417401D474422540C54F7700 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutManager.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h"; sourceTree = "SOURCE_ROOT"; }; | 417401D474422540C54F7700 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutManager.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 41EE7512746D88ACB108362B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp"; sourceTree = "SOURCE_ROOT"; }; | 41EE7512746D88ACB108362B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 42458330B018CCF81D0931CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathStrokeType.h"; path = "../../../../modules/juce_graphics/geometry/juce_PathStrokeType.h"; sourceTree = "SOURCE_ROOT"; }; | 42458330B018CCF81D0931CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathStrokeType.h"; path = "../../../../modules/juce_graphics/geometry/juce_PathStrokeType.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -319,7 +314,6 @@ | |||||
| 44B6E666E32F637DF7823CF2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; | 44B6E666E32F637DF7823CF2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 44DF2CBDEE1E27DBF3FFD639 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Initialisation.h"; path = "../../../../modules/juce_events/messages/juce_Initialisation.h"; sourceTree = "SOURCE_ROOT"; }; | 44DF2CBDEE1E27DBF3FFD639 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Initialisation.h"; path = "../../../../modules/juce_events/messages/juce_Initialisation.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4514B5F7DBC9B5A3E014C4CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Point.h"; path = "../../../../modules/juce_graphics/geometry/juce_Point.h"; sourceTree = "SOURCE_ROOT"; }; | 4514B5F7DBC9B5A3E014C4CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Point.h"; path = "../../../../modules/juce_graphics/geometry/juce_Point.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4550EB50BD17ADECC674C83C = {isa = PBXFileReference; lastKnownFileType = file.r; name = AUResources.r; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUResources.r; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 45C2C296C9A745B292F49C65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Atomic.h"; path = "../../../../modules/juce_core/memory/juce_Atomic.h"; sourceTree = "SOURCE_ROOT"; }; | 45C2C296C9A745B292F49C65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Atomic.h"; path = "../../../../modules/juce_core/memory/juce_Atomic.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 460FC41A761B1DBEF6DE8C8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageSequence.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.h"; sourceTree = "SOURCE_ROOT"; }; | 460FC41A761B1DBEF6DE8C8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageSequence.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 464FB7FCF24EAA87AE670472 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputSource.h"; path = "../../../../modules/juce_core/streams/juce_FileInputSource.h"; sourceTree = "SOURCE_ROOT"; }; | 464FB7FCF24EAA87AE670472 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputSource.h"; path = "../../../../modules/juce_core/streams/juce_FileInputSource.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -334,14 +328,12 @@ | |||||
| 4912E679D7789579BDF68CBE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextDiff.cpp"; path = "../../../../modules/juce_core/text/juce_TextDiff.cpp"; sourceTree = "SOURCE_ROOT"; }; | 4912E679D7789579BDF68CBE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextDiff.cpp"; path = "../../../../modules/juce_core/text/juce_TextDiff.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 499974142017D18C15D5AE2A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"; sourceTree = "SOURCE_ROOT"; }; | 499974142017D18C15D5AE2A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4999A3C6B9B1FCE2FA75E26B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryOutputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | 4999A3C6B9B1FCE2FA75E26B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryOutputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4A6A465D7BC825BB91F562C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUOutputBase.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUOutputBase.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 4AB9AA07703E3BAE99B586C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GroupComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_GroupComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 4AB9AA07703E3BAE99B586C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GroupComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_GroupComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4B01C1EF1219C6405CD9A061 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 4B01C1EF1219C6405CD9A061 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4B13AFACB5B6B81347E6652D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RecentlyOpenedFilesList.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp"; sourceTree = "SOURCE_ROOT"; }; | 4B13AFACB5B6B81347E6652D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RecentlyOpenedFilesList.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4B7CE8D596B3F3901B2A7826 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_basics.h"; path = "../../../../modules/juce_audio_basics/juce_audio_basics.h"; sourceTree = "SOURCE_ROOT"; }; | 4B7CE8D596B3F3901B2A7826 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_basics.h"; path = "../../../../modules/juce_audio_basics/juce_audio_basics.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4BDFDEDCF05F480BB99EE8A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseListener.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseListener.cpp"; sourceTree = "SOURCE_ROOT"; }; | 4BDFDEDCF05F480BB99EE8A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseListener.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseListener.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4BEE40628E4C3581FF774383 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AnimatedAppComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 4BEE40628E4C3581FF774383 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AnimatedAppComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4C4DA110B4ABCD9A9CBE93E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUViewLocalizedStringKeys.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUViewBase/AUViewLocalizedStringKeys.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 4CE2C5B8F3B9176330D7E38D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedPipe.cpp"; path = "../../../../modules/juce_core/network/juce_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; | 4CE2C5B8F3B9176330D7E38D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedPipe.cpp"; path = "../../../../modules/juce_core/network/juce_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4D57626C71E0A81969B64FFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODeviceType.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h"; sourceTree = "SOURCE_ROOT"; }; | 4D57626C71E0A81969B64FFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODeviceType.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 4D669F9349F7061E90B1DCDC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; | 4D669F9349F7061E90B1DCDC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -361,12 +353,10 @@ | |||||
| 50F1E35F917489F92521D617 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableCornerComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 50F1E35F917489F92521D617 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableCornerComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 513637A8BE7D94200DCBD1F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsContext.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; | 513637A8BE7D94200DCBD1F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsContext.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 513BA2176B24BC61831B58FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V2.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h"; sourceTree = "SOURCE_ROOT"; }; | 513BA2176B24BC61831B58FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V2.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 519C6BF83160A6B581905C58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUOutputElement.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUOutputElement.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 522D22FEB38D52304F01508D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipClient.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h"; sourceTree = "SOURCE_ROOT"; }; | 522D22FEB38D52304F01508D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipClient.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 525EF648F69C3D42DA9B06E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../../../modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; | 525EF648F69C3D42DA9B06E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../../../modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 528C0C08C23994B09945896C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colours.h"; path = "../../../../modules/juce_graphics/colour/juce_Colours.h"; sourceTree = "SOURCE_ROOT"; }; | 528C0C08C23994B09945896C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colours.h"; path = "../../../../modules/juce_graphics/colour/juce_Colours.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 52CEDC13A7802C7CD55F01A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioTransportSource.cpp"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp"; sourceTree = "SOURCE_ROOT"; }; | 52CEDC13A7802C7CD55F01A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioTransportSource.cpp"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 534561E5F94B5D7A093485DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAAudioChannelLayout.cpp; path = Extras/CoreAudio/PublicUtility/CAAudioChannelLayout.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 534F8743733885F462809C8F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentPeer.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.cpp"; sourceTree = "SOURCE_ROOT"; }; | 534F8743733885F462809C8F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentPeer.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 537D65EF3BBBDFC4651D389D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; | 537D65EF3BBBDFC4651D389D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; | ||||
| 538BF18F9D29A2A60EF6A6CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsDisplayComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 538BF18F9D29A2A60EF6A6CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsDisplayComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -374,7 +364,6 @@ | |||||
| 5535A6B1099BB113B17C42DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDReader.mm"; path = "../../../../modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm"; sourceTree = "SOURCE_ROOT"; }; | 5535A6B1099BB113B17C42DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDReader.mm"; path = "../../../../modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 55607B89BB15CE19B6E397E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationProperties.h"; path = "../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.h"; sourceTree = "SOURCE_ROOT"; }; | 55607B89BB15CE19B6E397E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationProperties.h"; path = "../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5585BCF8B17AD03D9FB4A32A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarComponent.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 5585BCF8B17AD03D9FB4A32A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarComponent.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5631EA8ECD79655B6BEDF8A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUCarbonViewDispatch.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewDispatch.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 5647736926AE116B8C392630 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConcertinaPanel.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.h"; sourceTree = "SOURCE_ROOT"; }; | 5647736926AE116B8C392630 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConcertinaPanel.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 56A295F04B7F248D0A52B878 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Fonts.mm"; path = "../../../../modules/juce_graphics/native/juce_mac_Fonts.mm"; sourceTree = "SOURCE_ROOT"; }; | 56A295F04B7F248D0A52B878 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Fonts.mm"; path = "../../../../modules/juce_graphics/native/juce_mac_Fonts.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 56BFD67859B81D9E53F5B727 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_URL.cpp"; path = "../../../../modules/juce_core/network/juce_URL.cpp"; sourceTree = "SOURCE_ROOT"; }; | 56BFD67859B81D9E53F5B727 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_URL.cpp"; path = "../../../../modules/juce_core/network/juce_URL.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -395,15 +384,14 @@ | |||||
| 5B1CD485D0BA99FEA4B09BC6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BooleanPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 5B1CD485D0BA99FEA4B09BC6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BooleanPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5B50BE8BDF7AE3C403DEF232 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colours.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colours.cpp"; sourceTree = "SOURCE_ROOT"; }; | 5B50BE8BDF7AE3C403DEF232 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colours.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colours.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5BE5D2C8BD79AA4B1D2A24D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDiff.h"; path = "../../../../modules/juce_core/text/juce_TextDiff.h"; sourceTree = "SOURCE_ROOT"; }; | 5BE5D2C8BD79AA4B1D2A24D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDiff.h"; path = "../../../../modules/juce_core/text/juce_TextDiff.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5C407CFD81A7E81FA35D5544 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUSilentTimeout.h; path = Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUSilentTimeout.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 5C49246ADF3F5AA9639EF915 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AlertWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_AlertWindow.h"; sourceTree = "SOURCE_ROOT"; }; | 5C49246ADF3F5AA9639EF915 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AlertWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_AlertWindow.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5C5E3AF3EB9BE171FD53666A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_utils.mm"; path = "../../../../modules/juce_audio_utils/juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; }; | 5C5E3AF3EB9BE171FD53666A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_utils.mm"; path = "../../../../modules/juce_audio_utils/juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5C7825FEE1CBF90AC0E3FE84 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_win32_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; | 5C7825FEE1CBF90AC0E3FE84 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_win32_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5C9E323856342E63607189B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputStream.h"; path = "../../../../modules/juce_core/files/juce_FileInputStream.h"; sourceTree = "SOURCE_ROOT"; }; | 5C9E323856342E63607189B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputStream.h"; path = "../../../../modules/juce_core/files/juce_FileInputStream.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5CC9E5327AB45BC5E12E7C49 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MACAddress.h"; path = "../../../../modules/juce_core/network/juce_MACAddress.h"; sourceTree = "SOURCE_ROOT"; }; | 5CC9E5327AB45BC5E12E7C49 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MACAddress.h"; path = "../../../../modules/juce_core/network/juce_MACAddress.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5DAA9288D1FC19812E6ABA3D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUCarbonViewDispatch.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUCarbonViewDispatch.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 5E354B48397B1478736E6F0D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreAudio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; | 5E354B48397B1478736E6F0D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreAudio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5E69C0346462512B115AE7BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ios_Audio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; | 5E69C0346462512B115AE7BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ios_Audio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5E90DDA49E067C3DF60891AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUBuffer.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUBuffer.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 5EA72D1F22006B0CC17B081E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooserDialogBox.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp"; sourceTree = "SOURCE_ROOT"; }; | 5EA72D1F22006B0CC17B081E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooserDialogBox.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5EB55A7484EFAF1FE8C5BADD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawablePath.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"; sourceTree = "SOURCE_ROOT"; }; | 5EB55A7484EFAF1FE8C5BADD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawablePath.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 5EE4BB25075E3ACDCFCE14D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Rectangle.h"; path = "../../../../modules/juce_graphics/geometry/juce_Rectangle.h"; sourceTree = "SOURCE_ROOT"; }; | 5EE4BB25075E3ACDCFCE14D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Rectangle.h"; path = "../../../../modules/juce_graphics/geometry/juce_Rectangle.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -438,7 +426,6 @@ | |||||
| 69BA49B5D5F563FF8918C64C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; | 69BA49B5D5F563FF8918C64C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6A2DA68C812379D32A014951 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Files.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; | 6A2DA68C812379D32A014951 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Files.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6A3C840E1B6CD34CA8C8DB4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GroupComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_GroupComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 6A3C840E1B6CD34CA8C8DB4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GroupComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_GroupComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6A593B7ADFAC09D547EA809D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUCarbonViewBase.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewBase.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 6A72E46DBDCFAD6F7039E739 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Headers.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h"; sourceTree = "SOURCE_ROOT"; }; | 6A72E46DBDCFAD6F7039E739 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Headers.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6A7D750E4C8BF2580F262F76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XMLCodeTokeniser.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; | 6A7D750E4C8BF2580F262F76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XMLCodeTokeniser.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6AAAA6BD093B9CCD11BC26EC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListenerList.h"; path = "../../../../modules/juce_events/broadcasters/juce_ListenerList.h"; sourceTree = "SOURCE_ROOT"; }; | 6AAAA6BD093B9CCD11BC26EC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListenerList.h"; path = "../../../../modules/juce_events/broadcasters/juce_ListenerList.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -446,14 +433,11 @@ | |||||
| 6C4AD1B0CA254C16E38609DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditorKeyMapper.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h"; sourceTree = "SOURCE_ROOT"; }; | 6C4AD1B0CA254C16E38609DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditorKeyMapper.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6C5452492262FE01944BE60C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 6C5452492262FE01944BE60C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6C8619FFBFA374CE3A374481 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessage.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessage.cpp"; sourceTree = "SOURCE_ROOT"; }; | 6C8619FFBFA374CE3A374481 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessage.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessage.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6CE9C1799C65E997A35E22CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CAAUParameter.h; path = Extras/CoreAudio/PublicUtility/CAAUParameter.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 6CEFF94C7852DB3BFA5E29EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VST3_Wrapper.cpp"; path = "../../../../modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp"; sourceTree = "SOURCE_ROOT"; }; | 6CEFF94C7852DB3BFA5E29EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VST3_Wrapper.cpp"; path = "../../../../modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6D085AD80CA57F2F8A5C393B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUDispatch.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUDispatch.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 6DD7B1CA8F5F2857F2210D04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageConvolutionKernel.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp"; sourceTree = "SOURCE_ROOT"; }; | 6DD7B1CA8F5F2857F2210D04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageConvolutionKernel.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6E79399429D2A1B149CCB022 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 6E79399429D2A1B149CCB022 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6EA0F6E82CE987903D0C7B13 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WavAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | 6EA0F6E82CE987903D0C7B13 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WavAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6EC7B55CE9A1E68A89CED63D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableCornerComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 6EC7B55CE9A1E68A89CED63D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableCornerComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6EDD3878142839D368B64F31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUEffectBase.h; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUEffectBase.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 6F381D0C54E869B237830DC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeDocument.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; | 6F381D0C54E869B237830DC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeDocument.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6F3D3E06535036A4B1779FDD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NormalisableRange.h"; path = "../../../../modules/juce_core/maths/juce_NormalisableRange.h"; sourceTree = "SOURCE_ROOT"; }; | 6F3D3E06535036A4B1779FDD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NormalisableRange.h"; path = "../../../../modules/juce_core/maths/juce_NormalisableRange.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 6F80E669C5CD62B01B4047A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Button.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.cpp"; sourceTree = "SOURCE_ROOT"; }; | 6F80E669C5CD62B01B4047A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Button.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -466,10 +450,8 @@ | |||||
| 70D7F049EE6F03FCF08AFB11 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; | 70D7F049EE6F03FCF08AFB11 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 71182371710295A8E05E1536 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MP3AudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; | 71182371710295A8E05E1536 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MP3AudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 71BDE6A5BAEA81ACAE4CDC28 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SliderPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | 71BDE6A5BAEA81ACAE4CDC28 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SliderPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 71CDD3C8D311F7994DD5CC8F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ComponentBase.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/ComponentBase.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 71D1E59DD8BD9FAFF42659AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiFile.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | 71D1E59DD8BD9FAFF42659AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiFile.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7224CC95ABFD72D07AEC0A9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemFactory.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h"; sourceTree = "SOURCE_ROOT"; }; | 7224CC95ABFD72D07AEC0A9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemFactory.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 728F423CEB1B9E6CA8545895 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUOutputBase.h; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUOutputBase.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 72C93E5C4D67FBDA352C4F08 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DocumentWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | 72C93E5C4D67FBDA352C4F08 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DocumentWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 732FA0A6EBB881C0D5085541 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_EdgeTable.h"; path = "../../../../modules/juce_graphics/geometry/juce_EdgeTable.h"; sourceTree = "SOURCE_ROOT"; }; | 732FA0A6EBB881C0D5085541 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_EdgeTable.h"; path = "../../../../modules/juce_graphics/geometry/juce_EdgeTable.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 733D78081DDEDCBA60B26614 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorListener.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h"; sourceTree = "SOURCE_ROOT"; }; | 733D78081DDEDCBA60B26614 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorListener.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -477,11 +459,11 @@ | |||||
| 736524AA87397E0C2C9C8817 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageCollector.h"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h"; sourceTree = "SOURCE_ROOT"; }; | 736524AA87397E0C2C9C8817 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageCollector.h"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7368195ADDFA8909053F98D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_ObjCHelpers.h"; path = "../../../../modules/juce_core/native/juce_osx_ObjCHelpers.h"; sourceTree = "SOURCE_ROOT"; }; | 7368195ADDFA8909053F98D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_ObjCHelpers.h"; path = "../../../../modules/juce_core/native/juce_osx_ObjCHelpers.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7368B0046A2F265498F9DD5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyMappingEditorComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 7368B0046A2F265498F9DD5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyMappingEditorComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 739336D279C585C749F3039A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUMIDIEffectBase.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUMIDIEffectBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 745D6A06B95F8E9CAFBB0CC8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorPlayer.cpp"; path = "../../../../modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp"; sourceTree = "SOURCE_ROOT"; }; | 745D6A06B95F8E9CAFBB0CC8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorPlayer.cpp"; path = "../../../../modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 74BB4F18BE439D41BFBA36A7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Line.h"; path = "../../../../modules/juce_graphics/geometry/juce_Line.h"; sourceTree = "SOURCE_ROOT"; }; | 74BB4F18BE439D41BFBA36A7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Line.h"; path = "../../../../modules/juce_graphics/geometry/juce_Line.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 74BD335259545B5C8FAE3942 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../../../modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; }; | 74BD335259545B5C8FAE3942 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../../../modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 74F2DCF770F5C64372FD4247 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AiffAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | 74F2DCF770F5C64372FD4247 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AiffAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 74F64B7ADDA82099E04331FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ComponentBase.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/ComponentBase.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 750F3B1989AEC12FF245BE70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PluginEditor.h; path = ../../Source/PluginEditor.h; sourceTree = "SOURCE_ROOT"; }; | 750F3B1989AEC12FF245BE70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PluginEditor.h; path = ../../Source/PluginEditor.h; sourceTree = "SOURCE_ROOT"; }; | ||||
| 753D44FB980D9BAD93995C1C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorParameter.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h"; sourceTree = "SOURCE_ROOT"; }; | 753D44FB980D9BAD93995C1C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorParameter.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7541F65B3F7500294E6F528F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertySet.h"; path = "../../../../modules/juce_core/containers/juce_PropertySet.h"; sourceTree = "SOURCE_ROOT"; }; | 7541F65B3F7500294E6F528F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertySet.h"; path = "../../../../modules/juce_core/containers/juce_PropertySet.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -500,12 +482,10 @@ | |||||
| 78959840E3EF9DC06998BB42 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; | 78959840E3EF9DC06998BB42 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7997E4EB2706B00B44880412 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_extra.h"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.h"; sourceTree = "SOURCE_ROOT"; }; | 7997E4EB2706B00B44880412 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_extra.h"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 79B3B7E2DD82AB16C411D9E0 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_graphics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | 79B3B7E2DD82AB16C411D9E0 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_graphics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 79B958A028493E0DB0133E2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAVectorUnit.cpp; path = Extras/CoreAudio/PublicUtility/CAVectorUnit.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 7A1CD659BB507996CC7EE951 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedAppComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 7A1CD659BB507996CC7EE951 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedAppComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7A56C13F02DFBCBC0375F0F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_curl_Network.cpp"; path = "../../../../modules/juce_core/native/juce_curl_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | 7A56C13F02DFBCBC0375F0F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_curl_Network.cpp"; path = "../../../../modules/juce_core/native/juce_curl_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7AC8B40A09251FDC9D75053A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPCompressorOutputStream.h"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; | 7AC8B40A09251FDC9D75053A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPCompressorOutputStream.h"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7B2A0D30289D548DCF3AC985 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertiesFile.cpp"; path = "../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | 7B2A0D30289D548DCF3AC985 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertiesFile.cpp"; path = "../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7B491514CCDB29EBB9674F9E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CADebugMacros.h; path = Extras/CoreAudio/PublicUtility/CADebugMacros.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 7B7DC20A834735F004A8A0C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourSelector.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_ColourSelector.cpp"; sourceTree = "SOURCE_ROOT"; }; | 7B7DC20A834735F004A8A0C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourSelector.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_ColourSelector.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7B870EE6D43B984CADE69C28 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CarbonVisibility.h"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_CarbonVisibility.h"; sourceTree = "SOURCE_ROOT"; }; | 7B870EE6D43B984CADE69C28 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CarbonVisibility.h"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_CarbonVisibility.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 7C6A0C6C2914BD052CB4702A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DragAndDropContainer.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp"; sourceTree = "SOURCE_ROOT"; }; | 7C6A0C6C2914BD052CB4702A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DragAndDropContainer.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -560,8 +540,10 @@ | |||||
| 8718970FF3F3F2AC38191F53 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.h"; sourceTree = "SOURCE_ROOT"; }; | 8718970FF3F3F2AC38191F53 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 87755AF25BF68EE19666A135 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_graphics.mm"; path = "../../../../modules/juce_graphics/juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; }; | 87755AF25BF68EE19666A135 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_graphics.mm"; path = "../../../../modules/juce_graphics/juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 87BE12FCBC4C554059FA344F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; | 87BE12FCBC4C554059FA344F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 87DBD7450AE0FDD762712620 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAMutex.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/CAMutex.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 87FA97D4268B5DAE05BAD596 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CompilerSupport.h"; path = "../../../../modules/juce_core/system/juce_CompilerSupport.h"; sourceTree = "SOURCE_ROOT"; }; | 87FA97D4268B5DAE05BAD596 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CompilerSupport.h"; path = "../../../../modules/juce_core/system/juce_CompilerSupport.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 88336AF4E2605BF6518D758B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageManager.h"; path = "../../../../modules/juce_events/messages/juce_MessageManager.h"; sourceTree = "SOURCE_ROOT"; }; | 88336AF4E2605BF6518D758B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageManager.h"; path = "../../../../modules/juce_events/messages/juce_MessageManager.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 88F2FC5C63F1BA3184DC38BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUEffectBase.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUEffectBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 890AA995A158C4D9E7738A40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSampleBuffer.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h"; sourceTree = "SOURCE_ROOT"; }; | 890AA995A158C4D9E7738A40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSampleBuffer.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 8916485BFFBA840EF46760CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeDocument.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.h"; sourceTree = "SOURCE_ROOT"; }; | 8916485BFFBA840EF46760CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeDocument.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 894982322611830C62233292 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PositionableAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_PositionableAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; | 894982322611830C62233292 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PositionableAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_PositionableAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -571,7 +553,6 @@ | |||||
| 89E2E6BA6057311E66E8A8BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrayAllocationBase.h"; path = "../../../../modules/juce_core/containers/juce_ArrayAllocationBase.h"; sourceTree = "SOURCE_ROOT"; }; | 89E2E6BA6057311E66E8A8BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrayAllocationBase.h"; path = "../../../../modules/juce_core/containers/juce_ArrayAllocationBase.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 8AE97D16E9DA460011B379BA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadower.h"; path = "../../../../modules/juce_gui_basics/misc/juce_DropShadower.h"; sourceTree = "SOURCE_ROOT"; }; | 8AE97D16E9DA460011B379BA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadower.h"; path = "../../../../modules/juce_gui_basics/misc/juce_DropShadower.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 8AEC8C684E53D6E14FC97605 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../../../modules/juce_events/native/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; }; | 8AEC8C684E53D6E14FC97605 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../../../modules/juce_events/native/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 8B184C08A51AA14F56E42152 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUBase.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUBase.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 8BBD921B5A82DB52E6842A1B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_ScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; | 8BBD921B5A82DB52E6842A1B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_ScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 8C0D1A1E000E47D09B771963 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginUtilities.cpp"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp"; sourceTree = "SOURCE_ROOT"; }; | 8C0D1A1E000E47D09B771963 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginUtilities.cpp"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 8C1A068D665727680931F85C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoManager.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoManager.h"; sourceTree = "SOURCE_ROOT"; }; | 8C1A068D665727680931F85C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoManager.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoManager.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -615,9 +596,9 @@ | |||||
| 93F82D964A8C329766946277 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsContext.h"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; | 93F82D964A8C329766946277 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsContext.h"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 94AA9AF4939F914AD00CEE1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CheckSettingMacros.h"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h"; sourceTree = "SOURCE_ROOT"; }; | 94AA9AF4939F914AD00CEE1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CheckSettingMacros.h"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 94D07EE2982807A4BB2E0CBB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChildProcess.h"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; | 94D07EE2982807A4BB2E0CBB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChildProcess.h"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 95FF785BAEC4F2799A75D2FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUCarbonViewBase.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUCarbonViewBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| 963140B9984908CF118F92F1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h"; sourceTree = "SOURCE_ROOT"; }; | 963140B9984908CF118F92F1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 965F7DCC8CF46085A636D851 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Desktop.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_Desktop.cpp"; sourceTree = "SOURCE_ROOT"; }; | 965F7DCC8CF46085A636D851 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Desktop.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_Desktop.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 969CF69D90AC73918B9BB0CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUEffectBase.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUEffectBase.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 96C79B505CA4FD6FFDC28D94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlowEffect.cpp"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; | 96C79B505CA4FD6FFDC28D94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlowEffect.cpp"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 988CB13161D84307D53770D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../../../modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; | 988CB13161D84307D53770D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../../../modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 990E71F1F4EB7B98AEEE3D05 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentPeer.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.h"; sourceTree = "SOURCE_ROOT"; }; | 990E71F1F4EB7B98AEEE3D05 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentPeer.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -625,7 +606,6 @@ | |||||
| 996E86CC90360798D87EE1A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; }; | 996E86CC90360798D87EE1A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 99E71BE7C7C30E6BDFAAFA32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextInputTarget.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextInputTarget.h"; sourceTree = "SOURCE_ROOT"; }; | 99E71BE7C7C30E6BDFAAFA32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextInputTarget.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextInputTarget.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 9A097CC9A7C64CB8958F89B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Midi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; | 9A097CC9A7C64CB8958F89B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Midi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 9A1D1CECCBA42358E4E62859 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUCarbonViewBase.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewBase.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| 9A6686BC6FC38F6D1917D7C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LADSPAPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; | 9A6686BC6FC38F6D1917D7C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LADSPAPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 9B3F11DD2E09FC8F63555D30 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_devices.mm"; path = "../../../../modules/juce_audio_devices/juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; }; | 9B3F11DD2E09FC8F63555D30 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_devices.mm"; path = "../../../../modules/juce_audio_devices/juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 9B7A0A69E4002D6C125F895D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_ALSA.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp"; sourceTree = "SOURCE_ROOT"; }; | 9B7A0A69E4002D6C125F895D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_ALSA.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -645,24 +625,21 @@ | |||||
| 9F6A1FA82A8C412622129993 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentMovementWatcher.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp"; sourceTree = "SOURCE_ROOT"; }; | 9F6A1FA82A8C412622129993 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentMovementWatcher.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| 9F9AC54CF90FDB770E5FCA03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WeakReference.h"; path = "../../../../modules/juce_core/memory/juce_WeakReference.h"; sourceTree = "SOURCE_ROOT"; }; | 9F9AC54CF90FDB770E5FCA03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WeakReference.h"; path = "../../../../modules/juce_core/memory/juce_WeakReference.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A0AB27A8CE89B12B37EF8FA4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MP3AudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | A0AB27A8CE89B12B37EF8FA4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MP3AudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A10B7B85424CB38AE344D7DC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CAVectorUnitTypes.h; path = Extras/CoreAudio/PublicUtility/CAVectorUnitTypes.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| A11F51909BE2463C28099C0B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActiveXControlComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"; sourceTree = "SOURCE_ROOT"; }; | A11F51909BE2463C28099C0B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActiveXControlComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A122A2AB08B82B5AF1FF4D0A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KnownPluginList.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp"; sourceTree = "SOURCE_ROOT"; }; | A122A2AB08B82B5AF1FF4D0A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KnownPluginList.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A1A74C33F871DF7D5E3C4B65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectangleList.h"; path = "../../../../modules/juce_graphics/geometry/juce_RectangleList.h"; sourceTree = "SOURCE_ROOT"; }; | A1A74C33F871DF7D5E3C4B65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectangleList.h"; path = "../../../../modules/juce_graphics/geometry/juce_RectangleList.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A206765795252391D3F60EA4 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; | A206765795252391D3F60EA4 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; | ||||
| A21E0C7AD5B7950C37912A31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Variant.cpp"; path = "../../../../modules/juce_core/containers/juce_Variant.cpp"; sourceTree = "SOURCE_ROOT"; }; | A21E0C7AD5B7950C37912A31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Variant.cpp"; path = "../../../../modules/juce_core/containers/juce_Variant.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A2605C2C8D583851AD65025E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReadWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; | A2605C2C8D583851AD65025E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReadWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A2BAB9DD00DF8E30A6DF756E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUMIDIBase.h; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| A2F1B4E1DE5CAA9FB76C01B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF32.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF32.h"; sourceTree = "SOURCE_ROOT"; }; | A2F1B4E1DE5CAA9FB76C01B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF32.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF32.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A31CE7177BF947DB60F72D94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleMessageComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | A31CE7177BF947DB60F72D94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleMessageComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A52038A2E61AB03CF55A3B0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioFormatReader.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; | A52038A2E61AB03CF55A3B0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioFormatReader.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A5985F8B03893AA7EFD0273A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAAUParameter.cpp; path = Extras/CoreAudio/PublicUtility/CAAUParameter.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| A59A08DCC76EE0FC7EBE1203 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; | A59A08DCC76EE0FC7EBE1203 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; | ||||
| A62DF2CD31D7890E1B54B18C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUScopeElement.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUScopeElement.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| A722B041FD2540D1380C4D02 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; | A722B041FD2540D1380C4D02 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A7A527D783D3B38F455964D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnectionServer.h"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.h"; sourceTree = "SOURCE_ROOT"; }; | A7A527D783D3B38F455964D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnectionServer.h"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A7EE73FF3A5962BBF41DC2AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Component.h"; path = "../../../../modules/juce_gui_basics/components/juce_Component.h"; sourceTree = "SOURCE_ROOT"; }; | A7EE73FF3A5962BBF41DC2AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Component.h"; path = "../../../../modules/juce_gui_basics/components/juce_Component.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A7FD436305E19DF69A7AF446 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DragAndDrop.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp"; sourceTree = "SOURCE_ROOT"; }; | A7FD436305E19DF69A7AF446 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DragAndDrop.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A8BA67A9567A51069D275EBB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ComponentBase.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/ComponentBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| A8F3FC233163016FE3B23543 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathIterator.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; | A8F3FC233163016FE3B23543 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathIterator.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A90A45FB8790A91DF1A78BE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBuilder.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.h"; sourceTree = "SOURCE_ROOT"; }; | A90A45FB8790A91DF1A78BE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBuilder.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| A90E41C0C52BDF0CC82161C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; | A90E41C0C52BDF0CC82161C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -672,6 +649,7 @@ | |||||
| A9C466FBA4FCF6484BCF86A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; }; | A9C466FBA4FCF6484BCF86A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AA29B047C1A1904618B410D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableObjectResizer.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h"; sourceTree = "SOURCE_ROOT"; }; | AA29B047C1A1904618B410D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableObjectResizer.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AAA122282581E6425F5D9405 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OggVorbisAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | AAA122282581E6425F5D9405 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OggVorbisAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AABC1F4E7D9DA3C6B6DC0F05 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUBuffer.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| AB7726FF34DB2E7FA75ECC19 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | AB7726FF34DB2E7FA75ECC19 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AB87317D90A518C8A886EE9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDeviceSelectorComponent.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h"; sourceTree = "SOURCE_ROOT"; }; | AB87317D90A518C8A886EE9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDeviceSelectorComponent.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| ABC394D5E03B690404E80E1E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; | ABC394D5E03B690404E80E1E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -699,8 +677,7 @@ | |||||
| AAEC41BFA57E45EBF94ED3C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableImage.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.cpp"; sourceTree = "SOURCE_ROOT"; }; | AAEC41BFA57E45EBF94ED3C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableImage.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AB0E8347C9AC7E4A861C0252 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilterAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; | AB0E8347C9AC7E4A861C0252 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilterAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AB10327C69AAE4AACCFC81EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableText.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableText.cpp"; sourceTree = "SOURCE_ROOT"; }; | AB10327C69AAE4AACCFC81EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableText.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableText.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AB7BCFBC4B2CB784F57A0FBC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUInputFormatConverter.h; path = Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUInputFormatConverter.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| AB9AD07EF899B75AC4CF01DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CAMutex.h; path = Extras/CoreAudio/PublicUtility/CAMutex.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| AC4612F7E064ECEC2E95B129 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAStreamBasicDescription.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/CAStreamBasicDescription.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| AC5452F5122E3A4B670B5185 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioThumbnail.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioThumbnail.h"; sourceTree = "SOURCE_ROOT"; }; | AC5452F5122E3A4B670B5185 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioThumbnail.h"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioThumbnail.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| ACC4E765AD4BF1D025FB4E83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Network.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | ACC4E765AD4BF1D025FB4E83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Network.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| ACDF0E99B316A7C266F6EFFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LAMEEncoderAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | ACDF0E99B316A7C266F6EFFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LAMEEncoderAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -709,13 +686,13 @@ | |||||
| AE3C497B58239EA75FD18AD9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlyphArrangement.h"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.h"; sourceTree = "SOURCE_ROOT"; }; | AE3C497B58239EA75FD18AD9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlyphArrangement.h"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AEE273E29C5B07B96BAFFA46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedArray.h"; path = "../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h"; sourceTree = "SOURCE_ROOT"; }; | AEE273E29C5B07B96BAFFA46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedArray.h"; path = "../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AF14FDB3693F569F275C1A8C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Files.mm"; path = "../../../../modules/juce_core/native/juce_mac_Files.mm"; sourceTree = "SOURCE_ROOT"; }; | AF14FDB3693F569F275C1A8C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Files.mm"; path = "../../../../modules/juce_core/native/juce_mac_Files.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| AFE00126A5FEF419332CD2B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUOutputElement.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUOutputElement.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| B0381BEAE259ABDDE18A64B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | B0381BEAE259ABDDE18A64B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B1426528BB892D5736D80404 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; | B1426528BB892D5736D80404 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B2067C8614967BECF8B198D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; }; | B2067C8614967BECF8B198D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B23CBCBBD05E21AEA76FB9E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDirectoryScanner.h"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h"; sourceTree = "SOURCE_ROOT"; }; | B23CBCBBD05E21AEA76FB9E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDirectoryScanner.h"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B287E8FA86ED37F618F0ABC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SubregionStream.cpp"; path = "../../../../modules/juce_core/streams/juce_SubregionStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | B287E8FA86ED37F618F0ABC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SubregionStream.cpp"; path = "../../../../modules/juce_core/streams/juce_SubregionStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B2B54E113A80EC53D5D71A38 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_gui_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | B2B54E113A80EC53D5D71A38 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_gui_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B318D50696B303889BDCF072 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUMIDIEffectBase.h; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| B34E109560D77640B7648C4D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; | B34E109560D77640B7648C4D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B45645B3B2E19FB1D72B91B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AiffAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; | B45645B3B2E19FB1D72B91B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AiffAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B532D9954FB106B6095AE0C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilenameComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h"; sourceTree = "SOURCE_ROOT"; }; | B532D9954FB106B6095AE0C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilenameComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -723,6 +700,7 @@ | |||||
| B57C430D154C1C86350F246A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CustomTypeface.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; | B57C430D154C1C86350F246A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CustomTypeface.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B57D00796D30ECB2DE58035F = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_utils/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | B57D00796D30ECB2DE58035F = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_utils/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B5FF7C5554FC26100CB08626 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FillType.h"; path = "../../../../modules/juce_graphics/colour/juce_FillType.h"; sourceTree = "SOURCE_ROOT"; }; | B5FF7C5554FC26100CB08626 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FillType.h"; path = "../../../../modules/juce_graphics/colour/juce_FillType.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B6394C38B7A283DE86213FAE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUOutputBase.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUOutputBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| B65F0500A687634E095C17E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInactivityDetector.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h"; sourceTree = "SOURCE_ROOT"; }; | B65F0500A687634E095C17E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInactivityDetector.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B6938F0B102875B8B0BEBC44 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PreferencesPanel.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | B6938F0B102875B8B0BEBC44 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PreferencesPanel.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| B72762B6ACA5F73EF9F0A220 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GenericAudioProcessorEditor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; | B72762B6ACA5F73EF9F0A220 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GenericAudioProcessorEditor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -737,7 +715,6 @@ | |||||
| BBBE74C4A9FA85B5F29FF346 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | BBBE74C4A9FA85B5F29FF346 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| BBECA9EB9DD3C9B6CB04B10A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Uuid.h"; path = "../../../../modules/juce_core/misc/juce_Uuid.h"; sourceTree = "SOURCE_ROOT"; }; | BBECA9EB9DD3C9B6CB04B10A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Uuid.h"; path = "../../../../modules/juce_core/misc/juce_Uuid.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| BBF88983012D33EFEF11EA81 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | BBF88983012D33EFEF11EA81 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| BC369095BAEED8707D12F63B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAStreamBasicDescription.cpp; path = Extras/CoreAudio/PublicUtility/CAStreamBasicDescription.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| BCB54D2E4C0C3357DACFD29B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NSViewComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; | BCB54D2E4C0C3357DACFD29B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NSViewComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| BCE8039887ABB9343A257AFC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessor.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.h"; sourceTree = "SOURCE_ROOT"; }; | BCE8039887ABB9343A257AFC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessor.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| BD1EC91E61ECEAB657C78D5C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Toolbar.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Toolbar.cpp"; sourceTree = "SOURCE_ROOT"; }; | BD1EC91E61ECEAB657C78D5C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Toolbar.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Toolbar.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -799,7 +776,6 @@ | |||||
| CF5FA6C569EF0D70C967EE90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SVGParser.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_SVGParser.cpp"; sourceTree = "SOURCE_ROOT"; }; | CF5FA6C569EF0D70C967EE90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SVGParser.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_SVGParser.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| CF82A46D7CDDAFC5B46AFBC5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditor.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.h"; sourceTree = "SOURCE_ROOT"; }; | CF82A46D7CDDAFC5B46AFBC5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditor.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| CF9911FF44333EF9154A6141 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; | CF9911FF44333EF9154A6141 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| D010985AB6D7A05BA96EB868 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CarbonEventHandler.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/CarbonEventHandler.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| D0406C91AA87E22F071648A8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharacterFunctions.h"; path = "../../../../modules/juce_core/text/juce_CharacterFunctions.h"; sourceTree = "SOURCE_ROOT"; }; | D0406C91AA87E22F071648A8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharacterFunctions.h"; path = "../../../../modules/juce_core/text/juce_CharacterFunctions.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| D120181C3218F30A0102BC17 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CaretComponent.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | D120181C3218F30A0102BC17 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CaretComponent.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| D18B1676A7BB2890B81717FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentMovementWatcher.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"; sourceTree = "SOURCE_ROOT"; }; | D18B1676A7BB2890B81717FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentMovementWatcher.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -866,8 +842,7 @@ | |||||
| DFF5523D4F5396F98114B642 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AffineTransform.h"; path = "../../../../modules/juce_graphics/geometry/juce_AffineTransform.h"; sourceTree = "SOURCE_ROOT"; }; | DFF5523D4F5396F98114B642 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AffineTransform.h"; path = "../../../../modules/juce_graphics/geometry/juce_AffineTransform.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E0461DEB1F6D01A42E288646 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Button.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.h"; sourceTree = "SOURCE_ROOT"; }; | E0461DEB1F6D01A42E288646 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Button.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E04D8B4BAEB817D520C2EF4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OptionalScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_OptionalScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; | E04D8B4BAEB817D520C2EF4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OptionalScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_OptionalScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E08045246EF1A84C7A4D9DF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUCarbonViewControl.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewControl.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| E0A48CA97D4C946F632C0DB7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUInputElement.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUInputElement.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| E0657C5A5A08F4B5BE55034A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUCarbonViewControl.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUCarbonViewControl.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| E0DDE45DB4B87F9311191965 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiFile.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiFile.h"; sourceTree = "SOURCE_ROOT"; }; | E0DDE45DB4B87F9311191965 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiFile.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiFile.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E0EE8480E1438F1521ABC0DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; | E0EE8480E1438F1521ABC0DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E15C0D3B2B648FE732D07ABD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleComponent.cpp"; path = "../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | E15C0D3B2B648FE732D07ABD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleComponent.cpp"; path = "../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -878,12 +853,13 @@ | |||||
| E398182BD8543E6B845F2255 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePoint.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.cpp"; sourceTree = "SOURCE_ROOT"; }; | E398182BD8543E6B845F2255 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePoint.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E3A38E6B33797818F62CD77E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinatePositioner.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"; sourceTree = "SOURCE_ROOT"; }; | E3A38E6B33797818F62CD77E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinatePositioner.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E3F3133499175DC014FC149B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FFT.cpp"; path = "../../../../modules/juce_audio_basics/effects/juce_FFT.cpp"; sourceTree = "SOURCE_ROOT"; }; | E3F3133499175DC014FC149B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FFT.cpp"; path = "../../../../modules/juce_audio_basics/effects/juce_FFT.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E42198F571F1BB1C5203F3D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUMIDIBase.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUMIDIBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| E4606F21F965427E694C1132 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Reverb.h"; path = "../../../../modules/juce_audio_basics/effects/juce_Reverb.h"; sourceTree = "SOURCE_ROOT"; }; | E4606F21F965427E694C1132 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Reverb.h"; path = "../../../../modules/juce_audio_basics/effects/juce_Reverb.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E521DD6592FA0F7828161360 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CAVectorUnit.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/CAVectorUnit.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| E52A19CA27A82BB3ECD76B63 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF16.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF16.h"; sourceTree = "SOURCE_ROOT"; }; | E52A19CA27A82BB3ECD76B63 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF16.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF16.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E57F57DB7857820B9FC7BCFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DeletedAtShutdown.h"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.h"; sourceTree = "SOURCE_ROOT"; }; | E57F57DB7857820B9FC7BCFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DeletedAtShutdown.h"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E5A17AB02D7926E004207D38 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComboBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ComboBox.cpp"; sourceTree = "SOURCE_ROOT"; }; | E5A17AB02D7926E004207D38 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComboBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ComboBox.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E5CD2295E0A994C362D85800 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageSequence.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp"; sourceTree = "SOURCE_ROOT"; }; | E5CD2295E0A994C362D85800 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageSequence.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E5EDE1797446522FADDF78B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CAAudioChannelLayout.h; path = Extras/CoreAudio/PublicUtility/CAAudioChannelLayout.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| E65E231978B796AA7868DC4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_plugin_client.h"; path = "../../../../modules/juce_audio_plugin_client/juce_audio_plugin_client.h"; sourceTree = "SOURCE_ROOT"; }; | E65E231978B796AA7868DC4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_plugin_client.h"; path = "../../../../modules/juce_audio_plugin_client/juce_audio_plugin_client.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E695834F7C3FC81BB41044C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyPanel.h"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.h"; sourceTree = "SOURCE_ROOT"; }; | E695834F7C3FC81BB41044C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyPanel.h"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| E7A0D2A3AAD8192B65EB0141 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioAppComponent.cpp"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | E7A0D2A3AAD8192B65EB0141 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioAppComponent.cpp"; path = "../../../../modules/juce_audio_utils/gui/juce_AudioAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -901,6 +877,7 @@ | |||||
| EA6921266422F00734EF49B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_data_structures.h"; path = "../../../../modules/juce_data_structures/juce_data_structures.h"; sourceTree = "SOURCE_ROOT"; }; | EA6921266422F00734EF49B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_data_structures.h"; path = "../../../../modules/juce_data_structures/juce_data_structures.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EA906B8480C7585912B627B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ByteOrder.h"; path = "../../../../modules/juce_core/memory/juce_ByteOrder.h"; sourceTree = "SOURCE_ROOT"; }; | EA906B8480C7585912B627B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ByteOrder.h"; path = "../../../../modules/juce_core/memory/juce_ByteOrder.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EB3444A4CFC3864FF3F7E4FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../../../modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; }; | EB3444A4CFC3864FF3F7E4FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../../../modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EB38777DCA28E40FF364EAE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUScopeElement.cpp; path = "../../../../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses/AUScopeElement.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||||
| EB8C7BDEF743331241D8BDE3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Label.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.h"; sourceTree = "SOURCE_ROOT"; }; | EB8C7BDEF743331241D8BDE3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Label.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EBF5AAA742C6D9C3DE7BA2CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Identifier.cpp"; path = "../../../../modules/juce_core/text/juce_Identifier.cpp"; sourceTree = "SOURCE_ROOT"; }; | EBF5AAA742C6D9C3DE7BA2CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Identifier.cpp"; path = "../../../../modules/juce_core/text/juce_Identifier.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EC155D21E24BFC61E5205344 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MountedVolumeListChangeDetector.h"; path = "../../../../modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h"; sourceTree = "SOURCE_ROOT"; }; | EC155D21E24BFC61E5205344 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MountedVolumeListChangeDetector.h"; path = "../../../../modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -908,17 +885,14 @@ | |||||
| EC401439D56540696500FB09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableText.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableText.h"; sourceTree = "SOURCE_ROOT"; }; | EC401439D56540696500FB09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableText.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableText.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EC704EDAD7A2015D623B0429 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandID.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"; sourceTree = "SOURCE_ROOT"; }; | EC704EDAD7A2015D623B0429 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandID.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| ED3F8B6AC260A35F53658415 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ED3F8B6AC260A35F53658415 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| ED5C52722B9653FA3B009C01 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AUOutputElement.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUOutputElement.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| ED5E2A6E19327A0F73876C42 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Files.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; | ED5E2A6E19327A0F73876C42 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Files.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EDC019B897AE281105783BFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPairArray.cpp"; path = "../../../../modules/juce_core/text/juce_StringPairArray.cpp"; sourceTree = "SOURCE_ROOT"; }; | EDC019B897AE281105783BFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPairArray.cpp"; path = "../../../../modules/juce_core/text/juce_StringPairArray.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EDD6B4608C8E4C7E7581489D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; }; | EDD6B4608C8E4C7E7581489D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EE149F9075819C0132879D4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_AU_Wrapper.mm"; path = "../../../../modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm"; sourceTree = "SOURCE_ROOT"; }; | EE149F9075819C0132879D4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_AU_Wrapper.mm"; path = "../../../../modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EE1708227B48B586BE17D06B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_android_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; | EE1708227B48B586BE17D06B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_android_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EE6030D7677731D8C2B14CA9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF8.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF8.h"; sourceTree = "SOURCE_ROOT"; }; | EE6030D7677731D8C2B14CA9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF8.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF8.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EE88F9B9461BEE0D11D3EB92 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AUCarbonViewControl.h; path = Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewControl.h; sourceTree = "DEVELOPER_DIR"; }; | |||||
| EECBEDF7C26CF9597CC601D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FlacAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | EECBEDF7C26CF9597CC601D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FlacAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EED2AEDB27E7562C4DCFA637 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TimeSliceThread.h"; path = "../../../../modules/juce_core/threads/juce_TimeSliceThread.h"; sourceTree = "SOURCE_ROOT"; }; | EED2AEDB27E7562C4DCFA637 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TimeSliceThread.h"; path = "../../../../modules/juce_core/threads/juce_TimeSliceThread.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| EFCF0633FF23B5F88112A200 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MusicDeviceBase.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| EFD8E22899758751230A8590 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryOutputStream.h"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; | EFD8E22899758751230A8590 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryOutputStream.h"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| F04CF5D4410243EF3DEDBEB8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Font.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_Font.cpp"; sourceTree = "SOURCE_ROOT"; }; | F04CF5D4410243EF3DEDBEB8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Font.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_Font.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| F0DC1A84185952857B3DCAE8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LagrangeInterpolator.cpp"; path = "../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp"; sourceTree = "SOURCE_ROOT"; }; | F0DC1A84185952857B3DCAE8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LagrangeInterpolator.cpp"; path = "../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -951,7 +925,6 @@ | |||||
| F79C97D63C8C542CFEB404DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReaderSource.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"; sourceTree = "SOURCE_ROOT"; }; | F79C97D63C8C542CFEB404DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReaderSource.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| F79F2406B1605D94EEC822DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicObject.h"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.h"; sourceTree = "SOURCE_ROOT"; }; | F79F2406B1605D94EEC822DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicObject.h"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| F7AD604135D04469C920F456 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReverbAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; | F7AD604135D04469C920F456 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReverbAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| F7AF91E09A9EB00EA5438730 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CarbonEventHandler.cpp; path = Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/CarbonEventHandler.cpp; sourceTree = "DEVELOPER_DIR"; }; | |||||
| F7E2FB533BCB2C8831276D22 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../../../modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; }; | F7E2FB533BCB2C8831276D22 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../../../modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; }; | ||||
| F7EC22087BE9304F03690131 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | F7EC22087BE9304F03690131 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| F80CC5FB6425D6B5DD1BBC59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | F80CC5FB6425D6B5DD1BBC59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | ||||
| @@ -2006,58 +1979,28 @@ | |||||
| F0F89564A3784EB052CEE01B, | F0F89564A3784EB052CEE01B, | ||||
| 3B12C460FF1466EAEDD258A8, | 3B12C460FF1466EAEDD258A8, | ||||
| 777B3EE5ECE5A0B4799E842E, ); name = "Juce Modules"; sourceTree = "<group>"; }; | 777B3EE5ECE5A0B4799E842E, ); name = "Juce Modules"; sourceTree = "<group>"; }; | ||||
| A8A516552AE9B51F35B89B2C = {isa = PBXGroup; children = ( | |||||
| 2B2D54521D69CF4407471A56, | |||||
| 8B184C08A51AA14F56E42152, | |||||
| 5E90DDA49E067C3DF60891AA, | |||||
| 206544B2ADA604E3A68FEF85, | |||||
| 6A593B7ADFAC09D547EA809D, | |||||
| 9A1D1CECCBA42358E4E62859, | |||||
| E08045246EF1A84C7A4D9DF5, | |||||
| EE88F9B9461BEE0D11D3EB92, | |||||
| 5631EA8ECD79655B6BEDF8A3, | |||||
| 374740EFBC17343E10F66F4C, | |||||
| 6D085AD80CA57F2F8A5C393B, | |||||
| 969CF69D90AC73918B9BB0CD, | |||||
| 6EDD3878142839D368B64F31, | |||||
| E0A48CA97D4C946F632C0DB7, | |||||
| 141FD2E7828F2F2BE0EE9506, | |||||
| AB7BCFBC4B2CB784F57A0FBC, | |||||
| 2E19A0C6793FD28085F7A256, | |||||
| A2BAB9DD00DF8E30A6DF756E, | |||||
| 0906F59C839873ADC151A188, | |||||
| B318D50696B303889BDCF072, | |||||
| 4A6A465D7BC825BB91F562C3, | |||||
| 728F423CEB1B9E6CA8545895, | |||||
| ED5C52722B9653FA3B009C01, | |||||
| 519C6BF83160A6B581905C58, | |||||
| 4550EB50BD17ADECC674C83C, | |||||
| 3031159E3E89066250B1D48A, | |||||
| A62DF2CD31D7890E1B54B18C, | |||||
| 5C407CFD81A7E81FA35D5544, | |||||
| 103FA4C6C505052C818A4829, | |||||
| 4C4DA110B4ABCD9A9CBE93E1, | |||||
| 534561E5F94B5D7A093485DF, | |||||
| E5EDE1797446522FADDF78B5, | |||||
| A5985F8B03893AA7EFD0273A, | |||||
| 6CE9C1799C65E997A35E22CD, | |||||
| 7B491514CCDB29EBB9674F9E, | |||||
| 3C003D01B67D75E4D745A9B0, | |||||
| AB9AD07EF899B75AC4CF01DA, | |||||
| F7AF91E09A9EB00EA5438730, | |||||
| D010985AB6D7A05BA96EB868, | |||||
| BC369095BAEED8707D12F63B, | |||||
| 375A031244EED3B21A609984, | |||||
| 79B958A028493E0DB0133E2B, | |||||
| 1D133744B523A61401D587D8, | |||||
| A10B7B85424CB38AE344D7DC, | |||||
| 71CDD3C8D311F7994DD5CC8F, | |||||
| 74F64B7ADDA82099E04331FF, | |||||
| EFCF0633FF23B5F88112A200, | |||||
| 416D1E80C31864739829BBD3, ); name = "Juce AU Wrapper"; sourceTree = "<group>"; }; | |||||
| 83470AD511CD6CC1E485F29B = {isa = PBXGroup; children = ( | 83470AD511CD6CC1E485F29B = {isa = PBXGroup; children = ( | ||||
| A8A516552AE9B51F35B89B2C, | |||||
| 844343AA474A10F4CD613ACF, | 844343AA474A10F4CD613ACF, | ||||
| 3AA0960DF09414DBA0A2255B, | |||||
| AABC1F4E7D9DA3C6B6DC0F05, | |||||
| 95FF785BAEC4F2799A75D2FF, | |||||
| E0657C5A5A08F4B5BE55034A, | |||||
| 5DAA9288D1FC19812E6ABA3D, | |||||
| 2051F23DC1B2A76D3B110616, | |||||
| 88F2FC5C63F1BA3184DC38BD, | |||||
| 31E15E7A0FBD027D83A28DFF, | |||||
| E42198F571F1BB1C5203F3D2, | |||||
| 739336D279C585C749F3039A, | |||||
| B6394C38B7A283DE86213FAE, | |||||
| AFE00126A5FEF419332CD2B9, | |||||
| EB38777DCA28E40FF364EAE1, | |||||
| 0D4E3861B5EE21765BDEE2A3, | |||||
| 28FD98C78FE1E918553D4C3D, | |||||
| 87DBD7450AE0FDD762712620, | |||||
| 3AA5D4AF03A0689BF8385319, | |||||
| AC4612F7E064ECEC2E95B129, | |||||
| E521DD6592FA0F7828161360, | |||||
| A8BA67A9567A51069D275EBB, | |||||
| 1BAAB47A9C5B1D76D28FA282, | 1BAAB47A9C5B1D76D28FA282, | ||||
| DCF6DECFAD7F4D907C0458A5, | DCF6DECFAD7F4D907C0458A5, | ||||
| 8F59D489139F78A729CED9E5, | 8F59D489139F78A729CED9E5, | ||||
| @@ -2083,7 +2026,8 @@ | |||||
| 8EB324480D60B3E3A81541E5, | 8EB324480D60B3E3A81541E5, | ||||
| 6CEFF94C7852DB3BFA5E29EB, | 6CEFF94C7852DB3BFA5E29EB, | ||||
| 7D08D5465E74DF02EA4E7410, | 7D08D5465E74DF02EA4E7410, | ||||
| 8FB68CA43E49DD39E013DB82, ); name = "Juce Library Code"; sourceTree = "<group>"; }; | |||||
| 8FB68CA43E49DD39E013DB82, | |||||
| 1CF9C794D7A955EA89D8B5CB, ); name = "Juce Library Code"; sourceTree = "<group>"; }; | |||||
| 239B4D5DE50B3B7A16114C15 = {isa = PBXGroup; children = ( | 239B4D5DE50B3B7A16114C15 = {isa = PBXGroup; children = ( | ||||
| 2D799F4BCA83847DEACB505D, | 2D799F4BCA83847DEACB505D, | ||||
| 0926E36205F4D676343AB6E7, ); name = Resources; sourceTree = "<group>"; }; | 0926E36205F4D676343AB6E7, ); name = Resources; sourceTree = "<group>"; }; | ||||
| @@ -2116,8 +2060,6 @@ | |||||
| COMBINE_HIDPI_IMAGES = YES; | COMBINE_HIDPI_IMAGES = YES; | ||||
| CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)"; | CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)"; | ||||
| COPY_PHASE_STRIP = NO; | COPY_PHASE_STRIP = NO; | ||||
| EXCLUDED_SOURCE_FILE_NAMES = "$(EXCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; | |||||
| EXCLUDED_SOURCE_FILE_NAMES_x86_64 = "*Carbon*.cpp"; | |||||
| GCC_DYNAMIC_NO_PIC = NO; | GCC_DYNAMIC_NO_PIC = NO; | ||||
| GCC_OPTIMIZATION_LEVEL = 0; | GCC_OPTIMIZATION_LEVEL = 0; | ||||
| GCC_PREPROCESSOR_DEFINITIONS = ( | GCC_PREPROCESSOR_DEFINITIONS = ( | ||||
| @@ -2128,7 +2070,7 @@ | |||||
| "JUCE_APP_VERSION_HEX=0x10000", ); | "JUCE_APP_VERSION_HEX=0x10000", ); | ||||
| GCC_VERSION = com.apple.compilers.llvm.clang.1_0; | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; | ||||
| GENERATE_PKGINFO_FILE = YES; | GENERATE_PKGINFO_FILE = YES; | ||||
| HEADER_SEARCH_PATHS = ("\"~/SDKs/VST3 SDK\"", "~/SDKs/vstsdk2.4", "../../JuceLibraryCode", "../../../../modules", "$(DEVELOPER_DIR)/Extras/CoreAudio/PublicUtility", "$(DEVELOPER_DIR)/Extras/CoreAudio/AudioUnits/AUPublic/Utility", "$(DEVELOPER_DIR)/Extras/CoreAudio/AudioUnits/AUPublic/AUBase", "$(inherited)"); | |||||
| HEADER_SEARCH_PATHS = ("\"~/SDKs/VST3 SDK\"", "~/SDKs/vstsdk2.4", "../../JuceLibraryCode", "../../../../modules", "$(inherited)"); | |||||
| INFOPLIST_FILE = Info.plist; | INFOPLIST_FILE = Info.plist; | ||||
| INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; | INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; | ||||
| LIBRARY_STYLE = Bundle; | LIBRARY_STYLE = Bundle; | ||||
| @@ -2144,8 +2086,6 @@ | |||||
| COMBINE_HIDPI_IMAGES = YES; | COMBINE_HIDPI_IMAGES = YES; | ||||
| CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)"; | CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)"; | ||||
| DEAD_CODE_STRIPPING = YES; | DEAD_CODE_STRIPPING = YES; | ||||
| EXCLUDED_SOURCE_FILE_NAMES = "$(EXCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; | |||||
| EXCLUDED_SOURCE_FILE_NAMES_x86_64 = "*Carbon*.cpp"; | |||||
| GCC_GENERATE_DEBUGGING_SYMBOLS = NO; | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; | ||||
| GCC_OPTIMIZATION_LEVEL = s; | GCC_OPTIMIZATION_LEVEL = s; | ||||
| GCC_PREPROCESSOR_DEFINITIONS = ( | GCC_PREPROCESSOR_DEFINITIONS = ( | ||||
| @@ -2157,7 +2097,7 @@ | |||||
| GCC_SYMBOLS_PRIVATE_EXTERN = YES; | GCC_SYMBOLS_PRIVATE_EXTERN = YES; | ||||
| GCC_VERSION = com.apple.compilers.llvm.clang.1_0; | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; | ||||
| GENERATE_PKGINFO_FILE = YES; | GENERATE_PKGINFO_FILE = YES; | ||||
| HEADER_SEARCH_PATHS = ("\"~/SDKs/VST3 SDK\"", "~/SDKs/vstsdk2.4", "../../JuceLibraryCode", "../../../../modules", "$(DEVELOPER_DIR)/Extras/CoreAudio/PublicUtility", "$(DEVELOPER_DIR)/Extras/CoreAudio/AudioUnits/AUPublic/Utility", "$(DEVELOPER_DIR)/Extras/CoreAudio/AudioUnits/AUPublic/AUBase", "$(inherited)"); | |||||
| HEADER_SEARCH_PATHS = ("\"~/SDKs/VST3 SDK\"", "~/SDKs/vstsdk2.4", "../../JuceLibraryCode", "../../../../modules", "$(inherited)"); | |||||
| INFOPLIST_FILE = Info.plist; | INFOPLIST_FILE = Info.plist; | ||||
| INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; | INSTALL_PATH = "$(HOME)/Library/Audio/Plug-Ins/Components/"; | ||||
| LIBRARY_STYLE = Bundle; | LIBRARY_STYLE = Bundle; | ||||
| @@ -2209,27 +2149,26 @@ | |||||
| E032EB514708440DE9B7FF2A = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( | E032EB514708440DE9B7FF2A = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( | ||||
| 8265E59547F2C5DDD10F58BF, | 8265E59547F2C5DDD10F58BF, | ||||
| E32999B782F688D3746FEB08, | E32999B782F688D3746FEB08, | ||||
| F04FAA69AC50147EA624EC1F, | |||||
| BE7B7AD7F8A22C21CE836999, | |||||
| 03978B040325C64F1A301026, | |||||
| 64CC64872B50899D0C1965A4, | |||||
| B3C70DEC14A0F3C68BFABAB3, | |||||
| 672ABA87BCE2AC50A10DEC8B, | |||||
| AAAF1BFC19F4CE7BBD8FA43A, | |||||
| F075907E84874848BF0BB205, | |||||
| A1AF669E9F10B2BE0FE3ECD8, | |||||
| 64AD03BB3A52EC9E2C030B8E, | |||||
| 7B4173581D4B03969E995CA5, | |||||
| F979285E6636E6CD0669E164, | |||||
| 5677D9A2B913014EB1B3E3B3, | |||||
| C74F334B15AD60AC06A086B7, | |||||
| CB8698D8E9F64AD71C0608E4, | |||||
| A5C8DB9F33F2934B307C105C, | |||||
| E42B91C4C0B68D26493D8586, | |||||
| 8DBCF6059F7B99ED17E39C3A, | |||||
| 71BEA1E8715EC77F3BA35BAE, | |||||
| 4E76293207C599EF3F0E9D66, | |||||
| 899A05A18F62ABBFF66B554E, | |||||
| 05D1398458CDB00C236D7553, | |||||
| EDC1CED5C7F88E1142F4A46A, | |||||
| B02F742C6DE19F5415457993, | |||||
| B89DA74BC8384D744F20B8CB, | |||||
| BF903CF8AFDA8D74E3A9D023, | |||||
| 9EDD2E63820FA844B4237F1F, | |||||
| 65EF022632E1E7967860DD5E, | |||||
| 15885D9F3F3CB8EFDC29A40F, | |||||
| C9C1F85E79851CE3F2EA0560, | |||||
| 10803DD1A2511511C9A2CEC5, | |||||
| EDE82B3320CC03F38226AA50, | |||||
| C3C922FB2D069BB6DE3ECAA1, | |||||
| 48D94EBEB2D48D0DCC1394C9, | |||||
| D2B29F3448FA79AB8C47B3D8, | |||||
| D5E7114B2C484F13A51DCBC3, | |||||
| 9B39F1EE70A26791804DA55E, | |||||
| 0A7276E46524FC5FD796F27D, | |||||
| 9EA2528254AA35DBDDFEA601, | |||||
| 68B259347BBF52B12FD6900D, | |||||
| 91CCE2D40B3D71F3126A1043, | |||||
| 74CF5671532851FFA52E9D0C, | 74CF5671532851FFA52E9D0C, | ||||
| E20B98D0BD4CB959779121EF, | E20B98D0BD4CB959779121EF, | ||||
| C838DDB6686561401CFD352E, | C838DDB6686561401CFD352E, | ||||
| @@ -2253,7 +2192,8 @@ | |||||
| 6AAB8C946DA0E3E1B96EEF7E, | 6AAB8C946DA0E3E1B96EEF7E, | ||||
| BCFB9D694F4DD8A76C6B9878, | BCFB9D694F4DD8A76C6B9878, | ||||
| 080999E86692B638CD108D70, | 080999E86692B638CD108D70, | ||||
| BFD65DA4F2FE24DF532304DA, ); runOnlyForDeploymentPostprocessing = 0; }; | |||||
| BFD65DA4F2FE24DF532304DA, | |||||
| A4996F8A30110B5EDB801516, ); runOnlyForDeploymentPostprocessing = 0; }; | |||||
| 95E57A758351FE57067B605F = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( | 95E57A758351FE57067B605F = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( | ||||
| 221B97F3CD062F71EBEBA165, | 221B97F3CD062F71EBEBA165, | ||||
| A068599CF7E166847EE45D5F, | A068599CF7E166847EE45D5F, | ||||
| @@ -475,96 +475,7 @@ namespace AUHelpers | |||||
| if (exporter.isXcode()) | if (exporter.isXcode()) | ||||
| { | { | ||||
| String sdkLocation (getPluginAUSDKLocation (projectSaver.project).toString()); | |||||
| if (sdkLocation.trim().isEmpty()) | |||||
| sdkLocation = "$(DEVELOPER_DIR)/Extras/CoreAudio/"; | |||||
| if (! sdkLocation.endsWithChar ('/')) | |||||
| sdkLocation << '/'; | |||||
| { | |||||
| String relativeSDK (exporter.rebaseFromProjectFolderToBuildTarget (RelativePath (sdkLocation, RelativePath::projectFolder)) | |||||
| .toUnixStyle()); | |||||
| if (! relativeSDK.endsWithChar ('/')) | |||||
| relativeSDK << '/'; | |||||
| exporter.extraSearchPaths.add (relativeSDK + "PublicUtility"); | |||||
| exporter.extraSearchPaths.add (relativeSDK + "AudioUnits/AUPublic/Utility"); | |||||
| exporter.extraSearchPaths.add (relativeSDK + "AudioUnits/AUPublic/AUBase"); | |||||
| } | |||||
| exporter.xcodeFrameworks.addTokens ("AudioUnit CoreAudioKit", false); | exporter.xcodeFrameworks.addTokens ("AudioUnit CoreAudioKit", false); | ||||
| exporter.xcodeExcludedFiles64Bit = "\"*Carbon*.cpp\""; | |||||
| Project::Item subGroup (projectSaver.getGeneratedCodeGroup().addNewSubGroup ("Juce AU Wrapper", -1)); | |||||
| subGroup.setID ("__juceappleaufiles"); | |||||
| { | |||||
| static const char* appleAUFiles[] = | |||||
| { | |||||
| "PublicUtility/CADebugMacros.h", | |||||
| "PublicUtility/CAAUParameter.cpp", | |||||
| "PublicUtility/CAAUParameter.h", | |||||
| "PublicUtility/CAAudioChannelLayout.cpp", | |||||
| "PublicUtility/CAAudioChannelLayout.h", | |||||
| "PublicUtility/CAMutex.cpp", | |||||
| "PublicUtility/CAMutex.h", | |||||
| "PublicUtility/CAStreamBasicDescription.cpp", | |||||
| "PublicUtility/CAStreamBasicDescription.h", | |||||
| "PublicUtility/CAVectorUnitTypes.h", | |||||
| "PublicUtility/CAVectorUnit.cpp", | |||||
| "PublicUtility/CAVectorUnit.h", | |||||
| "AudioUnits/AUPublic/AUViewBase/AUViewLocalizedStringKeys.h", | |||||
| "AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewDispatch.cpp", | |||||
| "AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewControl.cpp", | |||||
| "AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewControl.h", | |||||
| "AudioUnits/AUPublic/AUCarbonViewBase/CarbonEventHandler.cpp", | |||||
| "AudioUnits/AUPublic/AUCarbonViewBase/CarbonEventHandler.h", | |||||
| "AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewBase.cpp", | |||||
| "AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewBase.h", | |||||
| "AudioUnits/AUPublic/AUBase/AUBase.cpp", | |||||
| "AudioUnits/AUPublic/AUBase/AUBase.h", | |||||
| "AudioUnits/AUPublic/AUBase/AUDispatch.cpp", | |||||
| "AudioUnits/AUPublic/AUBase/AUDispatch.h", | |||||
| "AudioUnits/AUPublic/AUBase/AUInputElement.cpp", | |||||
| "AudioUnits/AUPublic/AUBase/AUInputElement.h", | |||||
| "AudioUnits/AUPublic/AUBase/AUOutputElement.cpp", | |||||
| "AudioUnits/AUPublic/AUBase/AUOutputElement.h", | |||||
| "AudioUnits/AUPublic/AUBase/AUResources.r", | |||||
| "AudioUnits/AUPublic/AUBase/AUScopeElement.cpp", | |||||
| "AudioUnits/AUPublic/AUBase/AUScopeElement.h", | |||||
| "AudioUnits/AUPublic/AUBase/ComponentBase.cpp", | |||||
| "AudioUnits/AUPublic/AUBase/ComponentBase.h", | |||||
| "AudioUnits/AUPublic/OtherBases/AUMIDIBase.cpp", | |||||
| "AudioUnits/AUPublic/OtherBases/AUMIDIBase.h", | |||||
| "AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.cpp", | |||||
| "AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.h", | |||||
| "AudioUnits/AUPublic/OtherBases/AUOutputBase.cpp", | |||||
| "AudioUnits/AUPublic/OtherBases/AUOutputBase.h", | |||||
| "AudioUnits/AUPublic/OtherBases/MusicDeviceBase.cpp", | |||||
| "AudioUnits/AUPublic/OtherBases/MusicDeviceBase.h", | |||||
| "AudioUnits/AUPublic/OtherBases/AUEffectBase.cpp", | |||||
| "AudioUnits/AUPublic/OtherBases/AUEffectBase.h", | |||||
| "AudioUnits/AUPublic/Utility/AUBuffer.cpp", | |||||
| "AudioUnits/AUPublic/Utility/AUBuffer.h", | |||||
| "AudioUnits/AUPublic/Utility/AUInputFormatConverter.h", | |||||
| "AudioUnits/AUPublic/Utility/AUSilentTimeout.h", | |||||
| "AudioUnits/AUPublic/Utility/AUTimestampGenerator.h", | |||||
| nullptr | |||||
| }; | |||||
| // This converts things like $(DEVELOPER_DIR) to ${DEVELOPER_DIR} | |||||
| sdkLocation = sdkLocation.replaceCharacters ("()", "{}"); | |||||
| for (const char** f = appleAUFiles; *f != nullptr; ++f) | |||||
| { | |||||
| const RelativePath file (sdkLocation + *f, RelativePath::projectFolder); | |||||
| subGroup.addRelativeFile (file, -1, file.hasFileExtension ("cpp;mm")); | |||||
| subGroup.getChild (subGroup.getNumChildren() - 1).getShouldInhibitWarningsValue() = true; | |||||
| } | |||||
| } | |||||
| XmlElement plistKey ("key"); | XmlElement plistKey ("key"); | ||||
| plistKey.addTextElement ("AudioComponents"); | plistKey.addTextElement ("AudioComponents"); | ||||
| @@ -0,0 +1,140 @@ | |||||
| /* | |||||
| File: AUResources.r | |||||
| Abstract: AUResources.r | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| // AUResources.r | |||||
| // | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ | |||||
| /* sample macro definitions -- all of these symbols must be defined | |||||
| #define RES_ID kHALOutputResID | |||||
| #define COMP_TYPE kAudioUnitComponentType | |||||
| #define COMP_SUBTYPE kAudioUnitOutputSubType | |||||
| #define COMP_MANUF kAudioUnitAudioHardwareOutputSubSubType | |||||
| #define VERSION 0x00010000 | |||||
| #define NAME "AudioHALOutput" | |||||
| #define DESCRIPTION "Audio hardware output AudioUnit" | |||||
| #define ENTRY_POINT "AUHALEntry" | |||||
| */ | |||||
| #define UseExtendedThingResource 1 | |||||
| #include <CoreServices/CoreServices.r> | |||||
| // this is a define used to indicate that a component has no static data that would mean | |||||
| // that no more than one instance could be open at a time - never been true for AUs | |||||
| #ifndef cmpThreadSafeOnMac | |||||
| #define cmpThreadSafeOnMac 0x10000000 | |||||
| #endif | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| resource 'STR ' (RES_ID, purgeable) { | |||||
| NAME | |||||
| }; | |||||
| resource 'STR ' (RES_ID + 1, purgeable) { | |||||
| DESCRIPTION | |||||
| }; | |||||
| resource 'dlle' (RES_ID) { | |||||
| ENTRY_POINT | |||||
| }; | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| resource 'thng' (RES_ID, NAME) { | |||||
| COMP_TYPE, | |||||
| COMP_SUBTYPE, | |||||
| COMP_MANUF, | |||||
| 0, 0, 0, 0, // no 68K | |||||
| 'STR ', RES_ID, | |||||
| 'STR ', RES_ID + 1, | |||||
| 0, 0, /* icon */ | |||||
| VERSION, | |||||
| componentHasMultiplePlatforms | componentDoAutoVersion, | |||||
| 0, | |||||
| { | |||||
| #if defined(ppc_YES) | |||||
| cmpThreadSafeOnMac, | |||||
| 'dlle', RES_ID, platformPowerPCNativeEntryPoint | |||||
| #define NeedLeadingComma 1 | |||||
| #endif | |||||
| #if defined(ppc64_YES) | |||||
| #if defined(NeedLeadingComma) | |||||
| , | |||||
| #endif | |||||
| cmpThreadSafeOnMac, | |||||
| 'dlle', RES_ID, platformPowerPC64NativeEntryPoint | |||||
| #define NeedLeadingComma 1 | |||||
| #endif | |||||
| #if defined(i386_YES) | |||||
| #if defined(NeedLeadingComma) | |||||
| , | |||||
| #endif | |||||
| cmpThreadSafeOnMac, | |||||
| 'dlle', RES_ID, platformIA32NativeEntryPoint | |||||
| #define NeedLeadingComma 1 | |||||
| #endif | |||||
| #if defined(x86_64_YES) | |||||
| #if defined(NeedLeadingComma) | |||||
| , | |||||
| #endif | |||||
| cmpThreadSafeOnMac, | |||||
| 'dlle', RES_ID, 8 | |||||
| #define NeedLeadingComma 1 | |||||
| #endif | |||||
| } | |||||
| }; | |||||
| #undef RES_ID | |||||
| #undef COMP_TYPE | |||||
| #undef COMP_SUBTYPE | |||||
| #undef COMP_MANUF | |||||
| #undef VERSION | |||||
| #undef NAME | |||||
| #undef DESCRIPTION | |||||
| #undef ENTRY_POINT | |||||
| #undef NeedLeadingComma | |||||
| @@ -0,0 +1,75 @@ | |||||
| /* | |||||
| File: AUBaseHelper.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUBaseHelper_h__ | |||||
| #define __AUBaseHelper_h__ | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreFoundation/CoreFoundation.h> | |||||
| #include <AudioUnit/AUComponent.h> | |||||
| #else | |||||
| #include <CoreFoundation.h> | |||||
| #include <AUComponent.h> | |||||
| #endif | |||||
| #include "AUBase.h" | |||||
| // helpers for dealing with the file-references dictionary in an AUPreset | |||||
| OSStatus GetFileRefPath (CFDictionaryRef parent, CFStringRef frKey, CFStringRef * fPath); | |||||
| // if fileRefDict is NULL, this call creates one | |||||
| // if not NULL, then the key value is added to it | |||||
| CFMutableDictionaryRef CreateFileRefDict (CFStringRef fKey, CFStringRef fPath, CFMutableDictionaryRef fileRefDict); | |||||
| int AccessURLAsset(const CFURLRef inURL, int mode); | |||||
| #if DEBUG | |||||
| void PrintAUParamEvent (AudioUnitParameterEvent& event, FILE* f); | |||||
| #endif | |||||
| #endif // __AUBaseHelper_h__ | |||||
| @@ -0,0 +1,219 @@ | |||||
| /* | |||||
| File: AUBuffer.cpp | |||||
| Abstract: AUBuffer.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUBuffer.h" | |||||
| #include <stdlib.h> | |||||
| AUBufferList::~AUBufferList() | |||||
| { | |||||
| Deallocate(); | |||||
| if (mPtrs) | |||||
| free(mPtrs); | |||||
| } | |||||
| // a * b + c | |||||
| static UInt32 SafeMultiplyAddUInt32(UInt32 a, UInt32 b, UInt32 c) | |||||
| { | |||||
| if (a == 0 || b == 0) return c; // prevent zero divide | |||||
| if (a > (0xFFFFFFFF - c) / b) | |||||
| throw std::bad_alloc(); | |||||
| return a * b + c; | |||||
| } | |||||
| void AUBufferList::Allocate(const CAStreamBasicDescription &format, UInt32 nFrames) | |||||
| { | |||||
| UInt32 nStreams; | |||||
| if (format.IsInterleaved()) { | |||||
| nStreams = 1; | |||||
| } else { | |||||
| nStreams = format.mChannelsPerFrame; | |||||
| } | |||||
| // careful -- the I/O thread could be running! | |||||
| if (nStreams > mAllocatedStreams) { | |||||
| size_t theHeaderSize = sizeof(AudioBufferList) - sizeof(AudioBuffer); | |||||
| mPtrs = (AudioBufferList *)CA_realloc(mPtrs, | |||||
| SafeMultiplyAddUInt32(nStreams, sizeof(AudioBuffer), theHeaderSize)); | |||||
| mAllocatedStreams = nStreams; | |||||
| } | |||||
| UInt32 bytesPerStream = SafeMultiplyAddUInt32(nFrames, format.mBytesPerFrame, 0xF) & ~0xF; | |||||
| UInt32 nBytes = SafeMultiplyAddUInt32(nStreams, bytesPerStream, 0); | |||||
| if (nBytes > mAllocatedBytes) { | |||||
| if (mExternalMemory) { | |||||
| mExternalMemory = false; | |||||
| mMemory = NULL; | |||||
| } | |||||
| mMemory = (Byte *)CA_realloc(mMemory, nBytes); | |||||
| mAllocatedBytes = nBytes; | |||||
| } | |||||
| mAllocatedFrames = nFrames; | |||||
| mPtrState = kPtrsInvalid; | |||||
| } | |||||
| void AUBufferList::Deallocate() | |||||
| { | |||||
| mAllocatedStreams = 0; | |||||
| mAllocatedFrames = 0; | |||||
| mAllocatedBytes = 0; | |||||
| // this causes a world of hurt if someone upstream disconnects during I/O (SysSoundGraph) | |||||
| /* if (mPtrs) { | |||||
| printf("deallocating bufferlist %08X\n", int(mPtrs)); | |||||
| free(mPtrs); | |||||
| mPtrs = NULL; | |||||
| } */ | |||||
| if (mMemory) { | |||||
| if (mExternalMemory) | |||||
| mExternalMemory = false; | |||||
| else | |||||
| free(mMemory); | |||||
| mMemory = NULL; | |||||
| } | |||||
| mPtrState = kPtrsInvalid; | |||||
| } | |||||
| AudioBufferList & AUBufferList::PrepareBuffer(const CAStreamBasicDescription &format, UInt32 nFrames) | |||||
| { | |||||
| if (nFrames > mAllocatedFrames) | |||||
| COMPONENT_THROW(kAudioUnitErr_TooManyFramesToProcess); | |||||
| UInt32 nStreams; | |||||
| UInt32 channelsPerStream; | |||||
| if (format.IsInterleaved()) { | |||||
| nStreams = 1; | |||||
| channelsPerStream = format.mChannelsPerFrame; | |||||
| } else { | |||||
| nStreams = format.mChannelsPerFrame; | |||||
| channelsPerStream = 1; | |||||
| if (nStreams > mAllocatedStreams) | |||||
| COMPONENT_THROW(kAudioUnitErr_FormatNotSupported); | |||||
| } | |||||
| AudioBufferList *abl = mPtrs; | |||||
| abl->mNumberBuffers = nStreams; | |||||
| AudioBuffer *buf = abl->mBuffers; | |||||
| Byte *mem = mMemory; | |||||
| UInt32 streamInterval = (mAllocatedFrames * format.mBytesPerFrame + 0xF) & ~0xF; | |||||
| UInt32 bytesPerBuffer = nFrames * format.mBytesPerFrame; | |||||
| for ( ; nStreams--; ++buf) { | |||||
| buf->mNumberChannels = channelsPerStream; | |||||
| buf->mData = mem; | |||||
| buf->mDataByteSize = bytesPerBuffer; | |||||
| mem += streamInterval; | |||||
| } | |||||
| if (UInt32(mem - mMemory) > mAllocatedBytes) | |||||
| COMPONENT_THROW(kAudioUnitErr_TooManyFramesToProcess); | |||||
| mPtrState = kPtrsToMyMemory; | |||||
| return *mPtrs; | |||||
| } | |||||
| AudioBufferList & AUBufferList::PrepareNullBuffer(const CAStreamBasicDescription &format, UInt32 nFrames) | |||||
| { | |||||
| UInt32 nStreams; | |||||
| UInt32 channelsPerStream; | |||||
| if (format.IsInterleaved()) { | |||||
| nStreams = 1; | |||||
| channelsPerStream = format.mChannelsPerFrame; | |||||
| } else { | |||||
| nStreams = format.mChannelsPerFrame; | |||||
| channelsPerStream = 1; | |||||
| if (nStreams > mAllocatedStreams) | |||||
| COMPONENT_THROW(kAudioUnitErr_FormatNotSupported); | |||||
| } | |||||
| AudioBufferList *abl = mPtrs; | |||||
| abl->mNumberBuffers = nStreams; | |||||
| AudioBuffer *buf = abl->mBuffers; | |||||
| UInt32 bytesPerBuffer = nFrames * format.mBytesPerFrame; | |||||
| for ( ; nStreams--; ++buf) { | |||||
| buf->mNumberChannels = channelsPerStream; | |||||
| buf->mData = NULL; | |||||
| buf->mDataByteSize = bytesPerBuffer; | |||||
| } | |||||
| mPtrState = kPtrsToExternalMemory; | |||||
| return *mPtrs; | |||||
| } | |||||
| // this should NOT be called while I/O is in process | |||||
| void AUBufferList::UseExternalBuffer(const CAStreamBasicDescription &format, const AudioUnitExternalBuffer &buf) | |||||
| { | |||||
| UInt32 alignedSize = buf.size & ~0xF; | |||||
| if (mMemory != NULL && alignedSize >= mAllocatedBytes) { | |||||
| // don't accept the buffer if we already have one and it's big enough | |||||
| // if we don't already have one, we don't need one | |||||
| Byte *oldMemory = mMemory; | |||||
| mMemory = buf.buffer; | |||||
| mAllocatedBytes = alignedSize; | |||||
| // from Allocate(): nBytes = nStreams * nFrames * format.mBytesPerFrame; | |||||
| // thus: nFrames = nBytes / (nStreams * format.mBytesPerFrame) | |||||
| mAllocatedFrames = mAllocatedBytes / (format.NumberChannelStreams() * format.mBytesPerFrame); | |||||
| mExternalMemory = true; | |||||
| free(oldMemory); | |||||
| } | |||||
| } | |||||
| #if DEBUG | |||||
| void AUBufferList::PrintBuffer(const char *label, int subscript, const AudioBufferList &abl, UInt32 nFrames, bool asFloats) | |||||
| { | |||||
| printf(" %s [%d] 0x%08lX:\n", label, subscript, long(&abl)); | |||||
| const AudioBuffer *buf = abl.mBuffers; | |||||
| for (UInt32 i = 0; i < abl.mNumberBuffers; ++buf, ++i) { | |||||
| printf(" [%2d] %5dbytes %dch @ %p: ", (int)i, (int)buf->mDataByteSize, (int)buf->mNumberChannels, buf->mData); | |||||
| if (buf->mData != NULL) { | |||||
| UInt32 nSamples = nFrames * buf->mNumberChannels; | |||||
| for (UInt32 j = 0; j < nSamples; ++j) { | |||||
| if (nSamples > 16 && (j % 16) == 0) | |||||
| printf("\n\t"); | |||||
| if (asFloats) | |||||
| printf(" %6.3f", ((float *)buf->mData)[j]); | |||||
| else | |||||
| printf(" %08X", (unsigned)((UInt32 *)buf->mData)[j]); | |||||
| } | |||||
| } | |||||
| printf("\n"); | |||||
| } | |||||
| } | |||||
| #endif | |||||
| @@ -0,0 +1,267 @@ | |||||
| /* | |||||
| File: AUBuffer.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUBuffer_h__ | |||||
| #define __AUBuffer_h__ | |||||
| #include <TargetConditionals.h> | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <AudioUnit/AudioUnit.h> | |||||
| #else | |||||
| #include <AudioUnit.h> | |||||
| #endif | |||||
| #include <string.h> | |||||
| #include "CAStreamBasicDescription.h" | |||||
| #include "CAAutoDisposer.h" | |||||
| #include "CADebugMacros.h" | |||||
| // make this usable outside the stricter context of AudiUnits | |||||
| #ifndef COMPONENT_THROW | |||||
| #define COMPONENT_THROW(err) \ | |||||
| do { DebugMessage(#err); throw static_cast<OSStatus>(err); } while (0) | |||||
| #endif | |||||
| /*! @class AUBufferList */ | |||||
| class AUBufferList { | |||||
| enum EPtrState { | |||||
| kPtrsInvalid, | |||||
| kPtrsToMyMemory, | |||||
| kPtrsToExternalMemory | |||||
| }; | |||||
| public: | |||||
| /*! @ctor AUBufferList */ | |||||
| AUBufferList() : mPtrState(kPtrsInvalid), mExternalMemory(false), mPtrs(NULL), mMemory(NULL), | |||||
| mAllocatedStreams(0), mAllocatedFrames(0), mAllocatedBytes(0) { } | |||||
| /*! @dtor ~AUBufferList */ | |||||
| ~AUBufferList(); | |||||
| /*! @method PrepareBuffer */ | |||||
| AudioBufferList & PrepareBuffer(const CAStreamBasicDescription &format, UInt32 nFrames); | |||||
| /*! @method PrepareNullBuffer */ | |||||
| AudioBufferList & PrepareNullBuffer(const CAStreamBasicDescription &format, UInt32 nFrames); | |||||
| /*! @method SetBufferList */ | |||||
| AudioBufferList & SetBufferList(const AudioBufferList &abl) { | |||||
| if (mAllocatedStreams < abl.mNumberBuffers) | |||||
| COMPONENT_THROW(-1); | |||||
| mPtrState = kPtrsToExternalMemory; | |||||
| memcpy(mPtrs, &abl, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl); | |||||
| return *mPtrs; | |||||
| } | |||||
| /*! @method SetBuffer */ | |||||
| void SetBuffer(UInt32 index, const AudioBuffer &ab) { | |||||
| if (mPtrState == kPtrsInvalid || index >= mPtrs->mNumberBuffers) | |||||
| COMPONENT_THROW(-1); | |||||
| mPtrState = kPtrsToExternalMemory; | |||||
| mPtrs->mBuffers[index] = ab; | |||||
| } | |||||
| /*! @method InvalidateBufferList */ | |||||
| void InvalidateBufferList() { mPtrState = kPtrsInvalid; } | |||||
| /*! @method GetBufferList */ | |||||
| AudioBufferList & GetBufferList() const { | |||||
| if (mPtrState == kPtrsInvalid) | |||||
| COMPONENT_THROW(-1); | |||||
| return *mPtrs; | |||||
| } | |||||
| /*! @method CopyBufferListTo */ | |||||
| void CopyBufferListTo(AudioBufferList &abl) const { | |||||
| if (mPtrState == kPtrsInvalid) | |||||
| COMPONENT_THROW(-1); | |||||
| memcpy(&abl, mPtrs, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl); | |||||
| } | |||||
| /*! @method CopyBufferContentsTo */ | |||||
| void CopyBufferContentsTo(AudioBufferList &abl) const { | |||||
| if (mPtrState == kPtrsInvalid) | |||||
| COMPONENT_THROW(-1); | |||||
| const AudioBuffer *srcbuf = mPtrs->mBuffers; | |||||
| AudioBuffer *destbuf = abl.mBuffers; | |||||
| for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++srcbuf, ++destbuf) { | |||||
| if (i >= mPtrs->mNumberBuffers) // duplicate last source to additional outputs [4341137] | |||||
| --srcbuf; | |||||
| if (destbuf->mData != srcbuf->mData) | |||||
| memmove(destbuf->mData, srcbuf->mData, srcbuf->mDataByteSize); | |||||
| destbuf->mDataByteSize = srcbuf->mDataByteSize; | |||||
| } | |||||
| } | |||||
| /*! @method Allocate */ | |||||
| void Allocate(const CAStreamBasicDescription &format, UInt32 nFrames); | |||||
| /*! @method Deallocate */ | |||||
| void Deallocate(); | |||||
| /*! @method UseExternalBuffer */ | |||||
| void UseExternalBuffer(const CAStreamBasicDescription &format, const AudioUnitExternalBuffer &buf); | |||||
| // AudioBufferList utilities | |||||
| /*! @method ZeroBuffer */ | |||||
| static void ZeroBuffer(AudioBufferList &abl) { | |||||
| AudioBuffer *buf = abl.mBuffers; | |||||
| for (UInt32 i = abl.mNumberBuffers ; i--; ++buf) | |||||
| memset(buf->mData, 0, buf->mDataByteSize); | |||||
| } | |||||
| #if DEBUG | |||||
| /*! @method PrintBuffer */ | |||||
| static void PrintBuffer(const char *label, int subscript, const AudioBufferList &abl, UInt32 nFrames = 8, bool asFloats = true); | |||||
| #endif | |||||
| /*! @method GetAllocatedFrames */ | |||||
| UInt32 GetAllocatedFrames() const { return mAllocatedFrames; } | |||||
| private: | |||||
| /*! @ctor AUBufferList */ | |||||
| AUBufferList(AUBufferList &) { } // prohibit copy constructor | |||||
| /*! @var mPtrState */ | |||||
| EPtrState mPtrState; | |||||
| /*! @var mExternalMemory */ | |||||
| bool mExternalMemory; | |||||
| /*! @var mPtrs */ | |||||
| AudioBufferList * mPtrs; | |||||
| /*! @var mMemory */ | |||||
| Byte * mMemory; | |||||
| /*! @var mAllocatedStreams */ | |||||
| UInt32 mAllocatedStreams; | |||||
| /*! @var mAllocatedFrames */ | |||||
| UInt32 mAllocatedFrames; | |||||
| /*! @var mAllocatedBytes */ | |||||
| UInt32 mAllocatedBytes; | |||||
| }; | |||||
| // Allocates an array of samples (type T), to be optimally aligned for the processor | |||||
| /*! @class TAUBuffer */ | |||||
| template <class T> | |||||
| class TAUBuffer { | |||||
| public: | |||||
| enum { | |||||
| kAlignInterval = 0x10, | |||||
| kAlignMask = kAlignInterval - 1 | |||||
| }; | |||||
| /*! @ctor TAUBuffer.0 */ | |||||
| TAUBuffer() : mMemObject(NULL), mAlignedBuffer(NULL), mBufferSizeBytes(0) | |||||
| { | |||||
| } | |||||
| /*! @ctor TAUBuffer.1 */ | |||||
| TAUBuffer(UInt32 numElems, UInt32 numChannels) : mMemObject(NULL), mAlignedBuffer(NULL), | |||||
| mBufferSizeBytes(0) | |||||
| { | |||||
| Allocate(numElems, numChannels); | |||||
| } | |||||
| /*! @dtor ~TAUBuffer */ | |||||
| ~TAUBuffer() | |||||
| { | |||||
| Deallocate(); | |||||
| } | |||||
| /*! @method Allocate */ | |||||
| void Allocate(UInt32 numElems) // can also re-allocate | |||||
| { | |||||
| UInt32 reqSize = numElems * sizeof(T); | |||||
| if (mMemObject != NULL && reqSize == mBufferSizeBytes) | |||||
| return; // already allocated | |||||
| mBufferSizeBytes = reqSize; | |||||
| mMemObject = CA_realloc(mMemObject, reqSize); | |||||
| UInt32 misalign = (uintptr_t)mMemObject & kAlignMask; | |||||
| if (misalign) { | |||||
| mMemObject = CA_realloc(mMemObject, reqSize + kAlignMask); | |||||
| mAlignedBuffer = (T *)((char *)mMemObject + kAlignInterval - misalign); | |||||
| } else | |||||
| mAlignedBuffer = (T *)mMemObject; | |||||
| } | |||||
| /*! @method Deallocate */ | |||||
| void Deallocate() | |||||
| { | |||||
| if (mMemObject == NULL) return; // so this method has no effect if we're using | |||||
| // an external buffer | |||||
| free(mMemObject); | |||||
| mMemObject = NULL; | |||||
| mAlignedBuffer = NULL; | |||||
| mBufferSizeBytes = 0; | |||||
| } | |||||
| /*! @method AllocateClear */ | |||||
| void AllocateClear(UInt32 numElems) // can also re-allocate | |||||
| { | |||||
| Allocate(numElems); | |||||
| Clear(); | |||||
| } | |||||
| /*! @method Clear */ | |||||
| void Clear() | |||||
| { | |||||
| memset(mAlignedBuffer, 0, mBufferSizeBytes); | |||||
| } | |||||
| // accessors | |||||
| /*! @method operator T *()@ */ | |||||
| operator T *() { return mAlignedBuffer; } | |||||
| private: | |||||
| /*! @var mMemObject */ | |||||
| void * mMemObject; // null when using an external buffer | |||||
| /*! @var mAlignedBuffer */ | |||||
| T * mAlignedBuffer; // always valid once allocated | |||||
| /*! @var mBufferSizeBytes */ | |||||
| UInt32 mBufferSizeBytes; | |||||
| }; | |||||
| #endif // __AUBuffer_h__ | |||||
| @@ -0,0 +1,403 @@ | |||||
| /* | |||||
| File: AUCarbonViewBase.cpp | |||||
| Abstract: AUCarbonViewBase.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUCarbonViewBase.h" | |||||
| #include "AUCarbonViewControl.h" | |||||
| #include <algorithm> | |||||
| AUCarbonViewBase::AUCarbonViewBase(AudioUnitCarbonView inInstance, Float32 inNotificationInterval /* in seconds */) : | |||||
| ComponentBase(inInstance), | |||||
| mEditAudioUnit(0), | |||||
| mParameterListener(NULL), | |||||
| #if !__LP64__ | |||||
| mEventListener(NULL), | |||||
| #endif | |||||
| mTimerRef (NULL), | |||||
| mTimerUPP (NULL), | |||||
| mCarbonWindow(NULL), | |||||
| mCarbonPane(NULL), | |||||
| mXOffset(0), | |||||
| mYOffset(0) | |||||
| { | |||||
| AUEventListenerCreate (ParameterListener, this, | |||||
| CFRunLoopGetCurrent(), kCFRunLoopCommonModes, | |||||
| inNotificationInterval, inNotificationInterval, | |||||
| &mParameterListener); | |||||
| } | |||||
| AUCarbonViewBase::~AUCarbonViewBase() | |||||
| { | |||||
| #if !__LP64__ | |||||
| if (mCarbonPane) | |||||
| DisposeControl(mCarbonPane); | |||||
| for (ControlList::iterator it = mControlList.begin(); it != mControlList.end(); ++it) { | |||||
| AUCarbonViewControl *ctl = *it; | |||||
| delete ctl; | |||||
| } | |||||
| AUListenerDispose(mParameterListener); | |||||
| if (mTimerRef) | |||||
| ::RemoveEventLoopTimer (mTimerRef); | |||||
| if (mTimerUPP) | |||||
| DisposeEventLoopTimerUPP (mTimerUPP); | |||||
| #endif | |||||
| } | |||||
| void AUCarbonViewBase::AddControl(AUCarbonViewControl *control) | |||||
| { | |||||
| ControlList::iterator it = find(mControlList.begin(), mControlList.end(), control); | |||||
| if (it == mControlList.end()) | |||||
| mControlList.push_back(control); | |||||
| } | |||||
| void AUCarbonViewBase::RemoveControl(AUCarbonViewControl *control) | |||||
| { | |||||
| ControlList::iterator it = find(mControlList.begin(), mControlList.end(), control); | |||||
| if (it != mControlList.end()) { | |||||
| AUCarbonViewControl *ctl = *it; | |||||
| mControlList.erase(it); | |||||
| delete ctl; | |||||
| } | |||||
| } | |||||
| void AUCarbonViewBase::ClearControls () | |||||
| { | |||||
| for (ControlList::iterator it = mControlList.begin(); it != mControlList.end(); ++it) { | |||||
| AUCarbonViewControl *ctl = *it; | |||||
| delete ctl; | |||||
| } | |||||
| mControlList.clear(); | |||||
| } | |||||
| void AUCarbonViewBase::ParameterListener(void * inCallbackRefCon, | |||||
| void * inObject, | |||||
| const AudioUnitEvent * inEvent, | |||||
| UInt64 inEventHostTime, | |||||
| Float32 inParameterValue) | |||||
| { | |||||
| if (inEvent->mEventType == kAudioUnitEvent_ParameterValueChange) { | |||||
| AUCarbonViewControl *ctl = (AUCarbonViewControl *)inObject; | |||||
| ctl->ParameterToControl(inParameterValue); | |||||
| } | |||||
| } | |||||
| OSStatus AUCarbonViewBase::CreateCarbonView(AudioUnit inAudioUnit, WindowRef inWindow, ControlRef inParentControl, const Float32Point &inLocation, const Float32Point &inSize, ControlRef &outParentControl) | |||||
| { | |||||
| #if !__LP64__ | |||||
| mEditAudioUnit = inAudioUnit; | |||||
| mCarbonWindow = inWindow; | |||||
| WindowAttributes attributes; | |||||
| verify_noerr(GetWindowAttributes(mCarbonWindow, &attributes)); | |||||
| mCompositWindow = (attributes & kWindowCompositingAttribute) != 0; | |||||
| Rect area; | |||||
| area.left = short(inLocation.x); area.top = short(inLocation.y); | |||||
| area.right = short(area.left + inSize.x); area.bottom = short(area.top + inSize.y); | |||||
| OSStatus err = ::CreateUserPaneControl(inWindow, &area, | |||||
| kControlSupportsEmbedding, | |||||
| &mCarbonPane); // subclass can resize mCarbonPane to taste | |||||
| verify_noerr(err); | |||||
| if (err) return err; | |||||
| outParentControl = mCarbonPane; | |||||
| // register for mouse-down in our pane -- we want to clear focus | |||||
| EventTypeSpec paneEvents[] = { | |||||
| { kEventClassControl, kEventControlClick } | |||||
| }; | |||||
| WantEventTypes(GetControlEventTarget(mCarbonPane), GetEventTypeCount(paneEvents), paneEvents); | |||||
| if (IsCompositWindow()) { | |||||
| verify_noerr(::HIViewAddSubview(inParentControl, mCarbonPane)); | |||||
| mXOffset = 0; | |||||
| mYOffset = 0; | |||||
| } | |||||
| else { | |||||
| verify_noerr(::EmbedControl(mCarbonPane, inParentControl)); | |||||
| mXOffset = inLocation.x; | |||||
| mYOffset = inLocation.y; | |||||
| } | |||||
| mBottomRight.h = mBottomRight.v = 0; | |||||
| SizeControl(mCarbonPane, 0, 0); | |||||
| if (err = CreateUI(mXOffset, mYOffset)) | |||||
| return err; | |||||
| // we should only resize the control if a subclass has embedded | |||||
| // controls in this AND this is done with the EmbedControl call below | |||||
| // if mBottomRight is STILL equal to zero, then that wasn't done | |||||
| // so don't size the control | |||||
| Rect paneBounds; | |||||
| GetControlBounds(mCarbonPane, &paneBounds); | |||||
| // only resize mCarbonPane if it has not already been resized during CreateUI | |||||
| if ((paneBounds.top == paneBounds.bottom) && (paneBounds.left == paneBounds.right)) { | |||||
| if (mBottomRight.h != 0 && mBottomRight.v != 0) | |||||
| SizeControl(mCarbonPane, (short) (mBottomRight.h - mXOffset), (short) (mBottomRight.v - mYOffset)); | |||||
| } | |||||
| if (IsCompositWindow()) { | |||||
| // prepare for handling scroll-events | |||||
| EventTypeSpec scrollEvents[] = { | |||||
| { kEventClassScrollable, kEventScrollableGetInfo }, | |||||
| { kEventClassScrollable, kEventScrollableScrollTo } | |||||
| }; | |||||
| WantEventTypes(GetControlEventTarget(mCarbonPane), GetEventTypeCount(scrollEvents), scrollEvents); | |||||
| mCurrentScrollPoint.x = mCurrentScrollPoint.y = 0.0f; | |||||
| } | |||||
| return err; | |||||
| #else | |||||
| return noErr; | |||||
| #endif | |||||
| } | |||||
| OSStatus AUCarbonViewBase::CreateUI(Float32 inXOffset, Float32 inYOffset) | |||||
| { | |||||
| return noErr; | |||||
| } | |||||
| OSStatus AUCarbonViewBase::EmbedControl(ControlRef ctl) | |||||
| { | |||||
| #if !__LP64__ | |||||
| Rect r; | |||||
| ::GetControlBounds(ctl, &r); | |||||
| if (r.right > mBottomRight.h) mBottomRight.h = r.right; | |||||
| if (r.bottom > mBottomRight.v) mBottomRight.v = r.bottom; | |||||
| if (IsCompositWindow()) | |||||
| return ::HIViewAddSubview(mCarbonPane, ctl); | |||||
| else | |||||
| return ::EmbedControl(ctl, mCarbonPane); | |||||
| #else | |||||
| return noErr; | |||||
| #endif | |||||
| } | |||||
| void AUCarbonViewBase::AddCarbonControl(AUCarbonViewControl::ControlType type, const CAAUParameter ¶m, ControlRef control) | |||||
| { | |||||
| verify_noerr(EmbedControl(control)); | |||||
| AUCarbonViewControl *auvc = new AUCarbonViewControl(this, mParameterListener, type, param, control); | |||||
| auvc->Bind(); | |||||
| AddControl(auvc); | |||||
| } | |||||
| bool AUCarbonViewBase::HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event) | |||||
| { | |||||
| #if !__LP64__ | |||||
| UInt32 eclass = GetEventClass(event); | |||||
| UInt32 ekind = GetEventKind(event); | |||||
| ControlRef control; | |||||
| switch (eclass) { | |||||
| case kEventClassControl: | |||||
| { | |||||
| switch (ekind) { | |||||
| case kEventControlClick: | |||||
| GetEventParameter(event, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &control); | |||||
| if (control == mCarbonPane) { | |||||
| ClearKeyboardFocus(mCarbonWindow); | |||||
| return true; | |||||
| } | |||||
| } | |||||
| } | |||||
| break; | |||||
| case kEventClassScrollable: | |||||
| { | |||||
| switch (ekind) { | |||||
| case kEventScrollableGetInfo: | |||||
| { | |||||
| // [1/4] | |||||
| /* <-- kEventParamImageSize (out, typeHISize) | |||||
| * On exit, contains the size of the entire scrollable view. | |||||
| */ | |||||
| HISize originalSize = { static_cast<CGFloat>(mBottomRight.h), static_cast<CGFloat>(mBottomRight.v) }; | |||||
| verify_noerr(SetEventParameter(event, kEventParamImageSize, typeHISize, sizeof(HISize), &originalSize)); | |||||
| // [2/4] | |||||
| /* <-- kEventParamViewSize (out, typeHISize) | |||||
| * On exit, contains the amount of the scrollable view that is | |||||
| * visible. | |||||
| */ | |||||
| HIViewRef parentView = HIViewGetSuperview(mCarbonPane); | |||||
| HIRect parentBounds; | |||||
| verify_noerr(HIViewGetBounds(parentView, &parentBounds)); | |||||
| //HISize windowSize = { float(windowBounds.right - windowBounds.left), | |||||
| // float(windowBounds.bottom - windowBounds.top) }; | |||||
| verify_noerr(SetEventParameter(event, kEventParamViewSize, typeHISize, sizeof(HISize), &(parentBounds.size))); | |||||
| // [3/4] | |||||
| /* <-- kEventParamLineSize (out, typeHISize) | |||||
| * On exit, contains the amount that should be scrolled in | |||||
| * response to a single click on a scrollbar arrow. | |||||
| */ | |||||
| HISize scrollIncrementSize = { 16.0f, float(20) }; | |||||
| verify_noerr(SetEventParameter(event, kEventParamLineSize, typeHISize, sizeof(HISize), &scrollIncrementSize)); | |||||
| // [4/4] | |||||
| /* <-- kEventParamOrigin (out, typeHIPoint) | |||||
| * On exit, contains the scrollable viewÕs current origin (the | |||||
| * view-relative coordinate that is drawn at the top left | |||||
| * corner of its frame). These coordinates should always be | |||||
| * greater than or equal to zero. They should be less than or | |||||
| * equal to the viewÕs image size minus its view size. | |||||
| */ | |||||
| verify_noerr(SetEventParameter(event, kEventParamOrigin, typeHIPoint, sizeof(HIPoint), &mCurrentScrollPoint)); | |||||
| } | |||||
| return true; | |||||
| case kEventScrollableScrollTo: | |||||
| { | |||||
| /* | |||||
| * kEventClassScrollable / kEventScrollableScrollTo | |||||
| * | |||||
| * Summary: | |||||
| * Requests that an HIScrollViewÕs scrollable view should scroll to | |||||
| * a particular origin. | |||||
| */ | |||||
| /* --> kEventParamOrigin (in, typeHIPoint) | |||||
| * The new origin for the scrollable view. The origin | |||||
| * coordinates will vary from (0,0) to scrollable viewÕs image | |||||
| * size minus its view size. | |||||
| */ | |||||
| HIPoint pointToScrollTo; | |||||
| verify_noerr(GetEventParameter(event, kEventParamOrigin, typeHIPoint, NULL, sizeof(HIPoint), NULL, &pointToScrollTo)); | |||||
| float xDelta = mCurrentScrollPoint.x - pointToScrollTo.x; | |||||
| float yDelta = mCurrentScrollPoint.y - pointToScrollTo.y; | |||||
| // move visible portion the appropriate amount | |||||
| verify_noerr(HIViewScrollRect(mCarbonPane, NULL, xDelta, yDelta)); | |||||
| // set new content to be drawn | |||||
| verify_noerr(HIViewSetBoundsOrigin(mCarbonPane, pointToScrollTo.x, pointToScrollTo.y)); | |||||
| mCurrentScrollPoint = pointToScrollTo; | |||||
| } | |||||
| return true; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| #endif | |||||
| return false; | |||||
| } | |||||
| /*! @method TellListener */ | |||||
| void AUCarbonViewBase::TellListener (const CAAUParameter &auvp, AudioUnitCarbonViewEventID event, void *evpar) | |||||
| { | |||||
| #if !__LP64__ | |||||
| if (mEventListener) | |||||
| (*mEventListener)(mEventListenerUserData, mComponentInstance, &auvp, event, evpar); | |||||
| #endif | |||||
| AudioUnitEvent auEvent; | |||||
| auEvent.mArgument.mParameter = auvp; | |||||
| if (event == kAudioUnitCarbonViewEvent_MouseDownInControl) { | |||||
| auEvent.mEventType = kAudioUnitEvent_BeginParameterChangeGesture; | |||||
| } else { | |||||
| auEvent.mEventType = kAudioUnitEvent_EndParameterChangeGesture; | |||||
| } | |||||
| AUEventListenerNotify(mParameterListener, this, &auEvent); | |||||
| } | |||||
| void AUCarbonViewBase::Update (bool inUIThread) | |||||
| { | |||||
| for (ControlList::iterator iter = mControlList.begin(); iter != mControlList.end(); ++iter) | |||||
| { | |||||
| (*iter)->Update(inUIThread); | |||||
| } | |||||
| } | |||||
| pascal void AUCarbonViewBase::TheTimerProc (EventLoopTimerRef inTimer, void *inUserData) | |||||
| { | |||||
| AUCarbonViewBase* This = reinterpret_cast<AUCarbonViewBase*>(inUserData); | |||||
| This->RespondToEventTimer (inTimer); | |||||
| } | |||||
| void AUCarbonViewBase::RespondToEventTimer (EventLoopTimerRef inTimer) | |||||
| {} | |||||
| /* | |||||
| THESE are reasonable values for these two times | |||||
| 0.005 // delay | |||||
| 0.050 // interval | |||||
| */ | |||||
| OSStatus AUCarbonViewBase::CreateEventLoopTimer (Float32 inDelay, Float32 inInterval) | |||||
| { | |||||
| if (mTimerUPP) | |||||
| return noErr; | |||||
| mTimerUPP = NewEventLoopTimerUPP(TheTimerProc); | |||||
| EventLoopRef mainEventLoop = GetMainEventLoop(); | |||||
| //doesn't seem to like too small a value | |||||
| if (inDelay < 0.005) | |||||
| inDelay = 0.005; | |||||
| OSStatus timerResult = ::InstallEventLoopTimer( | |||||
| mainEventLoop, | |||||
| inDelay, | |||||
| inInterval, | |||||
| mTimerUPP, | |||||
| this, | |||||
| &mTimerRef); | |||||
| return timerResult; | |||||
| } | |||||
| @@ -0,0 +1,188 @@ | |||||
| /* | |||||
| File: AUCarbonViewBase.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUCarbonViewBase_h__ | |||||
| #define __AUCarbonViewBase_h__ | |||||
| #include <vector> | |||||
| #include "AUCarbonViewControl.h" | |||||
| #include "ComponentBase.h" | |||||
| static const Float32 kDefaultNotificationInterval = 0.100; | |||||
| /*! @class AUCarbonViewBase */ | |||||
| class AUCarbonViewBase : public ComponentBase, public CarbonEventHandler | |||||
| { | |||||
| public: | |||||
| /*! @ctor AUCarbonViewBase */ | |||||
| AUCarbonViewBase ( AudioUnitCarbonView inInstance, | |||||
| Float32 inNotificationInterval = kDefaultNotificationInterval /* in seconds */); | |||||
| /*! @dtor ~AUCarbonViewBase */ | |||||
| virtual ~AUCarbonViewBase(); | |||||
| // AUViewBase overrides | |||||
| /*! @method CreateCarbonView */ | |||||
| virtual OSStatus CreateCarbonView (AudioUnit inAudioUnit, WindowRef inWindow, ControlRef inParentControl, const Float32Point &inLocation, const Float32Point &inSize, ControlRef &outParentControl); | |||||
| // our own virtual methods | |||||
| /*! @method CreateUI */ | |||||
| virtual OSStatus CreateUI (Float32 inXOffset, Float32 inYOffset); | |||||
| /*! @method HandleEvent */ | |||||
| virtual bool HandleEvent (EventHandlerCallRef inHandlerRef, EventRef event); | |||||
| /*! @method GetEditAudioUnit */ | |||||
| const AudioUnit GetEditAudioUnit () const { return mEditAudioUnit; } | |||||
| // | |||||
| /*! @method ComponentEntryDispatch */ | |||||
| static OSStatus ComponentEntryDispatch ( | |||||
| ComponentParameters * params, | |||||
| AUCarbonViewBase * This); | |||||
| /*! @method AddCarbonControl */ | |||||
| void AddCarbonControl ( | |||||
| AUCarbonViewControl::ControlType type, | |||||
| const CAAUParameter & param, | |||||
| ControlRef control); | |||||
| /*! @method GetCarbonWindow */ | |||||
| WindowRef GetCarbonWindow () { return mCarbonWindow; } | |||||
| /*! @method GetCarbonPane */ | |||||
| ControlRef GetCarbonPane () { return mCarbonPane; } | |||||
| /*! @method EmbedControl */ | |||||
| OSStatus EmbedControl (ControlRef ctl); | |||||
| /*! @method TellListener */ | |||||
| void TellListener (const CAAUParameter &auvp, AudioUnitCarbonViewEventID event, void *evpar); | |||||
| // pass in true if wanting an update to the view and you're calling this from a thread | |||||
| // that is safe to do UI in. | |||||
| // If you don't know, pass in false! | |||||
| /*! @method Update */ | |||||
| void Update (bool inUIThread); | |||||
| /*! @method GetXOffset */ | |||||
| Float32 GetXOffset () { return mXOffset; } | |||||
| /*! @method GetYOffset */ | |||||
| Float32 GetYOffset () { return mYOffset; } | |||||
| /*! @method ClearControls */ | |||||
| void ClearControls (); | |||||
| /*! @method IsCompositWindow */ | |||||
| bool IsCompositWindow () const { return mCompositWindow; } | |||||
| protected: | |||||
| #if !__LP64__ | |||||
| /*! @method SetEventListener */ | |||||
| void SetEventListener (AudioUnitCarbonViewEventListener listener, void *userData) | |||||
| { | |||||
| mEventListener = listener; | |||||
| mEventListenerUserData = userData; | |||||
| } | |||||
| #endif | |||||
| /*! @method AddControl */ | |||||
| void AddControl (AUCarbonViewControl *control); | |||||
| /*! @method RemoveControl */ | |||||
| void RemoveControl (AUCarbonViewControl *control); | |||||
| OSStatus CreateEventLoopTimer (Float32 inDelay, Float32 inInterval); | |||||
| /*! @method ParameterListener */ | |||||
| static void ParameterListener (void * inCallbackRefCon, | |||||
| void * inObject, | |||||
| const AudioUnitEvent * inEvent, | |||||
| UInt64 inEventHostTime, | |||||
| Float32 inParameterValue); | |||||
| static pascal void TheTimerProc ( EventLoopTimerRef inTimer, | |||||
| void * inUserData); | |||||
| virtual void RespondToEventTimer (EventLoopTimerRef inTimer); | |||||
| /*! @var mEditAudioUnit */ | |||||
| AudioUnit mEditAudioUnit; // the AU we're controlling | |||||
| /*! @var mParameterListener */ | |||||
| AUEventListenerRef mParameterListener; | |||||
| #if !__LP64__ | |||||
| /*! @var mEventListener */ | |||||
| AudioUnitCarbonViewEventListener | |||||
| mEventListener; | |||||
| #endif | |||||
| /*! @var mEventListenerUserData */ | |||||
| void * mEventListenerUserData; | |||||
| private: | |||||
| typedef std::vector<AUCarbonViewControl *> ControlList; | |||||
| /*! @var mControlList */ | |||||
| ControlList mControlList; | |||||
| EventLoopTimerRef mTimerRef; | |||||
| EventLoopTimerUPP mTimerUPP; | |||||
| protected: | |||||
| /*! @var mCarbonWindow */ | |||||
| WindowRef mCarbonWindow; | |||||
| /*! @var mCarbonPane */ | |||||
| ControlRef mCarbonPane; // user pane, contains all other controls | |||||
| /*! @var mBottomRight */ | |||||
| Point mBottomRight; // largest width and height of child controls | |||||
| /*! @var mXOffset */ | |||||
| Float32 mXOffset; | |||||
| /*! @var mYOffset */ | |||||
| Float32 mYOffset; | |||||
| /*! @var mCompositWindow */ | |||||
| bool mCompositWindow; | |||||
| /*! @var mCurrentScrollPoint */ | |||||
| HIPoint mCurrentScrollPoint; // needed for scrolling | |||||
| }; | |||||
| #endif // __AUCarbonViewBase_h__ | |||||
| @@ -0,0 +1,710 @@ | |||||
| /* | |||||
| File: AUCarbonViewControl.cpp | |||||
| Abstract: AUCarbonViewControl.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUCarbonViewControl.h" | |||||
| #include "AUCarbonViewBase.h" | |||||
| #include "AUViewLocalizedStringKeys.h" | |||||
| AUCarbonViewControl::AUCarbonViewControl(AUCarbonViewBase *ownerView, AUParameterListenerRef listener, ControlType type, const CAAUParameter ¶m, ControlRef control) : | |||||
| mOwnerView(ownerView), | |||||
| mListener(listener), | |||||
| mType(type), | |||||
| mParam(param), | |||||
| mControl(control), | |||||
| mInControlInitialization(0) | |||||
| { | |||||
| #if !__LP64__ | |||||
| SetControlReference(control, SRefCon(this)); | |||||
| #endif | |||||
| } | |||||
| AUCarbonViewControl::~AUCarbonViewControl() | |||||
| { | |||||
| AUListenerRemoveParameter(mListener, this, &mParam); | |||||
| } | |||||
| AUCarbonViewControl* AUCarbonViewControl::mLastControl = NULL; | |||||
| void AUCarbonViewControl::Bind() | |||||
| { | |||||
| #if !__LP64__ | |||||
| mInControlInitialization = 1; // true | |||||
| AUListenerAddParameter(mListener, this, &mParam); | |||||
| // will cause an almost-immediate callback | |||||
| EventTypeSpec events[] = { | |||||
| { kEventClassControl, kEventControlValueFieldChanged } // N.B. OS X only | |||||
| }; | |||||
| WantEventTypes(GetControlEventTarget(mControl), GetEventTypeCount(events), events); | |||||
| if (mType == kTypeContinuous || mType == kTypeText || mType == kTypeDiscrete) { | |||||
| EventTypeSpec events[] = { | |||||
| { kEventClassControl, kEventControlHit }, | |||||
| { kEventClassControl, kEventControlClick }, | |||||
| { kEventClassControl, kEventControlTrack } | |||||
| }; | |||||
| WantEventTypes(GetControlEventTarget(mControl), GetEventTypeCount(events), events); | |||||
| } | |||||
| if (mType == kTypeText) { | |||||
| EventTypeSpec events[] = { | |||||
| { kEventClassControl, kEventControlSetFocusPart } | |||||
| }; | |||||
| WantEventTypes(GetControlEventTarget(mControl), GetEventTypeCount(events), events); | |||||
| ControlKeyFilterUPP proc = mParam.ValuesHaveStrings() ? StdKeyFilterCallback : NumericKeyFilterCallback; | |||||
| // this will fail for a static text field | |||||
| SetControlData(mControl, 0, kControlEditTextKeyFilterTag, sizeof(proc), &proc); | |||||
| } | |||||
| Update(true); | |||||
| mInControlInitialization = 0; // false | |||||
| #endif | |||||
| } | |||||
| void AUCarbonViewControl::ParameterToControl(Float32 paramValue) | |||||
| { | |||||
| #if !__LP64__ | |||||
| ++mInControlInitialization; | |||||
| switch (mType) { | |||||
| case kTypeContinuous: | |||||
| SetValueFract(AUParameterValueToLinear(paramValue, &mParam)); | |||||
| break; | |||||
| case kTypeDiscrete: | |||||
| { | |||||
| long value = long(paramValue); | |||||
| // special case [1] -- menu parameters | |||||
| if (mParam.HasNamedParams()) { | |||||
| // if we're dealing with menus they behave differently! | |||||
| // becaue setting min and max doesn't work correctly for the control value | |||||
| // first menu item always reports a control value of 1 | |||||
| ControlKind ctrlKind; | |||||
| if (GetControlKind(mControl, &ctrlKind) == noErr) { | |||||
| if ((ctrlKind.kind == kControlKindPopupArrow) | |||||
| || (ctrlKind.kind == kControlKindPopupButton)) | |||||
| { | |||||
| value = value - long(mParam.ParamInfo().minValue) + 1; | |||||
| } | |||||
| } | |||||
| } | |||||
| // special case [2] -- Write-only boolean parameters | |||||
| AudioUnitParameterInfo AUPI = mParam.ParamInfo(); | |||||
| bool isWriteOnlyBoolParameter = ( (AUPI.unit == kAudioUnitParameterUnit_Boolean) && | |||||
| (AUPI.flags & kAudioUnitParameterFlag_IsWritable) && | |||||
| !(AUPI.flags & kAudioUnitParameterFlag_IsReadable) ); | |||||
| if (!isWriteOnlyBoolParameter) { | |||||
| SetValue (value); | |||||
| } | |||||
| } | |||||
| break; | |||||
| case kTypeText: | |||||
| { | |||||
| CFStringRef cfstr = mParam.GetStringFromValueCopy(¶mValue); | |||||
| if ( !(mParam.ParamInfo().flags & kAudioUnitParameterFlag_IsWritable) //READ ONLY PARAMS | |||||
| && (mParam.ParamInfo().flags & kAudioUnitParameterFlag_IsReadable)) | |||||
| { | |||||
| if (mParam.GetParamTag()) { | |||||
| CFMutableStringRef str = CFStringCreateMutableCopy(NULL, 256, cfstr); | |||||
| CFRelease (cfstr); | |||||
| CFStringAppend (str, CFSTR(" ")); | |||||
| CFStringAppend (str, mParam.GetParamTag()); | |||||
| cfstr = str; | |||||
| } | |||||
| } | |||||
| SetTextValue(cfstr); | |||||
| CFRelease (cfstr); | |||||
| } | |||||
| break; | |||||
| } | |||||
| --mInControlInitialization; | |||||
| #endif | |||||
| } | |||||
| void AUCarbonViewControl::ControlToParameter() | |||||
| { | |||||
| #if !__LP64__ | |||||
| if (mInControlInitialization) | |||||
| return; | |||||
| switch (mType) { | |||||
| case kTypeContinuous: | |||||
| { | |||||
| double controlValue = GetValueFract(); | |||||
| Float32 paramValue = AUParameterValueFromLinear(controlValue, &mParam); | |||||
| mParam.SetValue(mListener, this, paramValue); | |||||
| } | |||||
| break; | |||||
| case kTypeDiscrete: | |||||
| { | |||||
| long value = GetValue(); | |||||
| // special case [1] -- Menus | |||||
| if (mParam.HasNamedParams()) { | |||||
| // if we're dealing with menus they behave differently! | |||||
| // becaue setting min and max doesn't work correctly for the control value | |||||
| // first menu item always reports a control value of 1 | |||||
| ControlKind ctrlKind; | |||||
| if (GetControlKind(mControl, &ctrlKind) == noErr) { | |||||
| if ((ctrlKind.kind == kControlKindPopupArrow) | |||||
| || (ctrlKind.kind == kControlKindPopupButton)) | |||||
| { | |||||
| value = value + long(mParam.ParamInfo().minValue) - 1; | |||||
| } | |||||
| } | |||||
| } | |||||
| // special case [2] -- Write-only boolean parameters | |||||
| AudioUnitParameterInfo AUPI = mParam.ParamInfo(); | |||||
| bool isWriteOnlyBoolParameter = ( (AUPI.unit == kAudioUnitParameterUnit_Boolean) && | |||||
| (AUPI.flags & kAudioUnitParameterFlag_IsWritable) && | |||||
| !(AUPI.flags & kAudioUnitParameterFlag_IsReadable) ); | |||||
| if (isWriteOnlyBoolParameter) { | |||||
| value = 1; | |||||
| } | |||||
| mParam.SetValue (mListener, this, value); | |||||
| } | |||||
| break; | |||||
| case kTypeText: | |||||
| { | |||||
| Float32 val = mParam.GetValueFromString (GetTextValue()); | |||||
| mParam.SetValue(mListener, this, (mParam.IsIndexedParam() ? (int)val : val)); | |||||
| if (mParam.ValuesHaveStrings()) | |||||
| ParameterToControl(val); //make sure we display the correct text (from the AU) | |||||
| } | |||||
| break; | |||||
| } | |||||
| #endif | |||||
| } | |||||
| void AUCarbonViewControl::SetValueFract(double value) | |||||
| { | |||||
| #if !__LP64__ | |||||
| SInt32 minimum = GetControl32BitMinimum(mControl); | |||||
| SInt32 maximum = GetControl32BitMaximum(mControl); | |||||
| SInt32 cval = SInt32(value * (maximum - minimum) + minimum + 0.5); | |||||
| SetControl32BitValue(mControl, cval); | |||||
| // printf("set: value=%lf, min=%ld, max=%ld, ctl value=%ld\n", value, minimum, maximum, cval); | |||||
| #endif | |||||
| } | |||||
| double AUCarbonViewControl::GetValueFract() | |||||
| { | |||||
| #if !__LP64__ | |||||
| SInt32 minimum = GetControl32BitMinimum(mControl); | |||||
| SInt32 maximum = GetControl32BitMaximum(mControl); | |||||
| SInt32 cval = GetControl32BitValue(mControl); | |||||
| double result = double(cval - minimum) / double(maximum - minimum); | |||||
| // printf("get: min=%ld, max=%ld, value=%ld, result=%f\n", minimum, maximum, cval, result); | |||||
| return result; | |||||
| #else | |||||
| return 0; | |||||
| #endif | |||||
| } | |||||
| void AUCarbonViewControl::SetTextValue(CFStringRef cfstr) | |||||
| { | |||||
| #if !__LP64__ | |||||
| verify_noerr(SetControlData(mControl, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), &cfstr)); | |||||
| #endif | |||||
| } | |||||
| CFStringRef AUCarbonViewControl::GetTextValue() | |||||
| { | |||||
| #if !__LP64__ | |||||
| CFStringRef cfstr; | |||||
| verify_noerr(GetControlData(mControl, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), &cfstr, NULL)); | |||||
| return cfstr; | |||||
| #else | |||||
| return CFSTR(""); | |||||
| #endif | |||||
| } | |||||
| void AUCarbonViewControl::SetValue(long value) | |||||
| { | |||||
| #if !__LP64__ | |||||
| SetControl32BitValue(mControl, value); | |||||
| #endif | |||||
| } | |||||
| long AUCarbonViewControl::GetValue() | |||||
| { | |||||
| #if !__LP64__ | |||||
| return GetControl32BitValue(mControl); | |||||
| #else | |||||
| return 0; | |||||
| #endif | |||||
| } | |||||
| /* Notes on event handling | |||||
| Button (Click and release on button) | |||||
| kEventControlClick received | |||||
| kEventControlTrack received | |||||
| kEventControlValueFieldChanged received | |||||
| kEventControlHit received | |||||
| Button (Click and release outside of button bounds) | |||||
| kEventControlClick received | |||||
| kEventControlTrack received | |||||
| Slider (Click, drag, and release) | |||||
| kEventControlClick received | |||||
| kEventControlTrack received | |||||
| kEventControlValueFieldChanged received | |||||
| kEventControlValueFieldChanged received | |||||
| kEventControlHit received | |||||
| Slider (Click, release without changing value) | |||||
| kEventControlClick received | |||||
| kEventControlTrack received | |||||
| */ | |||||
| bool AUCarbonViewControl::HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event) | |||||
| { | |||||
| UInt32 eclass = GetEventClass(event); | |||||
| UInt32 ekind = GetEventKind(event); | |||||
| ControlRef control; | |||||
| bool handled = true; | |||||
| switch (eclass) { | |||||
| case kEventClassControl: | |||||
| { | |||||
| AudioUnitParameterInfo AUPI = mParam.ParamInfo(); | |||||
| bool isWriteOnlyBoolParameter = ( (AUPI.unit == kAudioUnitParameterUnit_Boolean) && | |||||
| (AUPI.flags & kAudioUnitParameterFlag_IsWritable) && | |||||
| !(AUPI.flags & kAudioUnitParameterFlag_IsReadable) ); | |||||
| switch (ekind) { | |||||
| case kEventControlSetFocusPart: // tab | |||||
| handled = !handled; // fall through to next case | |||||
| mLastControl = this; | |||||
| case kEventControlValueFieldChanged: | |||||
| GetEventParameter(event, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &control); | |||||
| verify(control == mControl); | |||||
| ControlToParameter(); | |||||
| return handled; | |||||
| case kEventControlClick: | |||||
| if (isWriteOnlyBoolParameter) { | |||||
| GetEventParameter(event, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &control); | |||||
| verify(control == mControl); | |||||
| ControlToParameter(); | |||||
| } else if (mLastControl != this) { | |||||
| if (mLastControl != NULL) { | |||||
| mLastControl->Update(false); | |||||
| } | |||||
| mLastControl = this; | |||||
| } | |||||
| mOwnerView->TellListener(mParam, kAudioUnitCarbonViewEvent_MouseDownInControl, NULL); | |||||
| break; // don't return true, continue normal processing | |||||
| case kEventControlHit: | |||||
| if (mLastControl != this) { | |||||
| if (mLastControl != NULL) | |||||
| mLastControl->Update(false); | |||||
| mLastControl = this; | |||||
| } | |||||
| mOwnerView->TellListener(mParam, kAudioUnitCarbonViewEvent_MouseUpInControl, NULL); | |||||
| break; // don't return true, continue normal processing | |||||
| case kEventControlTrack: | |||||
| if (mLastControl != this) { | |||||
| if (mLastControl != NULL) | |||||
| mLastControl->Update(false); | |||||
| mLastControl = this; | |||||
| } | |||||
| CallNextEventHandler(inHandlerRef, event); | |||||
| ControlToParameter(); // new code | |||||
| mOwnerView->TellListener(mParam, kAudioUnitCarbonViewEvent_MouseUpInControl, NULL); | |||||
| // old code: | |||||
| // break; // don't return true, continue normal processing | |||||
| return handled; // don't return true, continue normal processing | |||||
| } | |||||
| } | |||||
| } | |||||
| return !handled; | |||||
| } | |||||
| pascal void AUCarbonViewControl::SliderTrackProc(ControlRef theControl, ControlPartCode partCode) | |||||
| { | |||||
| // this doesn't need to actually do anything | |||||
| // AUCarbonViewControl *This = (AUCarbonViewControl *)GetControlReference(theControl); | |||||
| } | |||||
| pascal ControlKeyFilterResult AUCarbonViewControl::StdKeyFilterCallback(ControlRef theControl, | |||||
| SInt16 *keyCode, SInt16 *charCode, | |||||
| EventModifiers *modifiers) | |||||
| { | |||||
| #if !__LP64__ | |||||
| SInt16 c = *charCode; | |||||
| if (c >= ' ' || c == '\b' || c == 0x7F || (c >= 0x1c && c <= 0x1f) || c == '\t') | |||||
| return kControlKeyFilterPassKey; | |||||
| if (c == '\r' || c == 3) { // return or Enter | |||||
| AUCarbonViewControl *This = (AUCarbonViewControl *)GetControlReference(theControl); | |||||
| ControlEditTextSelectionRec sel = { 0, 32767 }; | |||||
| SetControlData(This->mControl, 0, kControlEditTextSelectionTag, sizeof(sel), &sel); | |||||
| This->ControlToParameter(); | |||||
| } | |||||
| #endif | |||||
| return kControlKeyFilterBlockKey; | |||||
| } | |||||
| pascal ControlKeyFilterResult AUCarbonViewControl::NumericKeyFilterCallback(ControlRef theControl, | |||||
| SInt16 *keyCode, SInt16 *charCode, | |||||
| EventModifiers *modifiers) | |||||
| { | |||||
| #if !__LP64__ | |||||
| SInt16 c = *charCode; | |||||
| if (isdigit(c) || c == '+' || c == '-' || c == '.' || c == '\b' || c == 0x7F || (c >= 0x1c && c <= 0x1f) | |||||
| || c == '\t') | |||||
| return kControlKeyFilterPassKey; | |||||
| if (c == '\r' || c == 3) { // return or Enter | |||||
| AUCarbonViewControl *This = (AUCarbonViewControl *)GetControlReference(theControl); | |||||
| ControlEditTextSelectionRec sel = { 0, 32767 }; | |||||
| SetControlData(This->mControl, 0, kControlEditTextSelectionTag, sizeof(sel), &sel); | |||||
| This->ControlToParameter(); | |||||
| } | |||||
| #endif | |||||
| return kControlKeyFilterBlockKey; | |||||
| } | |||||
| Boolean AUCarbonViewControl::SizeControlToFit(ControlRef inControl, SInt16 *outWidth, SInt16 *outHeight) | |||||
| { | |||||
| #if !__LP64__ | |||||
| if (inControl == 0) return false; | |||||
| Boolean bValue = false; | |||||
| // this only works on text controls -- returns an error for other controls, but doesn't do anything, | |||||
| // so the error is irrelevant | |||||
| SetControlData(inControl, kControlEntireControl, 'stim' /* kControlStaticTextIsMultilineTag */, sizeof(Boolean), &bValue); | |||||
| SInt16 baseLineOffset; | |||||
| Rect bestRect; | |||||
| OSErr err = GetBestControlRect(inControl, &bestRect, &baseLineOffset); | |||||
| if (err != noErr) return false; | |||||
| int width = (bestRect.right - bestRect.left) + 1; | |||||
| int height = (bestRect.bottom - bestRect.top) + 1; | |||||
| Rect boundsRect; | |||||
| GetControlBounds (inControl, &boundsRect); | |||||
| Rect newRect; | |||||
| newRect.top = boundsRect.top; | |||||
| newRect.bottom = newRect.top + height; | |||||
| newRect.left = boundsRect.left; | |||||
| newRect.right = newRect.left + width; | |||||
| SetControlBounds (inControl, &newRect); | |||||
| if (outWidth) | |||||
| *outWidth = width; | |||||
| if (outHeight) | |||||
| *outHeight = height; | |||||
| #endif | |||||
| return true; | |||||
| } | |||||
| #pragma mark ___AUPropertyControl | |||||
| bool AUPropertyControl::HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event) | |||||
| { | |||||
| UInt32 eclass = GetEventClass(event); | |||||
| UInt32 ekind = GetEventKind(event); | |||||
| switch (eclass) { | |||||
| case kEventClassControl: | |||||
| switch (ekind) { | |||||
| case kEventControlValueFieldChanged: | |||||
| HandleControlChange(); | |||||
| return true; // handled | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| void AUPropertyControl::RegisterEvents () | |||||
| { | |||||
| #if !__LP64__ | |||||
| EventTypeSpec events[] = { | |||||
| { kEventClassControl, kEventControlValueFieldChanged } // N.B. OS X only | |||||
| }; | |||||
| WantEventTypes(GetControlEventTarget(mControl), GetEventTypeCount(events), events); | |||||
| #endif | |||||
| } | |||||
| void AUPropertyControl::EmbedControl (ControlRef theControl) | |||||
| { | |||||
| mView->EmbedControl (theControl); | |||||
| } | |||||
| WindowRef AUPropertyControl::GetCarbonWindow() | |||||
| { | |||||
| return mView->GetCarbonWindow(); | |||||
| } | |||||
| #pragma mark ___AUVPreset | |||||
| #if !__LP64__ | |||||
| static CFStringRef kStringFactoryPreset = kAUViewLocalizedStringKey_FactoryPreset; | |||||
| static bool sAUVPresetLocalized = false; | |||||
| #endif | |||||
| AUVPresets::AUVPresets (AUCarbonViewBase* inParentView, | |||||
| CFArrayRef& inPresets, | |||||
| Point inLocation, | |||||
| int nameWidth, | |||||
| int controlWidth, | |||||
| ControlFontStyleRec & inFontStyle) | |||||
| : AUPropertyControl (inParentView), | |||||
| mPresets (inPresets), | |||||
| mView (inParentView) | |||||
| { | |||||
| #if !__LP64__ | |||||
| Rect r; | |||||
| // ok we now have an array of factory presets | |||||
| // get their strings and display them | |||||
| r.top = inLocation.v; r.bottom = r.top; | |||||
| r.left = inLocation.h; r.right = r.left; | |||||
| // localize as necessary | |||||
| if (!sAUVPresetLocalized) { | |||||
| CFBundleRef mainBundle = CFBundleGetBundleWithIdentifier(kLocalizedStringBundle_AUView); | |||||
| if (mainBundle) { | |||||
| kStringFactoryPreset = CFCopyLocalizedStringFromTableInBundle( | |||||
| kAUViewLocalizedStringKey_FactoryPreset, kLocalizedStringTable_AUView, | |||||
| mainBundle, CFSTR("FactoryPreset title string")); | |||||
| sAUVPresetLocalized = true; | |||||
| } | |||||
| } | |||||
| // create localized title string | |||||
| CFMutableStringRef factoryPresetsTitle = CFStringCreateMutable(NULL, 0); | |||||
| CFStringAppend(factoryPresetsTitle, kStringFactoryPreset); | |||||
| CFStringAppend(factoryPresetsTitle, kAUViewUnlocalizedString_TitleSeparator); | |||||
| ControlRef theControl; | |||||
| verify_noerr(CreateStaticTextControl(mView->GetCarbonWindow(), &r, factoryPresetsTitle, &inFontStyle, &theControl)); | |||||
| SInt16 width = 0; | |||||
| AUCarbonViewControl::SizeControlToFit(theControl, &width, &mHeight); | |||||
| CFRelease(factoryPresetsTitle); | |||||
| EmbedControl(theControl); | |||||
| r.top -= 2; | |||||
| r.left += width + 10; | |||||
| r.right = r.left; | |||||
| r.bottom = r.top; | |||||
| verify_noerr(CreatePopupButtonControl ( mView->GetCarbonWindow(), &r, NULL, | |||||
| -12345, // DON'T GET MENU FROM RESOURCE mMenuID,!!! | |||||
| FALSE, // variableWidth, | |||||
| 0, // titleWidth, | |||||
| 0, // titleJustification, | |||||
| 0, // titleStyle, | |||||
| &mControl)); | |||||
| MenuRef menuRef; | |||||
| verify_noerr(CreateNewMenu(1, 0, &menuRef)); | |||||
| int numPresets = CFArrayGetCount(mPresets); | |||||
| for (int i = 0; i < numPresets; ++i) | |||||
| { | |||||
| AUPreset* preset = (AUPreset*) CFArrayGetValueAtIndex (mPresets, i); | |||||
| verify_noerr(AppendMenuItemTextWithCFString (menuRef, preset->presetName, 0, 0, 0)); | |||||
| } | |||||
| verify_noerr(SetControlData(mControl, 0, kControlPopupButtonMenuRefTag, sizeof(menuRef), &menuRef)); | |||||
| verify_noerr (SetControlFontStyle (mControl, &inFontStyle)); | |||||
| SetControl32BitMaximum (mControl, numPresets); | |||||
| // size popup | |||||
| SInt16 height = 0; | |||||
| AUCarbonViewControl::SizeControlToFit(mControl, &width, &height); | |||||
| if (height > mHeight) mHeight = height; | |||||
| if (mHeight < 0) mHeight = 0; | |||||
| // find which menu item is the Default preset | |||||
| UInt32 propertySize = sizeof(AUPreset); | |||||
| AUPreset defaultPreset; | |||||
| OSStatus result = AudioUnitGetProperty (mView->GetEditAudioUnit(), | |||||
| kAudioUnitProperty_PresentPreset, | |||||
| kAudioUnitScope_Global, | |||||
| 0, | |||||
| &defaultPreset, | |||||
| &propertySize); | |||||
| mPropertyID = kAudioUnitProperty_PresentPreset; | |||||
| #endif | |||||
| #ifndef __LP64__ | |||||
| if (result != noErr) { // if the PresentPreset property is not implemented, fall back to the CurrentPreset property | |||||
| OSStatus result = AudioUnitGetProperty (mView->GetEditAudioUnit(), | |||||
| kAudioUnitProperty_CurrentPreset, | |||||
| kAudioUnitScope_Global, | |||||
| 0, | |||||
| &defaultPreset, | |||||
| &propertySize); | |||||
| mPropertyID = kAudioUnitProperty_CurrentPreset; | |||||
| if (result == noErr) | |||||
| CFRetain (defaultPreset.presetName); | |||||
| } | |||||
| #endif | |||||
| #if !__LP64__ | |||||
| EmbedControl (mControl); | |||||
| HandlePropertyChange(defaultPreset); | |||||
| RegisterEvents(); | |||||
| #endif | |||||
| } | |||||
| void AUVPresets::AddInterest (AUEventListenerRef inListener, | |||||
| void * inObject) | |||||
| { | |||||
| AudioUnitEvent e; | |||||
| e.mEventType = kAudioUnitEvent_PropertyChange; | |||||
| e.mArgument.mProperty.mAudioUnit = mView->GetEditAudioUnit(); | |||||
| e.mArgument.mProperty.mPropertyID = mPropertyID; | |||||
| e.mArgument.mProperty.mScope = kAudioUnitScope_Global; | |||||
| e.mArgument.mProperty.mElement = 0; | |||||
| AUEventListenerAddEventType(inListener, inObject, &e); | |||||
| } | |||||
| void AUVPresets::RemoveInterest (AUEventListenerRef inListener, | |||||
| void * inObject) | |||||
| { | |||||
| AudioUnitEvent e; | |||||
| e.mEventType = kAudioUnitEvent_PropertyChange; | |||||
| e.mArgument.mProperty.mAudioUnit = mView->GetEditAudioUnit(); | |||||
| e.mArgument.mProperty.mPropertyID = mPropertyID; | |||||
| e.mArgument.mProperty.mScope = kAudioUnitScope_Global; | |||||
| e.mArgument.mProperty.mElement = 0; | |||||
| AUEventListenerRemoveEventType(inListener, inObject, &e); | |||||
| } | |||||
| void AUVPresets::HandleControlChange () | |||||
| { | |||||
| #if !__LP64__ | |||||
| SInt32 i = GetControl32BitValue(mControl); | |||||
| if (i > 0) | |||||
| { | |||||
| AUPreset* preset = (AUPreset*) CFArrayGetValueAtIndex (mPresets, i-1); | |||||
| verify_noerr(AudioUnitSetProperty (mView->GetEditAudioUnit(), | |||||
| mPropertyID, // either currentPreset or PresentPreset depending on which is supported | |||||
| kAudioUnitScope_Global, | |||||
| 0, | |||||
| preset, | |||||
| sizeof(AUPreset))); | |||||
| // when we change a preset we can't expect the AU to update its state | |||||
| // as it isn't meant to know that its being viewed! | |||||
| // so we broadcast a notification to all listeners that all parameters on this AU have changed | |||||
| AudioUnitParameter changedUnit; | |||||
| changedUnit.mAudioUnit = mView->GetEditAudioUnit(); | |||||
| changedUnit.mParameterID = kAUParameterListener_AnyParameter; | |||||
| verify_noerr (AUParameterListenerNotify (NULL, NULL, &changedUnit) ); | |||||
| } | |||||
| #endif | |||||
| } | |||||
| void AUVPresets::HandlePropertyChange(AUPreset &preset) | |||||
| { | |||||
| #if !__LP64__ | |||||
| // check to see if the preset is in our menu | |||||
| int numPresets = CFArrayGetCount(mPresets); | |||||
| if (preset.presetNumber < 0) { | |||||
| SetControl32BitValue (mControl, 0); //controls are one-based | |||||
| } else { | |||||
| for (SInt32 i = 0; i < numPresets; ++i) { | |||||
| AUPreset* currPreset = (AUPreset*) CFArrayGetValueAtIndex (mPresets, i); | |||||
| if (preset.presetNumber == currPreset->presetNumber) { | |||||
| SetControl32BitValue (mControl, ++i); //controls are one-based | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| if (preset.presetName) | |||||
| CFRelease (preset.presetName); | |||||
| #endif | |||||
| } | |||||
| bool AUVPresets::HandlePropertyChange (const AudioUnitProperty &inProp) | |||||
| { | |||||
| if (inProp.mPropertyID == mPropertyID) | |||||
| { | |||||
| UInt32 theSize = sizeof(AUPreset); | |||||
| AUPreset currentPreset; | |||||
| OSStatus result = AudioUnitGetProperty(inProp.mAudioUnit, | |||||
| inProp.mPropertyID, | |||||
| inProp.mScope, | |||||
| inProp.mElement, ¤tPreset, &theSize); | |||||
| if (result == noErr) { | |||||
| #ifndef __LP64__ | |||||
| if (inProp.mPropertyID == kAudioUnitProperty_CurrentPreset && currentPreset.presetName) | |||||
| CFRetain (currentPreset.presetName); | |||||
| #endif | |||||
| HandlePropertyChange(currentPreset); | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| @@ -0,0 +1,230 @@ | |||||
| /* | |||||
| File: AUCarbonViewControl.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUCarbonViewControl_h__ | |||||
| #define __AUCarbonViewControl_h__ | |||||
| #include <Carbon/Carbon.h> | |||||
| #include <AudioUnit/AudioUnitCarbonView.h> | |||||
| #include <AudioToolbox/AudioUnitUtilities.h> | |||||
| #include "CarbonEventHandler.h" | |||||
| #include "CAAUParameter.h" | |||||
| class AUCarbonViewBase; | |||||
| // ____________________________________________________________________________ | |||||
| // AUCarbonViewControl | |||||
| // Wrapper for a control that is wired to an AudioUnit parameter. | |||||
| /*! @class AUCarbonViewControl */ | |||||
| class AUCarbonViewControl : public CarbonEventHandler { | |||||
| // note that the controls are never disposed; that's managed by the AUCarbonViewBase's | |||||
| // parent pane which contains all of them ... if we later need to be able to delete | |||||
| // individual controls on the fly, extra work needed | |||||
| public: | |||||
| enum ControlType { | |||||
| kTypeContinuous, // e.g. slider | |||||
| kTypeDiscrete, // e.g. pop-up menu | |||||
| kTypeText | |||||
| }; | |||||
| AUCarbonViewControl(AUCarbonViewBase *ownerView, AUParameterListenerRef listener, ControlType type, const CAAUParameter ¶m, ControlRef control); | |||||
| ~AUCarbonViewControl(); | |||||
| /*! @method Bind */ | |||||
| virtual void Bind(); // second-stage construction | |||||
| /*! @method ControlToParameter */ | |||||
| virtual void ControlToParameter(); | |||||
| /*! @method ParameterToControl */ | |||||
| virtual void ParameterToControl(Float32 newValue); | |||||
| /*! @method SetValueFract */ | |||||
| virtual void SetValueFract(double value); | |||||
| /*! @method GetValueFract */ | |||||
| virtual double GetValueFract(); | |||||
| /*! @method SetTextValue */ | |||||
| virtual void SetTextValue(CFStringRef str); | |||||
| /*! @method GetTextValue */ | |||||
| virtual CFStringRef GetTextValue(); | |||||
| /*! @method SetValue */ | |||||
| virtual void SetValue(long value); | |||||
| /*! @method GetValue */ | |||||
| virtual long GetValue(); | |||||
| /*! @method GetOwnerView */ | |||||
| AUCarbonViewBase * GetOwnerView() {return mOwnerView;} | |||||
| /*! @method Update */ | |||||
| void Update (bool inUIThread) | |||||
| { | |||||
| if (inUIThread) | |||||
| ParameterToControl (mParam.GetValue()); | |||||
| else | |||||
| AUParameterListenerNotify (mListener, this, &mParam); | |||||
| } | |||||
| // CarbonEventHandler overrides | |||||
| /*! @method HandleEvent */ | |||||
| virtual bool HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event); | |||||
| /*! @method ControlRef */ | |||||
| operator ControlRef() { return mControl; } | |||||
| /*! @method SizeControlToFit */ | |||||
| static Boolean SizeControlToFit(ControlRef inControl, SInt16 *outWidth = NULL, SInt16 *outHeight = NULL); | |||||
| /*! @method SliderTrackProc */ | |||||
| static pascal void SliderTrackProc(ControlRef theControl, ControlPartCode partCode); | |||||
| /*! @method NumericKeyFilterCallback */ | |||||
| static pascal ControlKeyFilterResult NumericKeyFilterCallback(ControlRef theControl, SInt16 *keyCode, SInt16 *charCode, | |||||
| EventModifiers *modifiers); | |||||
| protected: | |||||
| /*! @method ParamInfo */ | |||||
| const AudioUnitParameterInfo &ParamInfo() { return mParam.ParamInfo(); } | |||||
| /*! @var mOwnerView */ | |||||
| AUCarbonViewBase * mOwnerView; | |||||
| /*! @var mListener */ | |||||
| AUParameterListenerRef mListener; | |||||
| /*! @var mType */ | |||||
| ControlType mType; | |||||
| /*! @var mParam */ | |||||
| CAAUParameter mParam; | |||||
| /*! @var mControl */ | |||||
| ControlRef mControl; | |||||
| /*! @method StdKeyFilterCallback */ | |||||
| static pascal ControlKeyFilterResult StdKeyFilterCallback(ControlRef theControl, SInt16 *keyCode, SInt16 *charCode, | |||||
| EventModifiers *modifiers); | |||||
| SInt16 mInControlInitialization; | |||||
| static AUCarbonViewControl* mLastControl; | |||||
| }; | |||||
| /*! @class AUPropertyControl */ | |||||
| class AUPropertyControl : public CarbonEventHandler { | |||||
| public: | |||||
| /*! @ctor AUPropertyControl */ | |||||
| AUPropertyControl (AUCarbonViewBase * inBase) : mControl(0), mView (inBase), mHeight(0) {} | |||||
| /*! @method HandleEvent */ | |||||
| virtual bool HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event); | |||||
| /*! @method HandlePropertyChange */ | |||||
| virtual bool HandlePropertyChange (const AudioUnitProperty &inProp) = 0; | |||||
| /*! @method AddInterest */ | |||||
| virtual void AddInterest (AUEventListenerRef inListener, | |||||
| void * inObject) = 0; | |||||
| /*! @method RemoveInterest */ | |||||
| virtual void RemoveInterest (AUEventListenerRef inListener, | |||||
| void * inObject) = 0; | |||||
| /*! @method GetHeight */ | |||||
| int GetHeight() { return mHeight;} | |||||
| protected: | |||||
| /*! @method HandleControlChange */ | |||||
| virtual void HandleControlChange () = 0; | |||||
| /*! @method RegisterEvents */ | |||||
| void RegisterEvents (); | |||||
| /*! @method EmbedControl */ | |||||
| void EmbedControl (ControlRef theControl); | |||||
| /*! @method GetCarbonWindow */ | |||||
| WindowRef GetCarbonWindow(); | |||||
| /*! @var mControl */ | |||||
| ControlRef mControl; | |||||
| /*! @var mView */ | |||||
| AUCarbonViewBase* mView; | |||||
| /*! @var mHeight */ | |||||
| SInt16 mHeight; | |||||
| }; | |||||
| /*! @class AUVPresets */ | |||||
| class AUVPresets : public AUPropertyControl { | |||||
| public: | |||||
| /*! @ctor HandleControlChange */ | |||||
| AUVPresets (AUCarbonViewBase * inBase, | |||||
| CFArrayRef& inPresets, | |||||
| Point inLocation, | |||||
| int nameWidth, | |||||
| int controlWidth, | |||||
| ControlFontStyleRec & inFontStyle); | |||||
| virtual ~AUVPresets () { CFRelease (mPresets); } | |||||
| /*! @method HandlePropertyChange */ | |||||
| virtual bool HandlePropertyChange (const AudioUnitProperty &inProp); | |||||
| /*! @method AddInterest */ | |||||
| virtual void AddInterest (AUEventListenerRef inListener, | |||||
| void * inObject); | |||||
| /*! @method RemoveInterest */ | |||||
| virtual void RemoveInterest (AUEventListenerRef inListener, | |||||
| void * inObject); | |||||
| protected: | |||||
| /*! @method HandleControlChange */ | |||||
| virtual void HandleControlChange (); | |||||
| /*! @var mPresets */ | |||||
| CFArrayRef mPresets; | |||||
| /*! @var mView */ | |||||
| AUCarbonViewBase* mView; | |||||
| AudioUnitPropertyID mPropertyID; | |||||
| void HandlePropertyChange(AUPreset &preset); | |||||
| }; | |||||
| #endif // __AUCarbonViewControl_h__ | |||||
| @@ -0,0 +1,125 @@ | |||||
| /* | |||||
| File: AUCarbonViewDispatch.cpp | |||||
| Abstract: AUCarbonViewDispatch.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUCarbonViewBase.h" | |||||
| // ____________________________________________________________________________ | |||||
| // component dispatch | |||||
| #if PRAGMA_STRUCT_ALIGN | |||||
| #pragma options align=mac68k | |||||
| #elif PRAGMA_STRUCT_PACKPUSH | |||||
| #pragma pack(push, 2) | |||||
| #elif PRAGMA_STRUCT_PACK | |||||
| #pragma pack(2) | |||||
| #endif | |||||
| struct AudioUnitCarbonViewCreateGluePB { | |||||
| unsigned char componentFlags; | |||||
| unsigned char componentParamSize; | |||||
| short componentWhat; | |||||
| ControlRef* outControl; | |||||
| const Float32Point* inSize; | |||||
| const Float32Point* inLocation; | |||||
| ControlRef inParentControl; | |||||
| WindowRef inWindow; | |||||
| AudioUnit inAudioUnit; | |||||
| AudioUnitCarbonView inView; | |||||
| }; | |||||
| #if !__LP64__ | |||||
| struct AudioUnitCarbonViewSetEventListenerGluePB { | |||||
| unsigned char componentFlags; | |||||
| unsigned char componentParamSize; | |||||
| short componentWhat; | |||||
| void* inUserData; | |||||
| AudioUnitCarbonViewEventListener inCallback; | |||||
| AudioUnitCarbonView inView; | |||||
| }; | |||||
| #endif | |||||
| #if PRAGMA_STRUCT_ALIGN | |||||
| #pragma options align=reset | |||||
| #elif PRAGMA_STRUCT_PACKPUSH | |||||
| #pragma pack(pop) | |||||
| #elif PRAGMA_STRUCT_PACK | |||||
| #pragma pack() | |||||
| #endif | |||||
| #define CheckNull(x) if ((x) == NULL) return paramErr; | |||||
| OSStatus AUCarbonViewBase::ComponentEntryDispatch(ComponentParameters *p, AUCarbonViewBase *This) | |||||
| { | |||||
| if (This == NULL) return paramErr; | |||||
| OSStatus result = noErr; | |||||
| switch (p->what) { | |||||
| case kAudioUnitCarbonViewCreateSelect: | |||||
| { | |||||
| AudioUnitCarbonViewCreateGluePB *pb = (AudioUnitCarbonViewCreateGluePB *)p; | |||||
| CheckNull(pb->inAudioUnit); | |||||
| CheckNull(pb->inWindow); | |||||
| CheckNull(pb->inParentControl); | |||||
| CheckNull(pb->inSize); | |||||
| CheckNull(pb->inLocation); | |||||
| CheckNull(pb->outControl); | |||||
| result = This->CreateCarbonView(pb->inAudioUnit, pb->inWindow, pb->inParentControl, | |||||
| *pb->inLocation, *pb->inSize, *pb->outControl); | |||||
| } | |||||
| break; | |||||
| #if !__LP64__ | |||||
| case kAudioUnitCarbonViewSetEventListenerSelect: | |||||
| { | |||||
| AudioUnitCarbonViewSetEventListenerGluePB *pb = (AudioUnitCarbonViewSetEventListenerGluePB *)p; | |||||
| This->SetEventListener(pb->inCallback, pb->inUserData); | |||||
| } | |||||
| break; | |||||
| #endif | |||||
| default: | |||||
| result = ComponentBase::ComponentEntryDispatch(p, This); | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| @@ -0,0 +1,438 @@ | |||||
| /* | |||||
| File: AUDispatch.cpp | |||||
| Abstract: AUDispatch.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUBase.h" | |||||
| #include "CAXException.h" | |||||
| #include "AUDispatch.h" | |||||
| #if TARGET_OS_MAC | |||||
| #if __LP64__ | |||||
| // comp instance, parameters in forward order | |||||
| #define PARAM(_typ, _name, _index, _nparams) \ | |||||
| _typ _name = *(_typ *)¶ms->params[_index + 1]; | |||||
| #else | |||||
| // parameters in reverse order, then comp instance | |||||
| #define PARAM(_typ, _name, _index, _nparams) \ | |||||
| _typ _name = *(_typ *)¶ms->params[_nparams - 1 - _index]; | |||||
| #endif | |||||
| #elif TARGET_OS_WIN32 | |||||
| // (no comp instance), parameters in forward order | |||||
| #define PARAM(_typ, _name, _index, _nparams) \ | |||||
| _typ _name = *(_typ *)¶ms->params[_index]; | |||||
| #endif | |||||
| OSStatus AUBase::ComponentEntryDispatch(ComponentParameters *params, AUBase *This) | |||||
| { | |||||
| if (This == NULL) return kAudio_ParamError; | |||||
| OSStatus result = noErr; | |||||
| switch (params->what) { | |||||
| case kComponentCanDoSelect: | |||||
| switch (GetSelectorForCanDo(params)) { | |||||
| // any selectors | |||||
| case kAudioUnitInitializeSelect: | |||||
| case kAudioUnitUninitializeSelect: | |||||
| case kAudioUnitGetPropertyInfoSelect: | |||||
| case kAudioUnitGetPropertySelect: | |||||
| case kAudioUnitSetPropertySelect: | |||||
| case kAudioUnitAddPropertyListenerSelect: | |||||
| #if (!__LP64__) | |||||
| case kAudioUnitRemovePropertyListenerSelect: | |||||
| #endif | |||||
| case kAudioUnitGetParameterSelect: | |||||
| case kAudioUnitSetParameterSelect: | |||||
| case kAudioUnitResetSelect: | |||||
| result = 1; | |||||
| break; | |||||
| // v1 selectors | |||||
| // v2 selectors | |||||
| case kAudioUnitRemovePropertyListenerWithUserDataSelect: | |||||
| case kAudioUnitAddRenderNotifySelect: | |||||
| case kAudioUnitRemoveRenderNotifySelect: | |||||
| case kAudioUnitScheduleParametersSelect: | |||||
| case kAudioUnitRenderSelect: | |||||
| result = (This->AudioUnitAPIVersion() > 1); | |||||
| break; | |||||
| default: | |||||
| return ComponentBase::ComponentEntryDispatch(params, This); | |||||
| } | |||||
| break; | |||||
| case kAudioUnitInitializeSelect: | |||||
| { | |||||
| CAMutex::Locker lock2(This->GetMutex()); | |||||
| result = This->DoInitialize(); | |||||
| } | |||||
| break; | |||||
| case kAudioUnitUninitializeSelect: | |||||
| { | |||||
| CAMutex::Locker lock2(This->GetMutex()); | |||||
| This->DoCleanup(); | |||||
| result = noErr; | |||||
| } | |||||
| break; | |||||
| case kAudioUnitGetPropertyInfoSelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AudioUnitPropertyID, pinID, 0, 5); | |||||
| PARAM(AudioUnitScope, pinScope, 1, 5); | |||||
| PARAM(AudioUnitElement, pinElement, 2, 5); | |||||
| PARAM(UInt32 *, poutDataSize, 3, 5); | |||||
| PARAM(Boolean *, poutWritable, 4, 5); | |||||
| // pass our own copies so that we assume responsibility for testing | |||||
| // the caller's pointers against null and our C++ classes can | |||||
| // always assume they're non-null | |||||
| UInt32 dataSize; | |||||
| Boolean writable; | |||||
| result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable); | |||||
| if (poutDataSize != NULL) | |||||
| *poutDataSize = dataSize; | |||||
| if (poutWritable != NULL) | |||||
| *poutWritable = writable; | |||||
| } | |||||
| break; | |||||
| case kAudioUnitGetPropertySelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AudioUnitPropertyID, pinID, 0, 5); | |||||
| PARAM(AudioUnitScope, pinScope, 1, 5); | |||||
| PARAM(AudioUnitElement, pinElement, 2, 5); | |||||
| PARAM(void *, poutData, 3, 5); | |||||
| PARAM(UInt32 *, pioDataSize, 4, 5); | |||||
| UInt32 actualPropertySize, clientBufferSize; | |||||
| Boolean writable; | |||||
| char *tempBuffer; | |||||
| void *destBuffer; | |||||
| if (pioDataSize == NULL) { | |||||
| ca_debug_string("AudioUnitGetProperty: null size pointer"); | |||||
| result = kAudio_ParamError; | |||||
| goto finishGetProperty; | |||||
| } | |||||
| if (poutData == NULL) { | |||||
| UInt32 dataSize; | |||||
| result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable); | |||||
| *pioDataSize = dataSize; | |||||
| goto finishGetProperty; | |||||
| } | |||||
| clientBufferSize = *pioDataSize; | |||||
| if (clientBufferSize == 0) | |||||
| { | |||||
| ca_debug_string("AudioUnitGetProperty: *ioDataSize == 0 on entry"); | |||||
| // $$$ or should we allow this as a shortcut for finding the size? | |||||
| result = kAudio_ParamError; | |||||
| goto finishGetProperty; | |||||
| } | |||||
| result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, | |||||
| actualPropertySize, writable); | |||||
| if (result) | |||||
| goto finishGetProperty; | |||||
| if (clientBufferSize < actualPropertySize) | |||||
| { | |||||
| tempBuffer = new char[actualPropertySize]; | |||||
| destBuffer = tempBuffer; | |||||
| } else { | |||||
| tempBuffer = NULL; | |||||
| destBuffer = poutData; | |||||
| } | |||||
| result = This->DispatchGetProperty(pinID, pinScope, pinElement, destBuffer); | |||||
| if (result == noErr) { | |||||
| if (clientBufferSize < actualPropertySize && tempBuffer != NULL) | |||||
| { | |||||
| memcpy(poutData, tempBuffer, clientBufferSize); | |||||
| delete[] tempBuffer; | |||||
| // pioDataSize remains correct, the number of bytes we wrote | |||||
| } else | |||||
| *pioDataSize = actualPropertySize; | |||||
| } else | |||||
| *pioDataSize = 0; | |||||
| finishGetProperty: | |||||
| ; | |||||
| } | |||||
| break; | |||||
| case kAudioUnitSetPropertySelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AudioUnitPropertyID, pinID, 0, 5); | |||||
| PARAM(AudioUnitScope, pinScope, 1, 5); | |||||
| PARAM(AudioUnitElement, pinElement, 2, 5); | |||||
| PARAM(const void *, pinData, 3, 5); | |||||
| PARAM(UInt32, pinDataSize, 4, 5); | |||||
| if (pinData && pinDataSize) | |||||
| result = This->DispatchSetProperty(pinID, pinScope, pinElement, pinData, pinDataSize); | |||||
| else { | |||||
| if (pinData == NULL && pinDataSize == 0) { | |||||
| result = This->DispatchRemovePropertyValue (pinID, pinScope, pinElement); | |||||
| } else { | |||||
| if (pinData == NULL) { | |||||
| ca_debug_string("AudioUnitSetProperty: inData == NULL"); | |||||
| result = kAudio_ParamError; | |||||
| goto finishSetProperty; | |||||
| } | |||||
| if (pinDataSize == 0) { | |||||
| ca_debug_string("AudioUnitSetProperty: inDataSize == 0"); | |||||
| result = kAudio_ParamError; | |||||
| goto finishSetProperty; | |||||
| } | |||||
| } | |||||
| } | |||||
| finishSetProperty: | |||||
| ; | |||||
| } | |||||
| break; | |||||
| case kAudioUnitAddPropertyListenerSelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AudioUnitPropertyID, pinID, 0, 3); | |||||
| PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3); | |||||
| PARAM(void *, pinProcRefCon, 2, 3); | |||||
| result = This->AddPropertyListener(pinID, pinProc, pinProcRefCon); | |||||
| } | |||||
| break; | |||||
| #if (!__LP64__) | |||||
| case kAudioUnitRemovePropertyListenerSelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AudioUnitPropertyID, pinID, 0, 2); | |||||
| PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 2); | |||||
| result = This->RemovePropertyListener(pinID, pinProc, NULL, false); | |||||
| } | |||||
| break; | |||||
| #endif | |||||
| case kAudioUnitRemovePropertyListenerWithUserDataSelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AudioUnitPropertyID, pinID, 0, 3); | |||||
| PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3); | |||||
| PARAM(void *, pinProcRefCon, 2, 3); | |||||
| result = This->RemovePropertyListener(pinID, pinProc, pinProcRefCon, true); | |||||
| } | |||||
| break; | |||||
| case kAudioUnitAddRenderNotifySelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AURenderCallback, pinProc, 0, 2); | |||||
| PARAM(void *, pinProcRefCon, 1, 2); | |||||
| result = This->SetRenderNotification (pinProc, pinProcRefCon); | |||||
| } | |||||
| break; | |||||
| case kAudioUnitRemoveRenderNotifySelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AURenderCallback, pinProc, 0, 2); | |||||
| PARAM(void *, pinProcRefCon, 1, 2); | |||||
| result = This->RemoveRenderNotification (pinProc, pinProcRefCon); | |||||
| } | |||||
| break; | |||||
| case kAudioUnitGetParameterSelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AudioUnitParameterID, pinID, 0, 4); | |||||
| PARAM(AudioUnitScope, pinScope, 1, 4); | |||||
| PARAM(AudioUnitElement, pinElement, 2, 4); | |||||
| PARAM(AudioUnitParameterValue *, poutValue, 3, 4); | |||||
| result = (poutValue == NULL ? kAudio_ParamError : This->GetParameter(pinID, pinScope, pinElement, *poutValue)); | |||||
| } | |||||
| break; | |||||
| case kAudioUnitSetParameterSelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); // is this realtime or no??? | |||||
| PARAM(AudioUnitParameterID, pinID, 0, 5); | |||||
| PARAM(AudioUnitScope, pinScope, 1, 5); | |||||
| PARAM(AudioUnitElement, pinElement, 2, 5); | |||||
| PARAM(AudioUnitParameterValue, pinValue, 3, 5); | |||||
| PARAM(UInt32, pinBufferOffsetInFrames, 4, 5); | |||||
| result = This->SetParameter(pinID, pinScope, pinElement, pinValue, pinBufferOffsetInFrames); | |||||
| } | |||||
| break; | |||||
| case kAudioUnitScheduleParametersSelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); // is this realtime or no??? | |||||
| if (This->AudioUnitAPIVersion() > 1) | |||||
| { | |||||
| PARAM(AudioUnitParameterEvent *, pinParameterEvent, 0, 2); | |||||
| PARAM(UInt32, pinNumParamEvents, 1, 2); | |||||
| result = This->ScheduleParameter (pinParameterEvent, pinNumParamEvents); | |||||
| } else | |||||
| result = badComponentSelector; | |||||
| } | |||||
| break; | |||||
| case kAudioUnitRenderSelect: | |||||
| { | |||||
| // realtime; no lock | |||||
| { | |||||
| PARAM(AudioUnitRenderActionFlags *, pinActionFlags, 0, 5); | |||||
| PARAM(const AudioTimeStamp *, pinTimeStamp, 1, 5); | |||||
| PARAM(UInt32, pinOutputBusNumber, 2, 5); | |||||
| PARAM(UInt32, pinNumberFrames, 3, 5); | |||||
| PARAM(AudioBufferList *, pioData, 4, 5); | |||||
| AudioUnitRenderActionFlags tempFlags; | |||||
| if (pinTimeStamp == NULL || pioData == NULL) | |||||
| result = kAudio_ParamError; | |||||
| else { | |||||
| if (pinActionFlags == NULL) { | |||||
| tempFlags = 0; | |||||
| pinActionFlags = &tempFlags; | |||||
| } | |||||
| result = This->DoRender(*pinActionFlags, *pinTimeStamp, pinOutputBusNumber, pinNumberFrames, *pioData); | |||||
| } | |||||
| } | |||||
| } | |||||
| break; | |||||
| case kAudioUnitResetSelect: | |||||
| { | |||||
| CAMutex::Locker lock(This->GetMutex()); | |||||
| PARAM(AudioUnitScope, pinScope, 0, 2); | |||||
| PARAM(AudioUnitElement, pinElement, 1, 2); | |||||
| This->ResetRenderTime(); | |||||
| result = This->Reset(pinScope, pinElement); | |||||
| } | |||||
| break; | |||||
| default: | |||||
| result = ComponentBase::ComponentEntryDispatch(params, This); | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| // Fast dispatch entry points -- these need to replicate all error-checking logic from above | |||||
| OSStatus CMgr_AudioUnitBaseGetParameter( AUBase * This, | |||||
| AudioUnitParameterID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| float *outValue) | |||||
| { | |||||
| OSStatus result = AUBase::noErr; | |||||
| try { | |||||
| if (This == NULL || outValue == NULL) return kAudio_ParamError; | |||||
| result = This->GetParameter(inID, inScope, inElement, *outValue); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| OSStatus CMgr_AudioUnitBaseSetParameter( AUBase * This, | |||||
| AudioUnitParameterID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| float inValue, | |||||
| UInt32 inBufferOffset) | |||||
| { | |||||
| OSStatus result = AUBase::noErr; | |||||
| try { | |||||
| if (This == NULL) return kAudio_ParamError; | |||||
| result = This->SetParameter(inID, inScope, inElement, inValue, inBufferOffset); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| OSStatus CMgr_AudioUnitBaseRender( AUBase * This, | |||||
| AudioUnitRenderActionFlags *ioActionFlags, | |||||
| const AudioTimeStamp * inTimeStamp, | |||||
| UInt32 inBusNumber, | |||||
| UInt32 inNumberFrames, | |||||
| AudioBufferList * ioData) | |||||
| { | |||||
| if (inTimeStamp == NULL || ioData == NULL) return kAudio_ParamError; | |||||
| OSStatus result = AUBase::noErr; | |||||
| AudioUnitRenderActionFlags tempFlags; | |||||
| try { | |||||
| if (ioActionFlags == NULL) { | |||||
| tempFlags = 0; | |||||
| ioActionFlags = &tempFlags; | |||||
| } | |||||
| result = This->DoRender(*ioActionFlags, *inTimeStamp, inBusNumber, inNumberFrames, *ioData); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| @@ -0,0 +1,82 @@ | |||||
| /* | |||||
| File: AUDispatch.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUDispatch_h__ | |||||
| #define __AUDispatch_h__ | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <AudioUnit/AudioUnit.h> | |||||
| #else | |||||
| #include "AudioUnit.h" | |||||
| #endif | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| /*! @function AudioUnitBaseGetParameter */ | |||||
| OSStatus CMgr_AudioUnitBaseGetParameter( AUBase * This, | |||||
| AudioUnitParameterID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| float * outValue); | |||||
| /*! @function AudioUnitBaseSetParameter */ | |||||
| OSStatus CMgr_AudioUnitBaseSetParameter( AUBase * This, | |||||
| AudioUnitParameterID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| float inValue, | |||||
| UInt32 inBufferOffset); | |||||
| /*! @function AudioUnitBaseRender */ | |||||
| OSStatus CMgr_AudioUnitBaseRender( AUBase * This, | |||||
| AudioUnitRenderActionFlags *ioActionFlags, | |||||
| const AudioTimeStamp * inTimeStamp, | |||||
| UInt32 inBusNumber, | |||||
| UInt32 inNumberFrames, | |||||
| AudioBufferList * ioData); | |||||
| #endif | |||||
| #endif // __AUDispatch_h__ | |||||
| @@ -0,0 +1,465 @@ | |||||
| /* | |||||
| File: AUEffectBase.cpp | |||||
| Abstract: AUEffectBase.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUEffectBase.h" | |||||
| /* | |||||
| This class does not deal as well as it should with N-M effects... | |||||
| The problem areas are (if the channels don't match): | |||||
| ProcessInPlace if the channels don't match - there will be problems if InputChan != OutputChan | |||||
| Bypass - its just passing the buffers through when not processing them | |||||
| This will be fixed in a future update... | |||||
| */ | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| AUEffectBase::AUEffectBase( AudioComponentInstance audioUnit, | |||||
| bool inProcessesInPlace ) : | |||||
| AUBase(audioUnit, 1, 1), // 1 in bus, 1 out bus | |||||
| mBypassEffect(false), | |||||
| mParamSRDep (false), | |||||
| mProcessesInPlace(inProcessesInPlace), | |||||
| mMainOutput(NULL), mMainInput(NULL) | |||||
| #if TARGET_OS_IPHONE | |||||
| , mOnlyOneKernel(false) | |||||
| #endif | |||||
| { | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| AUEffectBase::~AUEffectBase() | |||||
| { | |||||
| Cleanup(); | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUEffectBase::Cleanup() | |||||
| { | |||||
| for (KernelList::iterator it = mKernelList.begin(); it != mKernelList.end(); ++it) | |||||
| delete *it; | |||||
| mKernelList.clear(); | |||||
| mMainOutput = NULL; | |||||
| mMainInput = NULL; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| OSStatus AUEffectBase::Initialize() | |||||
| { | |||||
| // get our current numChannels for input and output | |||||
| SInt16 auNumInputs = (SInt16) GetInput(0)->GetStreamFormat().mChannelsPerFrame; | |||||
| SInt16 auNumOutputs = (SInt16) GetOutput(0)->GetStreamFormat().mChannelsPerFrame; | |||||
| // does the unit publish specific information about channel configurations? | |||||
| const AUChannelInfo *auChannelConfigs = NULL; | |||||
| UInt32 numIOconfigs = SupportedNumChannels(&auChannelConfigs); | |||||
| if ((numIOconfigs > 0) && (auChannelConfigs != NULL)) | |||||
| { | |||||
| bool foundMatch = false; | |||||
| for (UInt32 i = 0; (i < numIOconfigs) && !foundMatch; ++i) | |||||
| { | |||||
| SInt16 configNumInputs = auChannelConfigs[i].inChannels; | |||||
| SInt16 configNumOutputs = auChannelConfigs[i].outChannels; | |||||
| if ((configNumInputs < 0) && (configNumOutputs < 0)) | |||||
| { | |||||
| // unit accepts any number of channels on input and output | |||||
| if (((configNumInputs == -1) && (configNumOutputs == -2)) | |||||
| || ((configNumInputs == -2) && (configNumOutputs == -1))) | |||||
| { | |||||
| foundMatch = true; | |||||
| // unit accepts any number of channels on input and output IFF they are the same number on both scopes | |||||
| } | |||||
| else if (((configNumInputs == -1) && (configNumOutputs == -1)) && (auNumInputs == auNumOutputs)) | |||||
| { | |||||
| foundMatch = true; | |||||
| // unit has specified a particular number of channels on both scopes | |||||
| } | |||||
| else | |||||
| continue; | |||||
| } | |||||
| else | |||||
| { | |||||
| // the -1 case on either scope is saying that the unit doesn't care about the | |||||
| // number of channels on that scope | |||||
| bool inputMatch = (auNumInputs == configNumInputs) || (configNumInputs == -1); | |||||
| bool outputMatch = (auNumOutputs == configNumOutputs) || (configNumOutputs == -1); | |||||
| if (inputMatch && outputMatch) | |||||
| foundMatch = true; | |||||
| } | |||||
| } | |||||
| if (!foundMatch) | |||||
| return kAudioUnitErr_FormatNotSupported; | |||||
| } | |||||
| else | |||||
| { | |||||
| // there is no specifically published channel info | |||||
| // so for those kinds of effects, the assumption is that the channels (whatever their number) | |||||
| // should match on both scopes | |||||
| if ((auNumOutputs != auNumInputs) || (auNumOutputs == 0)) | |||||
| { | |||||
| return kAudioUnitErr_FormatNotSupported; | |||||
| } | |||||
| } | |||||
| MaintainKernels(); | |||||
| mMainOutput = GetOutput(0); | |||||
| mMainInput = GetInput(0); | |||||
| const CAStreamBasicDescription& format = GetStreamFormat(kAudioUnitScope_Output, 0); | |||||
| format.IdentifyCommonPCMFormat(mCommonPCMFormat, NULL); | |||||
| mBytesPerFrame = format.mBytesPerFrame; | |||||
| return noErr; | |||||
| } | |||||
| OSStatus AUEffectBase::Reset( AudioUnitScope inScope, | |||||
| AudioUnitElement inElement) | |||||
| { | |||||
| for (KernelList::iterator it = mKernelList.begin(); it != mKernelList.end(); ++it) { | |||||
| AUKernelBase *kernel = *it; | |||||
| if (kernel != NULL) | |||||
| kernel->Reset(); | |||||
| } | |||||
| return AUBase::Reset(inScope, inElement); | |||||
| } | |||||
| OSStatus AUEffectBase::GetPropertyInfo (AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 & outDataSize, | |||||
| Boolean & outWritable) | |||||
| { | |||||
| if (inScope == kAudioUnitScope_Global) { | |||||
| switch (inID) { | |||||
| case kAudioUnitProperty_BypassEffect: | |||||
| outWritable = true; | |||||
| outDataSize = sizeof (UInt32); | |||||
| return noErr; | |||||
| case kAudioUnitProperty_InPlaceProcessing: | |||||
| outWritable = true; | |||||
| outDataSize = sizeof (UInt32); | |||||
| return noErr; | |||||
| } | |||||
| } | |||||
| return AUBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable); | |||||
| } | |||||
| OSStatus AUEffectBase::GetProperty (AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| void * outData) | |||||
| { | |||||
| if (inScope == kAudioUnitScope_Global) { | |||||
| switch (inID) { | |||||
| case kAudioUnitProperty_BypassEffect: | |||||
| *((UInt32*)outData) = (IsBypassEffect() ? 1 : 0); | |||||
| return noErr; | |||||
| case kAudioUnitProperty_InPlaceProcessing: | |||||
| *((UInt32*)outData) = (mProcessesInPlace ? 1 : 0); | |||||
| return noErr; | |||||
| } | |||||
| } | |||||
| return AUBase::GetProperty (inID, inScope, inElement, outData); | |||||
| } | |||||
| OSStatus AUEffectBase::SetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const void * inData, | |||||
| UInt32 inDataSize) | |||||
| { | |||||
| if (inScope == kAudioUnitScope_Global) { | |||||
| switch (inID) { | |||||
| case kAudioUnitProperty_BypassEffect: | |||||
| { | |||||
| if (inDataSize < sizeof(UInt32)) | |||||
| return kAudioUnitErr_InvalidPropertyValue; | |||||
| bool tempNewSetting = *((UInt32*)inData) != 0; | |||||
| // we're changing the state of bypass | |||||
| if (tempNewSetting != IsBypassEffect()) | |||||
| { | |||||
| if (!tempNewSetting && IsBypassEffect() && IsInitialized()) // turning bypass off and we're initialized | |||||
| Reset(0, 0); | |||||
| SetBypassEffect (tempNewSetting); | |||||
| } | |||||
| return noErr; | |||||
| } | |||||
| case kAudioUnitProperty_InPlaceProcessing: | |||||
| mProcessesInPlace = (*((UInt32*)inData) != 0); | |||||
| return noErr; | |||||
| } | |||||
| } | |||||
| return AUBase::SetProperty (inID, inScope, inElement, inData, inDataSize); | |||||
| } | |||||
| void AUEffectBase::MaintainKernels() | |||||
| { | |||||
| #if TARGET_OS_IPHONE | |||||
| UInt32 nKernels = mOnlyOneKernel ? 1 : GetNumberOfChannels(); | |||||
| #else | |||||
| UInt32 nKernels = GetNumberOfChannels(); | |||||
| #endif | |||||
| if (mKernelList.size() < nKernels) { | |||||
| mKernelList.reserve(nKernels); | |||||
| for (UInt32 i = (UInt32)mKernelList.size(); i < nKernels; ++i) | |||||
| mKernelList.push_back(NewKernel()); | |||||
| } else { | |||||
| while (mKernelList.size() > nKernels) { | |||||
| AUKernelBase *kernel = mKernelList.back(); | |||||
| delete kernel; | |||||
| mKernelList.pop_back(); | |||||
| } | |||||
| } | |||||
| for(unsigned int i = 0; i < nKernels; i++ ) | |||||
| { | |||||
| if(mKernelList[i]) { | |||||
| mKernelList[i]->SetChannelNum (i); | |||||
| } | |||||
| } | |||||
| } | |||||
| bool AUEffectBase::StreamFormatWritable( AudioUnitScope scope, | |||||
| AudioUnitElement element) | |||||
| { | |||||
| return IsInitialized() ? false : true; | |||||
| } | |||||
| OSStatus AUEffectBase::ChangeStreamFormat( AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const CAStreamBasicDescription & inPrevFormat, | |||||
| const CAStreamBasicDescription & inNewFormat) | |||||
| { | |||||
| OSStatus result = AUBase::ChangeStreamFormat(inScope, inElement, inPrevFormat, inNewFormat); | |||||
| if (result == noErr) | |||||
| { | |||||
| // for the moment this only dependency we know about | |||||
| // where a parameter's range may change is with the sample rate | |||||
| // and effects are only publishing parameters in the global scope! | |||||
| if (GetParamHasSampleRateDependency() && fnotequal(inPrevFormat.mSampleRate, inNewFormat.mSampleRate)) | |||||
| PropertyChanged(kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, 0); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| // ____________________________________________________________________________ | |||||
| // | |||||
| // This method is called (potentially repeatedly) by ProcessForScheduledParams() | |||||
| // in order to perform the actual DSP required for this portion of the entire buffer | |||||
| // being processed. The entire buffer can be divided up into smaller "slices" | |||||
| // according to the timestamps on the scheduled parameters... | |||||
| // | |||||
| OSStatus AUEffectBase::ProcessScheduledSlice( void *inUserData, | |||||
| UInt32 inStartFrameInBuffer, | |||||
| UInt32 inSliceFramesToProcess, | |||||
| UInt32 inTotalBufferFrames ) | |||||
| { | |||||
| ScheduledProcessParams &sliceParams = *((ScheduledProcessParams*)inUserData); | |||||
| AudioUnitRenderActionFlags &actionFlags = *sliceParams.actionFlags; | |||||
| AudioBufferList &inputBufferList = *sliceParams.inputBufferList; | |||||
| AudioBufferList &outputBufferList = *sliceParams.outputBufferList; | |||||
| UInt32 channelSize = inSliceFramesToProcess * mBytesPerFrame; | |||||
| // fix the size of the buffer we're operating on before we render this slice of time | |||||
| for(unsigned int i = 0; i < inputBufferList.mNumberBuffers; i++ ) { | |||||
| inputBufferList.mBuffers[i].mDataByteSize = inputBufferList.mBuffers[i].mNumberChannels * channelSize; | |||||
| } | |||||
| for(unsigned int i = 0; i < outputBufferList.mNumberBuffers; i++ ) { | |||||
| outputBufferList.mBuffers[i].mDataByteSize = outputBufferList.mBuffers[i].mNumberChannels * channelSize; | |||||
| } | |||||
| // process the buffer | |||||
| OSStatus result = ProcessBufferLists(actionFlags, inputBufferList, outputBufferList, inSliceFramesToProcess ); | |||||
| // we just partially processed the buffers, so increment the data pointers to the next part of the buffer to process | |||||
| for(unsigned int i = 0; i < inputBufferList.mNumberBuffers; i++ ) { | |||||
| inputBufferList.mBuffers[i].mData = | |||||
| (char *)inputBufferList.mBuffers[i].mData + inputBufferList.mBuffers[i].mNumberChannels * channelSize; | |||||
| } | |||||
| for(unsigned int i = 0; i < outputBufferList.mNumberBuffers; i++ ) { | |||||
| outputBufferList.mBuffers[i].mData = | |||||
| (char *)outputBufferList.mBuffers[i].mData + outputBufferList.mBuffers[i].mNumberChannels * channelSize; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| // ____________________________________________________________________________ | |||||
| // | |||||
| OSStatus AUEffectBase::Render( AudioUnitRenderActionFlags &ioActionFlags, | |||||
| const AudioTimeStamp & inTimeStamp, | |||||
| UInt32 nFrames) | |||||
| { | |||||
| if (!HasInput(0)) | |||||
| return kAudioUnitErr_NoConnection; | |||||
| OSStatus result = noErr; | |||||
| result = mMainInput->PullInput(ioActionFlags, inTimeStamp, 0 /* element */, nFrames); | |||||
| if (result == noErr) | |||||
| { | |||||
| if(ProcessesInPlace() && mMainOutput->WillAllocateBuffer()) | |||||
| { | |||||
| mMainOutput->SetBufferList(mMainInput->GetBufferList() ); | |||||
| } | |||||
| if (ShouldBypassEffect()) | |||||
| { | |||||
| // leave silence bit alone | |||||
| if(!ProcessesInPlace() ) | |||||
| { | |||||
| mMainInput->CopyBufferContentsTo (mMainOutput->GetBufferList()); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| if(mParamList.size() == 0 ) | |||||
| { | |||||
| // this will read/write silence bit | |||||
| result = ProcessBufferLists(ioActionFlags, mMainInput->GetBufferList(), mMainOutput->GetBufferList(), nFrames); | |||||
| } | |||||
| else | |||||
| { | |||||
| // deal with scheduled parameters... | |||||
| AudioBufferList &inputBufferList = mMainInput->GetBufferList(); | |||||
| AudioBufferList &outputBufferList = mMainOutput->GetBufferList(); | |||||
| ScheduledProcessParams processParams; | |||||
| processParams.actionFlags = &ioActionFlags; | |||||
| processParams.inputBufferList = &inputBufferList; | |||||
| processParams.outputBufferList = &outputBufferList; | |||||
| // divide up the buffer into slices according to scheduled params then | |||||
| // do the DSP for each slice (ProcessScheduledSlice() called for each slice) | |||||
| result = ProcessForScheduledParams( mParamList, | |||||
| nFrames, | |||||
| &processParams ); | |||||
| // fixup the buffer pointers to how they were before we started | |||||
| UInt32 channelSize = nFrames * mBytesPerFrame; | |||||
| for(unsigned int i = 0; i < inputBufferList.mNumberBuffers; i++ ) { | |||||
| UInt32 size = inputBufferList.mBuffers[i].mNumberChannels * channelSize; | |||||
| inputBufferList.mBuffers[i].mData = (char *)inputBufferList.mBuffers[i].mData - size; | |||||
| inputBufferList.mBuffers[i].mDataByteSize = size; | |||||
| } | |||||
| for(unsigned int i = 0; i < outputBufferList.mNumberBuffers; i++ ) { | |||||
| UInt32 size = outputBufferList.mBuffers[i].mNumberChannels * channelSize; | |||||
| outputBufferList.mBuffers[i].mData = (char *)outputBufferList.mBuffers[i].mData - size; | |||||
| outputBufferList.mBuffers[i].mDataByteSize = size; | |||||
| } | |||||
| } | |||||
| } | |||||
| if ( (ioActionFlags & kAudioUnitRenderAction_OutputIsSilence) && !ProcessesInPlace() ) | |||||
| { | |||||
| AUBufferList::ZeroBuffer(mMainOutput->GetBufferList() ); | |||||
| } | |||||
| } | |||||
| return result; | |||||
| } | |||||
| OSStatus AUEffectBase::ProcessBufferLists( | |||||
| AudioUnitRenderActionFlags & ioActionFlags, | |||||
| const AudioBufferList & inBuffer, | |||||
| AudioBufferList & outBuffer, | |||||
| UInt32 inFramesToProcess ) | |||||
| { | |||||
| if (ShouldBypassEffect()) | |||||
| return noErr; | |||||
| // interleaved (or mono) | |||||
| switch (mCommonPCMFormat) { | |||||
| case CAStreamBasicDescription::kPCMFormatFloat32 : | |||||
| ProcessBufferListsT<Float32>(ioActionFlags, inBuffer, outBuffer, inFramesToProcess); | |||||
| break; | |||||
| case CAStreamBasicDescription::kPCMFormatFixed824 : | |||||
| ProcessBufferListsT<SInt32>(ioActionFlags, inBuffer, outBuffer, inFramesToProcess); | |||||
| break; | |||||
| case CAStreamBasicDescription::kPCMFormatInt16 : | |||||
| ProcessBufferListsT<SInt16>(ioActionFlags, inBuffer, outBuffer, inFramesToProcess); | |||||
| break; | |||||
| default : | |||||
| throw CAException(kAudio_UnimplementedError); | |||||
| } | |||||
| return noErr; | |||||
| } | |||||
| Float64 AUEffectBase::GetSampleRate() | |||||
| { | |||||
| return GetOutput(0)->GetStreamFormat().mSampleRate; | |||||
| } | |||||
| UInt32 AUEffectBase::GetNumberOfChannels() | |||||
| { | |||||
| return GetOutput(0)->GetStreamFormat().mChannelsPerFrame; | |||||
| } | |||||
| @@ -0,0 +1,377 @@ | |||||
| /* | |||||
| File: AUEffectBase.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUEffectBase_h__ | |||||
| #define __AUEffectBase_h__ | |||||
| #include "AUBase.h" | |||||
| #include "AUSilentTimeout.h" | |||||
| #include "CAException.h" | |||||
| class AUKernelBase; | |||||
| // Base class for an effect with one input stream, one output stream, | |||||
| // any number of channels. | |||||
| /*! @class AUEffectBase */ | |||||
| class AUEffectBase : public AUBase { | |||||
| public: | |||||
| /*! @ctor AUEffectBase */ | |||||
| AUEffectBase( AudioComponentInstance audioUnit, | |||||
| bool inProcessesInPlace = true ); | |||||
| /*! @dtor ~AUEffectBase */ | |||||
| ~AUEffectBase(); | |||||
| /*! @method Initialize */ | |||||
| virtual OSStatus Initialize(); | |||||
| /*! @method Cleanup */ | |||||
| virtual void Cleanup(); | |||||
| /*! @method Reset */ | |||||
| virtual OSStatus Reset( AudioUnitScope inScope, | |||||
| AudioUnitElement inElement); | |||||
| /*! @method GetPropertyInfo */ | |||||
| virtual OSStatus GetPropertyInfo (AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 & outDataSize, | |||||
| Boolean & outWritable); | |||||
| /*! @method GetProperty */ | |||||
| virtual OSStatus GetProperty (AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| void * outData); | |||||
| /*! @method SetProperty */ | |||||
| virtual OSStatus SetProperty(AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const void * inData, | |||||
| UInt32 inDataSize); | |||||
| /*! @method StreamFormatWritable */ | |||||
| virtual bool StreamFormatWritable (AudioUnitScope scope, | |||||
| AudioUnitElement element); | |||||
| /*! @method ChangeStreamFormat */ | |||||
| virtual OSStatus ChangeStreamFormat ( | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const CAStreamBasicDescription & inPrevFormat, | |||||
| const CAStreamBasicDescription & inNewFormat); | |||||
| /*! @method Render */ | |||||
| virtual OSStatus Render(AudioUnitRenderActionFlags & ioActionFlags, | |||||
| const AudioTimeStamp & inTimeStamp, | |||||
| UInt32 inNumberFrames); | |||||
| // our virtual methods | |||||
| // If your unit processes N to N channels, and there are no interactions between channels, | |||||
| // it can override NewKernel to create a mono processing object per channel. Otherwise, | |||||
| // don't override NewKernel, and instead, override ProcessBufferLists. | |||||
| /*! @method NewKernel */ | |||||
| virtual AUKernelBase * NewKernel() { return NULL; } | |||||
| /*! @method ProcessBufferLists */ | |||||
| virtual OSStatus ProcessBufferLists( | |||||
| AudioUnitRenderActionFlags & ioActionFlags, | |||||
| const AudioBufferList & inBuffer, | |||||
| AudioBufferList & outBuffer, | |||||
| UInt32 inFramesToProcess ); | |||||
| // convenience format accessors (use output 0's format) | |||||
| /*! @method GetSampleRate */ | |||||
| Float64 GetSampleRate(); | |||||
| /*! @method GetNumberOfChannels */ | |||||
| UInt32 GetNumberOfChannels(); | |||||
| // convenience wrappers for accessing parameters in the global scope | |||||
| /*! @method SetParameter */ | |||||
| using AUBase::SetParameter; | |||||
| void SetParameter( AudioUnitParameterID paramID, | |||||
| AudioUnitParameterValue value) | |||||
| { | |||||
| Globals()->SetParameter(paramID, value); | |||||
| } | |||||
| /*! @method GetParameter */ | |||||
| using AUBase::GetParameter; | |||||
| AudioUnitParameterValue GetParameter( AudioUnitParameterID paramID ) | |||||
| { | |||||
| return Globals()->GetParameter(paramID ); | |||||
| } | |||||
| /*! @method CanScheduleParameters */ | |||||
| virtual bool CanScheduleParameters() const { return true; } | |||||
| /*! @method IsBypassEffect */ | |||||
| // This is used for the property value - to reflect to the UI if an effect is bypassed | |||||
| bool IsBypassEffect () { return mBypassEffect; } | |||||
| protected: | |||||
| /*! @method MaintainKernels */ | |||||
| void MaintainKernels(); | |||||
| /*! @method ShouldBypassEffect */ | |||||
| // This is used in the render call to see if an effect is bypassed | |||||
| // It can return a different status than IsBypassEffect (though it MUST take that into account) | |||||
| virtual bool ShouldBypassEffect () { return IsBypassEffect(); } | |||||
| public: | |||||
| /*! @method SetBypassEffect */ | |||||
| virtual void SetBypassEffect (bool inFlag) { mBypassEffect = inFlag; } | |||||
| /*! @method SetParamHasSampleRateDependency */ | |||||
| void SetParamHasSampleRateDependency (bool inFlag) | |||||
| { | |||||
| mParamSRDep = inFlag; | |||||
| } | |||||
| /*! @method GetParamHasSampleRateDependency */ | |||||
| bool GetParamHasSampleRateDependency () const { return mParamSRDep; } | |||||
| struct ScheduledProcessParams // pointer passed in as void* userData param for ProcessScheduledSlice() | |||||
| { | |||||
| AudioUnitRenderActionFlags *actionFlags; | |||||
| AudioBufferList *inputBufferList; | |||||
| AudioBufferList *outputBufferList; | |||||
| }; | |||||
| virtual OSStatus ProcessScheduledSlice( void *inUserData, | |||||
| UInt32 inStartFrameInBuffer, | |||||
| UInt32 inSliceFramesToProcess, | |||||
| UInt32 inTotalBufferFrames ); | |||||
| bool ProcessesInPlace() const {return mProcessesInPlace;}; | |||||
| void SetProcessesInPlace(bool inProcessesInPlace) {mProcessesInPlace = inProcessesInPlace;}; | |||||
| typedef std::vector<AUKernelBase *> KernelList; | |||||
| protected: | |||||
| /*! @var mKernelList */ | |||||
| KernelList mKernelList; | |||||
| AUKernelBase* GetKernel(UInt32 index) { return mKernelList[index]; } | |||||
| /*! @method IsInputSilent */ | |||||
| bool IsInputSilent (AudioUnitRenderActionFlags inActionFlags, UInt32 inFramesToProcess) | |||||
| { | |||||
| bool inputSilent = (inActionFlags & kAudioUnitRenderAction_OutputIsSilence) != 0; | |||||
| // take latency and tail time into account when propagating the silent bit | |||||
| UInt32 silentTimeoutFrames = UInt32(GetSampleRate() * (GetLatency() + GetTailTime())); | |||||
| mSilentTimeout.Process (inFramesToProcess, silentTimeoutFrames, inputSilent); | |||||
| return inputSilent; | |||||
| } | |||||
| #if TARGET_OS_IPHONE | |||||
| void SetOnlyOneKernel(bool inUseOnlyOneKernel) { mOnlyOneKernel = inUseOnlyOneKernel; } // set in ctor of subclass that wants it. | |||||
| #endif | |||||
| template <typename T> | |||||
| void ProcessBufferListsT( | |||||
| AudioUnitRenderActionFlags & ioActionFlags, | |||||
| const AudioBufferList & inBuffer, | |||||
| AudioBufferList & outBuffer, | |||||
| UInt32 inFramesToProcess ); | |||||
| CAStreamBasicDescription::CommonPCMFormat GetCommonPCMFormat() const { return mCommonPCMFormat; } | |||||
| private: | |||||
| /*! @var mBypassEffect */ | |||||
| bool mBypassEffect; | |||||
| /*! @var mParamSRDep */ | |||||
| bool mParamSRDep; | |||||
| /*! @var mProcessesInplace */ | |||||
| bool mProcessesInPlace; | |||||
| /*! @var mSilentTimeout */ | |||||
| AUSilentTimeout mSilentTimeout; | |||||
| /*! @var mMainOutput */ | |||||
| AUOutputElement * mMainOutput; | |||||
| /*! @var mMainInput */ | |||||
| AUInputElement * mMainInput; | |||||
| #if TARGET_OS_IPHONE | |||||
| /*! @var mOnlyOneKernel */ | |||||
| bool mOnlyOneKernel; | |||||
| #endif | |||||
| /*! @var mCommonPCMFormat */ | |||||
| CAStreamBasicDescription::CommonPCMFormat mCommonPCMFormat; | |||||
| UInt32 mBytesPerFrame; | |||||
| }; | |||||
| // Base class for a "kernel", an object that performs DSP on one channel of an interleaved stream. | |||||
| /*! @class AUKernelBase */ | |||||
| class AUKernelBase { | |||||
| public: | |||||
| /*! @ctor AUKernelBase */ | |||||
| AUKernelBase(AUEffectBase *inAudioUnit ) : | |||||
| mAudioUnit(inAudioUnit) { } | |||||
| /*! @dtor ~AUKernelBase */ | |||||
| virtual ~AUKernelBase() { } | |||||
| /*! @method Reset */ | |||||
| virtual void Reset() { } | |||||
| /*! @method Process */ | |||||
| virtual void Process( const Float32 * inSourceP, | |||||
| Float32 * inDestP, | |||||
| UInt32 inFramesToProcess, | |||||
| UInt32 inNumChannels, | |||||
| bool & ioSilence) { throw CAException(kAudio_UnimplementedError ); } | |||||
| /*! @method Process */ | |||||
| virtual void Process( const SInt32 * inSourceP, | |||||
| SInt32 * inDestP, | |||||
| UInt32 inFramesToProcess, | |||||
| UInt32 inNumChannels, | |||||
| bool & ioSilence) { throw CAException(kAudio_UnimplementedError ); } | |||||
| /*! @method Process */ | |||||
| virtual void Process( const SInt16 * inSourceP, | |||||
| SInt16 * inDestP, | |||||
| UInt32 inFramesToProcess, | |||||
| UInt32 inNumChannels, | |||||
| bool & ioSilence) { throw CAException(kAudio_UnimplementedError ); } | |||||
| /*! @method GetSampleRate */ | |||||
| Float64 GetSampleRate() | |||||
| { | |||||
| return mAudioUnit->GetSampleRate(); | |||||
| } | |||||
| /*! @method GetParameter */ | |||||
| AudioUnitParameterValue GetParameter (AudioUnitParameterID paramID) | |||||
| { | |||||
| return mAudioUnit->GetParameter(paramID); | |||||
| } | |||||
| void SetChannelNum (UInt32 inChan) { mChannelNum = inChan; } | |||||
| UInt32 GetChannelNum () { return mChannelNum; } | |||||
| protected: | |||||
| /*! @var mAudioUnit */ | |||||
| AUEffectBase * mAudioUnit; | |||||
| UInt32 mChannelNum; | |||||
| }; | |||||
| template <typename T> | |||||
| void AUEffectBase::ProcessBufferListsT( | |||||
| AudioUnitRenderActionFlags & ioActionFlags, | |||||
| const AudioBufferList & inBuffer, | |||||
| AudioBufferList & outBuffer, | |||||
| UInt32 inFramesToProcess ) | |||||
| { | |||||
| bool ioSilence; | |||||
| bool silentInput = IsInputSilent (ioActionFlags, inFramesToProcess); | |||||
| ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence; | |||||
| // call the kernels to handle either interleaved or deinterleaved | |||||
| if (inBuffer.mNumberBuffers == 1) { | |||||
| if (inBuffer.mBuffers[0].mNumberChannels == 0) | |||||
| throw CAException(kAudio_ParamError); | |||||
| for (UInt32 channel = 0; channel < mKernelList.size(); ++channel) { | |||||
| AUKernelBase *kernel = mKernelList[channel]; | |||||
| if (kernel == NULL) continue; | |||||
| ioSilence = silentInput; | |||||
| // process each interleaved channel individually | |||||
| kernel->Process( | |||||
| (const T *)inBuffer.mBuffers[0].mData + channel, | |||||
| (T *)outBuffer.mBuffers[0].mData + channel, | |||||
| inFramesToProcess, | |||||
| inBuffer.mBuffers[0].mNumberChannels, | |||||
| ioSilence); | |||||
| if (!ioSilence) | |||||
| ioActionFlags &= ~kAudioUnitRenderAction_OutputIsSilence; | |||||
| } | |||||
| } else { | |||||
| for (UInt32 channel = 0; channel < mKernelList.size(); ++channel) { | |||||
| AUKernelBase *kernel = mKernelList[channel]; | |||||
| if (kernel == NULL) continue; | |||||
| ioSilence = silentInput; | |||||
| const AudioBuffer *srcBuffer = &inBuffer.mBuffers[channel]; | |||||
| AudioBuffer *destBuffer = &outBuffer.mBuffers[channel]; | |||||
| kernel->Process( | |||||
| (const T *)srcBuffer->mData, | |||||
| (T *)destBuffer->mData, | |||||
| inFramesToProcess, | |||||
| 1, | |||||
| ioSilence); | |||||
| if (!ioSilence) | |||||
| ioActionFlags &= ~kAudioUnitRenderAction_OutputIsSilence; | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif // __AUEffectBase_h__ | |||||
| @@ -0,0 +1,151 @@ | |||||
| /* | |||||
| File: AUInputElement.cpp | |||||
| Abstract: AUInputElement.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUBase.h" | |||||
| inline bool HasGoodBufferPointers(const AudioBufferList &abl, UInt32 nBytes) | |||||
| { | |||||
| const AudioBuffer *buf = abl.mBuffers; | |||||
| for (UInt32 i = abl.mNumberBuffers; i--;++buf) { | |||||
| if (buf->mData == NULL || buf->mDataByteSize < nBytes) | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| // AUInputElement::AUInputElement | |||||
| // | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| AUInputElement::AUInputElement(AUBase *audioUnit) : | |||||
| AUIOElement(audioUnit), | |||||
| mInputType(kNoInput) | |||||
| { | |||||
| } | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| // AUInputElement::SetConnection | |||||
| // | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| void AUInputElement::SetConnection(const AudioUnitConnection &conn) | |||||
| { | |||||
| if (conn.sourceAudioUnit == 0) { | |||||
| Disconnect(); | |||||
| return; | |||||
| } | |||||
| mInputType = kFromConnection; | |||||
| mConnection = conn; | |||||
| AllocateBuffer(); | |||||
| mConnInstanceStorage = NULL; | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| mConnRenderProc = NULL; | |||||
| UInt32 size = sizeof(AudioUnitRenderProc); | |||||
| OSStatus result = AudioUnitGetProperty( conn.sourceAudioUnit, | |||||
| kAudioUnitProperty_FastDispatch, | |||||
| kAudioUnitScope_Global, | |||||
| kAudioUnitRenderSelect, | |||||
| &mConnRenderProc, | |||||
| &size); | |||||
| if (result == noErr) | |||||
| mConnInstanceStorage = CMgr_GetComponentInstanceStorage (conn.sourceAudioUnit); | |||||
| else | |||||
| mConnRenderProc = NULL; | |||||
| #endif | |||||
| } | |||||
| void AUInputElement::Disconnect() | |||||
| { | |||||
| mInputType = kNoInput; | |||||
| mIOBuffer.Deallocate(); | |||||
| } | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| // AUInputElement::SetInputCallback | |||||
| // | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| void AUInputElement::SetInputCallback(AURenderCallback proc, void *refCon) | |||||
| { | |||||
| if (proc == NULL) | |||||
| Disconnect(); | |||||
| else { | |||||
| mInputType = kFromCallback; | |||||
| mInputProc = proc; | |||||
| mInputProcRefCon = refCon; | |||||
| AllocateBuffer(); | |||||
| } | |||||
| } | |||||
| OSStatus AUInputElement::SetStreamFormat(const CAStreamBasicDescription &fmt) | |||||
| { | |||||
| OSStatus err = AUIOElement::SetStreamFormat(fmt); | |||||
| if (err == AUBase::noErr) | |||||
| AllocateBuffer(); | |||||
| return err; | |||||
| } | |||||
| OSStatus AUInputElement::PullInput( AudioUnitRenderActionFlags & ioActionFlags, | |||||
| const AudioTimeStamp & inTimeStamp, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 nFrames) | |||||
| { | |||||
| if (!IsActive()) | |||||
| return kAudioUnitErr_NoConnection; | |||||
| AudioBufferList *pullBuffer; | |||||
| if (HasConnection() || !WillAllocateBuffer()) | |||||
| pullBuffer = &mIOBuffer.PrepareNullBuffer(mStreamFormat, nFrames); | |||||
| else | |||||
| pullBuffer = &mIOBuffer.PrepareBuffer(mStreamFormat, nFrames); | |||||
| return PullInputWithBufferList (ioActionFlags, inTimeStamp, inElement, nFrames, pullBuffer); | |||||
| } | |||||
| @@ -0,0 +1,119 @@ | |||||
| /* | |||||
| File: AUInputElement.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUInput_h__ | |||||
| #define __AUInput_h__ | |||||
| #include "AUScopeElement.h" | |||||
| #include "AUBuffer.h" | |||||
| /*! @class AUInputElement */ | |||||
| class AUInputElement : public AUIOElement { | |||||
| public: | |||||
| /*! @ctor AUInputElement */ | |||||
| AUInputElement(AUBase *audioUnit); | |||||
| /*! @dtor ~AUInputElement */ | |||||
| virtual ~AUInputElement() { } | |||||
| // AUElement override | |||||
| /*! @method SetStreamFormat */ | |||||
| virtual OSStatus SetStreamFormat(const CAStreamBasicDescription &desc); | |||||
| /*! @method NeedsBufferSpace */ | |||||
| virtual bool NeedsBufferSpace() const { return IsCallback(); } | |||||
| /*! @method SetConnection */ | |||||
| void SetConnection(const AudioUnitConnection &conn); | |||||
| /*! @method SetInputCallback */ | |||||
| void SetInputCallback(AURenderCallback proc, void *refCon); | |||||
| /*! @method IsActive */ | |||||
| bool IsActive() const { return mInputType != kNoInput; } | |||||
| /*! @method IsCallback */ | |||||
| bool IsCallback() const { return mInputType == kFromCallback; } | |||||
| /*! @method HasConnection */ | |||||
| bool HasConnection() const { return mInputType == kFromConnection; } | |||||
| /*! @method PullInput */ | |||||
| OSStatus PullInput( AudioUnitRenderActionFlags & ioActionFlags, | |||||
| const AudioTimeStamp & inTimeStamp, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 inNumberFrames); | |||||
| /*! @method PullInputWithBufferList */ | |||||
| OSStatus PullInputWithBufferList( AudioUnitRenderActionFlags & ioActionFlags, | |||||
| const AudioTimeStamp & inTimeStamp, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 nFrames, | |||||
| AudioBufferList * inBufferList); | |||||
| protected: | |||||
| /*! @method Disconnect */ | |||||
| void Disconnect(); | |||||
| enum EInputType { kNoInput, kFromConnection, kFromCallback }; | |||||
| /*! @var mInputType */ | |||||
| EInputType mInputType; | |||||
| // if from callback: | |||||
| /*! @var mInputProc */ | |||||
| AURenderCallback mInputProc; | |||||
| /*! @var mInputProcRefCon */ | |||||
| void * mInputProcRefCon; | |||||
| // if from connection: | |||||
| /*! @var mConnection */ | |||||
| AudioUnitConnection mConnection; | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| /*! @var mConnRenderProc */ | |||||
| AudioUnitRenderProc mConnRenderProc; | |||||
| #endif | |||||
| /*! @var mConnInstanceStorage */ | |||||
| void * mConnInstanceStorage; // for the input component | |||||
| }; | |||||
| #endif // __AUInput_h__ | |||||
| @@ -0,0 +1,155 @@ | |||||
| /* | |||||
| File: AUInputFormatConverter.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUInputFormatConverter_h__ | |||||
| #define __AUInputFormatConverter_h__ | |||||
| #include "FormatConverterClient.h" | |||||
| #include "AUTimestampGenerator.h" | |||||
| // ____________________________________________________________________________ | |||||
| // AUInputFormatConverter | |||||
| // | |||||
| // Subclass of FormatConverterClient that applies a format conversion | |||||
| // to an input of an AudioUnit. | |||||
| /*! @class AUInputFormatConverter */ | |||||
| class AUInputFormatConverter : public FormatConverterClient { | |||||
| public: | |||||
| /*! @ctor AUInputFormatConverter */ | |||||
| AUInputFormatConverter(AUBase *hostAU, int inputBus) : | |||||
| mHost(hostAU), | |||||
| mHostBus(inputBus), | |||||
| mPreviousSilentFrames(0x1000) | |||||
| { | |||||
| #if DEBUG | |||||
| mTimestampGenerator.mVerbosity = 0; | |||||
| strcpy(mTimestampGenerator.mDebugName, "AUConverter"); | |||||
| #endif | |||||
| } | |||||
| // need to subsequently call Initialize, with the desired formats | |||||
| /*! @dtor ~AUInputFormatConverter */ | |||||
| ~AUInputFormatConverter() | |||||
| { | |||||
| } | |||||
| virtual OSStatus Initialize(const AudioStreamBasicDescription &src, const AudioStreamBasicDescription &dest) | |||||
| { | |||||
| OSStatus err = FormatConverterClient::Initialize(src, dest); | |||||
| if (err) return err; | |||||
| mIsPCMToPCM = (src.mFormatID == kAudioFormatLinearPCM) && (dest.mFormatID == kAudioFormatLinearPCM); | |||||
| mHasSRC = (fnonzero(src.mSampleRate) && fnonzero(dest.mSampleRate) && fnotequal(src.mSampleRate, dest.mSampleRate)); | |||||
| return ca_noErr; | |||||
| } | |||||
| virtual OSStatus Reset() | |||||
| { | |||||
| mPreviousSilentFrames = 0x1000; | |||||
| mTimestampGenerator.Reset(); | |||||
| return FormatConverterClient::Reset(); | |||||
| } | |||||
| void SetStartInputTimeAtZero(bool b) | |||||
| { | |||||
| mTimestampGenerator.SetStartInputAtZero(b); | |||||
| } | |||||
| /*! @method FillComplexBuffer */ | |||||
| OSStatus AUFillComplexBuffer(const AudioTimeStamp & inTimeStamp, | |||||
| UInt32 & ioOutputDataPacketSize, | |||||
| AudioBufferList & outOutputData, | |||||
| AudioStreamPacketDescription* outPacketDescription, | |||||
| bool& outSilence) | |||||
| { | |||||
| mTimestampGenerator.AddOutputTime(inTimeStamp, ioOutputDataPacketSize, mOutputFormat.mSampleRate); | |||||
| mSilentOutput = true; | |||||
| OSStatus err = FillComplexBuffer(ioOutputDataPacketSize, outOutputData, outPacketDescription); | |||||
| if (mSilentOutput) { | |||||
| if (!mIsPCMToPCM || (mHasSRC && mPreviousSilentFrames < 32)) | |||||
| mSilentOutput = false; | |||||
| mPreviousSilentFrames += ioOutputDataPacketSize; | |||||
| } else | |||||
| mPreviousSilentFrames = 0; | |||||
| outSilence = mSilentOutput; | |||||
| return err; | |||||
| } | |||||
| /*! @method FormatConverterInputProc */ | |||||
| virtual OSStatus FormatConverterInputProc( | |||||
| UInt32 & ioNumberDataPackets, | |||||
| AudioBufferList & ioData, | |||||
| AudioStreamPacketDescription** outDataPacketDescription) | |||||
| { | |||||
| OSStatus err = ca_noErr; | |||||
| AudioUnitRenderActionFlags actionFlags = 0; | |||||
| AUInputElement *input = mHost->GetInput(mHostBus); | |||||
| *ioNumberDataPackets = std::min(*ioNumberDataPackets, This->mHost->GetMaxFramesPerSlice()); | |||||
| const AudioTimeStamp &inputTime = mTimestampGenerator.GenerateInputTime(ioNumberDataPackets, mInputFormat.mSampleRate); | |||||
| err = input->PullInput(actionFlags, inputTime, mHostBus, ioNumberDataPackets); | |||||
| if (!err) { | |||||
| input->CopyBufferListTo(ioData); | |||||
| if (!(actionFlags & kAudioUnitRenderAction_OutputIsSilence)) | |||||
| mSilentOutput = false; | |||||
| } | |||||
| return err; | |||||
| } | |||||
| protected: | |||||
| /*! @var mHost */ | |||||
| AUBase * mHost; | |||||
| /*! @var mHostBus */ | |||||
| int mHostBus; | |||||
| AUTimestampGenerator mTimestampGenerator; | |||||
| bool mIsPCMToPCM; | |||||
| bool mHasSRC; | |||||
| bool mSilentOutput; | |||||
| UInt32 mPreviousSilentFrames; | |||||
| }; | |||||
| #endif // __AUInputFormatConverter_h__ | |||||
| @@ -0,0 +1,495 @@ | |||||
| /* | |||||
| File: AUMIDIBase.cpp | |||||
| Abstract: AUMIDIBase.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUMIDIBase.h" | |||||
| #include <CoreMIDI/CoreMIDI.h> | |||||
| #include "CAXException.h" | |||||
| //temporaray location | |||||
| enum | |||||
| { | |||||
| kMidiMessage_NoteOff = 0x80, | |||||
| kMidiMessage_NoteOn = 0x90, | |||||
| kMidiMessage_PolyPressure = 0xA0, | |||||
| kMidiMessage_ControlChange = 0xB0, | |||||
| kMidiMessage_ProgramChange = 0xC0, | |||||
| kMidiMessage_ChannelPressure = 0xD0, | |||||
| kMidiMessage_PitchWheel = 0xE0, | |||||
| kMidiController_AllSoundOff = 120, | |||||
| kMidiController_ResetAllControllers = 121, | |||||
| kMidiController_AllNotesOff = 123 | |||||
| }; | |||||
| AUMIDIBase::AUMIDIBase(AUBase* inBase) | |||||
| : mAUBaseInstance (*inBase) | |||||
| { | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| mMapManager = new CAAUMIDIMapManager(); | |||||
| #endif | |||||
| } | |||||
| AUMIDIBase::~AUMIDIBase() | |||||
| { | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| if (mMapManager) | |||||
| delete mMapManager; | |||||
| #endif | |||||
| } | |||||
| #if TARGET_API_MAC_OSX | |||||
| OSStatus AUMIDIBase::DelegateGetPropertyInfo(AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 & outDataSize, | |||||
| Boolean & outWritable) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| switch (inID) { | |||||
| #if !TARGET_OS_IPHONE | |||||
| case kMusicDeviceProperty_MIDIXMLNames: | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| if (GetXMLNames(NULL) == noErr) { | |||||
| outDataSize = sizeof(CFURLRef); | |||||
| outWritable = false; | |||||
| } else | |||||
| result = kAudioUnitErr_InvalidProperty; | |||||
| break; | |||||
| #endif | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| case kAudioUnitProperty_AllParameterMIDIMappings: | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| outWritable = true; | |||||
| outDataSize = sizeof (AUParameterMIDIMapping)*mMapManager->NumMaps(); | |||||
| result = noErr; | |||||
| break; | |||||
| case kAudioUnitProperty_HotMapParameterMIDIMapping: | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| outWritable = true; | |||||
| outDataSize = sizeof (AUParameterMIDIMapping); | |||||
| result = noErr; | |||||
| break; | |||||
| case kAudioUnitProperty_AddParameterMIDIMapping: | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| outWritable = true; | |||||
| outDataSize = sizeof (AUParameterMIDIMapping); | |||||
| result = noErr; | |||||
| break; | |||||
| case kAudioUnitProperty_RemoveParameterMIDIMapping: | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| outWritable = true; | |||||
| outDataSize = sizeof (AUParameterMIDIMapping); | |||||
| result = noErr; | |||||
| break; | |||||
| #endif | |||||
| default: | |||||
| result = kAudioUnitErr_InvalidProperty; | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| #if CA_AUTO_MIDI_MAP || (!TARGET_OS_IPHONE) | |||||
| InvalidScope: | |||||
| return kAudioUnitErr_InvalidScope; | |||||
| InvalidElement: | |||||
| return kAudioUnitErr_InvalidElement; | |||||
| #endif | |||||
| } | |||||
| OSStatus AUMIDIBase::DelegateGetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| void * outData) | |||||
| { | |||||
| OSStatus result; | |||||
| switch (inID) { | |||||
| #if !TARGET_OS_IPHONE | |||||
| case kMusicDeviceProperty_MIDIXMLNames: | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| result = GetXMLNames((CFURLRef *)outData); | |||||
| break; | |||||
| #endif | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| case kAudioUnitProperty_AllParameterMIDIMappings:{ | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| AUParameterMIDIMapping* maps = (static_cast<AUParameterMIDIMapping*>(outData)); | |||||
| mMapManager->GetMaps(maps); | |||||
| // printf ("GETTING MAPS\n"); | |||||
| // mMapManager->Print(); | |||||
| result = noErr; | |||||
| break; | |||||
| } | |||||
| case kAudioUnitProperty_HotMapParameterMIDIMapping:{ | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| AUParameterMIDIMapping * map = (static_cast<AUParameterMIDIMapping*>(outData)); | |||||
| mMapManager->GetHotParameterMap (*map); | |||||
| result = noErr; | |||||
| break; | |||||
| } | |||||
| #endif | |||||
| default: | |||||
| result = kAudioUnitErr_InvalidProperty; | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| #if CA_AUTO_MIDI_MAP || (!TARGET_OS_IPHONE) | |||||
| InvalidScope: | |||||
| return kAudioUnitErr_InvalidScope; | |||||
| InvalidElement: | |||||
| return kAudioUnitErr_InvalidElement; | |||||
| #endif | |||||
| } | |||||
| OSStatus AUMIDIBase::DelegateSetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const void * inData, | |||||
| UInt32 inDataSize) | |||||
| { | |||||
| OSStatus result; | |||||
| switch (inID) { | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| case kAudioUnitProperty_AddParameterMIDIMapping:{ | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| AUParameterMIDIMapping * maps = (AUParameterMIDIMapping*)inData; | |||||
| mMapManager->SortedInsertToParamaterMaps (maps, (inDataSize / sizeof(AUParameterMIDIMapping)), mAUBaseInstance); | |||||
| mAUBaseInstance.PropertyChanged (kAudioUnitProperty_AllParameterMIDIMappings, kAudioUnitScope_Global, 0); | |||||
| result = noErr; | |||||
| break; | |||||
| } | |||||
| case kAudioUnitProperty_RemoveParameterMIDIMapping:{ | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| AUParameterMIDIMapping * maps = (AUParameterMIDIMapping*)inData; | |||||
| bool didChange; | |||||
| mMapManager->SortedRemoveFromParameterMaps(maps, (inDataSize / sizeof(AUParameterMIDIMapping)), didChange); | |||||
| if (didChange) | |||||
| mAUBaseInstance.PropertyChanged (kAudioUnitProperty_AllParameterMIDIMappings, kAudioUnitScope_Global, 0); | |||||
| result = noErr; | |||||
| break; | |||||
| } | |||||
| case kAudioUnitProperty_HotMapParameterMIDIMapping:{ | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| AUParameterMIDIMapping & map = *((AUParameterMIDIMapping*)inData); | |||||
| mMapManager->SetHotMapping (map); | |||||
| result = noErr; | |||||
| break; | |||||
| } | |||||
| case kAudioUnitProperty_AllParameterMIDIMappings:{ | |||||
| ca_require(inScope == kAudioUnitScope_Global, InvalidScope); | |||||
| ca_require(inElement == 0, InvalidElement); | |||||
| AUParameterMIDIMapping * mappings = (AUParameterMIDIMapping*)inData; | |||||
| mMapManager->ReplaceAllMaps (mappings, (inDataSize / sizeof(AUParameterMIDIMapping)), mAUBaseInstance); | |||||
| result = noErr; | |||||
| break; | |||||
| } | |||||
| #endif | |||||
| default: | |||||
| result = kAudioUnitErr_InvalidProperty; | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| InvalidScope: | |||||
| return kAudioUnitErr_InvalidScope; | |||||
| InvalidElement: | |||||
| return kAudioUnitErr_InvalidElement; | |||||
| #endif | |||||
| } | |||||
| #endif //TARGET_API_MAC_OSX | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| #pragma mark ____MidiDispatch | |||||
| inline const Byte * NextMIDIEvent(const Byte *event, const Byte *end) | |||||
| { | |||||
| Byte c = *event; | |||||
| switch (c >> 4) { | |||||
| default: // data byte -- assume in sysex | |||||
| while ((*++event & 0x80) == 0 && event < end) | |||||
| ; | |||||
| break; | |||||
| case 0x8: | |||||
| case 0x9: | |||||
| case 0xA: | |||||
| case 0xB: | |||||
| case 0xE: | |||||
| event += 3; | |||||
| break; | |||||
| case 0xC: | |||||
| case 0xD: | |||||
| event += 2; | |||||
| break; | |||||
| case 0xF: | |||||
| switch (c) { | |||||
| case 0xF0: | |||||
| while ((*++event & 0x80) == 0 && event < end) | |||||
| ; | |||||
| break; | |||||
| case 0xF1: | |||||
| case 0xF3: | |||||
| event += 2; | |||||
| break; | |||||
| case 0xF2: | |||||
| event += 3; | |||||
| break; | |||||
| default: | |||||
| ++event; | |||||
| break; | |||||
| } | |||||
| } | |||||
| return (event >= end) ? end : event; | |||||
| } | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| // AUMIDIBase::HandleMIDIPacketList | |||||
| // | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| OSStatus AUMIDIBase::HandleMIDIPacketList(const MIDIPacketList *pktlist) | |||||
| { | |||||
| if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized; | |||||
| int nPackets = pktlist->numPackets; | |||||
| const MIDIPacket *pkt = pktlist->packet; | |||||
| while (nPackets-- > 0) { | |||||
| const Byte *event = pkt->data, *packetEnd = event + pkt->length; | |||||
| long startFrame = (long)pkt->timeStamp; | |||||
| while (event < packetEnd) { | |||||
| Byte status = event[0]; | |||||
| if (status & 0x80) { | |||||
| // really a status byte (not sysex continuation) | |||||
| HandleMidiEvent(status & 0xF0, status & 0x0F, event[1], event[2], static_cast<UInt32>(startFrame)); | |||||
| // note that we're generating a bogus channel number for system messages (0xF0-FF) | |||||
| } | |||||
| event = NextMIDIEvent(event, packetEnd); | |||||
| } | |||||
| pkt = reinterpret_cast<const MIDIPacket *>(packetEnd); | |||||
| } | |||||
| return noErr; | |||||
| } | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| // AUMIDIBase::HandleMidiEvent | |||||
| // | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| OSStatus AUMIDIBase::HandleMidiEvent(UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame) | |||||
| { | |||||
| if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized; | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| // you potentially have a choice to make here - if a param mapping matches, do you still want to process the | |||||
| // MIDI event or not. The default behaviour is to continue on with the MIDI event. | |||||
| if (mMapManager->HandleHotMapping (status, channel, data1, mAUBaseInstance)) { | |||||
| mAUBaseInstance.PropertyChanged (kAudioUnitProperty_HotMapParameterMIDIMapping, kAudioUnitScope_Global, 0); | |||||
| } | |||||
| else { | |||||
| mMapManager->FindParameterMapEventMatch(status, channel, data1, data2, inStartFrame, mAUBaseInstance); | |||||
| } | |||||
| #endif | |||||
| OSStatus result = noErr; | |||||
| switch(status) | |||||
| { | |||||
| case kMidiMessage_NoteOn: | |||||
| if(data2) | |||||
| { | |||||
| result = HandleNoteOn(channel, data1, data2, inStartFrame); | |||||
| } | |||||
| else | |||||
| { | |||||
| // zero velocity translates to note off | |||||
| result = HandleNoteOff(channel, data1, data2, inStartFrame); | |||||
| } | |||||
| break; | |||||
| case kMidiMessage_NoteOff: | |||||
| result = HandleNoteOff(channel, data1, data2, inStartFrame); | |||||
| break; | |||||
| default: | |||||
| result = HandleNonNoteEvent (status, channel, data1, data2, inStartFrame); | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| OSStatus AUMIDIBase::HandleNonNoteEvent (UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| switch (status) | |||||
| { | |||||
| case kMidiMessage_PitchWheel: | |||||
| result = HandlePitchWheel(channel, data1, data2, inStartFrame); | |||||
| break; | |||||
| case kMidiMessage_ProgramChange: | |||||
| result = HandleProgramChange(channel, data1); | |||||
| break; | |||||
| case kMidiMessage_ChannelPressure: | |||||
| result = HandleChannelPressure(channel, data1, inStartFrame); | |||||
| break; | |||||
| case kMidiMessage_ControlChange: | |||||
| { | |||||
| switch (data1) { | |||||
| case kMidiController_AllNotesOff: | |||||
| result = HandleAllNotesOff(channel); | |||||
| break; | |||||
| case kMidiController_ResetAllControllers: | |||||
| result = HandleResetAllControllers(channel); | |||||
| break; | |||||
| case kMidiController_AllSoundOff: | |||||
| result = HandleAllSoundOff(channel); | |||||
| break; | |||||
| default: | |||||
| result = HandleControlChange(channel, data1, data2, inStartFrame); | |||||
| break; | |||||
| } | |||||
| break; | |||||
| } | |||||
| case kMidiMessage_PolyPressure: | |||||
| result = HandlePolyPressure (channel, data1, data2, inStartFrame); | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| OSStatus AUMIDIBase::SysEx (const UInt8 * inData, | |||||
| UInt32 inLength) | |||||
| { | |||||
| if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized; | |||||
| return HandleSysEx(inData, inLength ); | |||||
| } | |||||
| #if TARGET_OS_MAC | |||||
| #if __LP64__ | |||||
| // comp instance, parameters in forward order | |||||
| #define PARAM(_typ, _name, _index, _nparams) \ | |||||
| _typ _name = *(_typ *)¶ms->params[_index + 1]; | |||||
| #else | |||||
| // parameters in reverse order, then comp instance | |||||
| #define PARAM(_typ, _name, _index, _nparams) \ | |||||
| _typ _name = *(_typ *)¶ms->params[_nparams - 1 - _index]; | |||||
| #endif | |||||
| #elif TARGET_OS_WIN32 | |||||
| // (no comp instance), parameters in forward order | |||||
| #define PARAM(_typ, _name, _index, _nparams) \ | |||||
| _typ _name = *(_typ *)¶ms->params[_index]; | |||||
| #endif | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| OSStatus AUMIDIBase::ComponentEntryDispatch( ComponentParameters * params, | |||||
| AUMIDIBase * This) | |||||
| { | |||||
| if (This == NULL) return kAudio_ParamError; | |||||
| OSStatus result; | |||||
| switch (params->what) { | |||||
| case kMusicDeviceMIDIEventSelect: | |||||
| { | |||||
| PARAM(UInt32, pbinStatus, 0, 4); | |||||
| PARAM(UInt32, pbinData1, 1, 4); | |||||
| PARAM(UInt32, pbinData2, 2, 4); | |||||
| PARAM(UInt32, pbinOffsetSampleFrame, 3, 4); | |||||
| result = This->MIDIEvent(pbinStatus, pbinData1, pbinData2, pbinOffsetSampleFrame); | |||||
| } | |||||
| break; | |||||
| case kMusicDeviceSysExSelect: | |||||
| { | |||||
| PARAM(const UInt8 *, pbinData, 0, 2); | |||||
| PARAM(UInt32, pbinLength, 1, 2); | |||||
| result = This->SysEx(pbinData, pbinLength); | |||||
| } | |||||
| break; | |||||
| default: | |||||
| result = badComponentSelector; | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| #endif | |||||
| @@ -0,0 +1,213 @@ | |||||
| /* | |||||
| File: AUMIDIBase.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUMIDIBase_h__ | |||||
| #define __AUMIDIBase_h__ | |||||
| #include "AUBase.h" | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| #include "CAAUMIDIMapManager.h" | |||||
| #endif | |||||
| struct MIDIPacketList; | |||||
| // ________________________________________________________________________ | |||||
| // MusicDeviceBase | |||||
| // | |||||
| /*! @class AUMIDIBase */ | |||||
| class AUMIDIBase { | |||||
| public: | |||||
| // this is NOT a copy constructor! | |||||
| /*! @ctor AUMIDIBase */ | |||||
| AUMIDIBase(AUBase* inBase); | |||||
| /*! @dtor ~AUMIDIBase */ | |||||
| virtual ~AUMIDIBase(); | |||||
| /*! @method MIDIEvent */ | |||||
| virtual OSStatus MIDIEvent( UInt32 inStatus, | |||||
| UInt32 inData1, | |||||
| UInt32 inData2, | |||||
| UInt32 inOffsetSampleFrame) | |||||
| { | |||||
| UInt32 strippedStatus = inStatus & 0xf0; | |||||
| UInt32 channel = inStatus & 0x0f; | |||||
| return HandleMidiEvent(strippedStatus, channel, inData1, inData2, inOffsetSampleFrame); | |||||
| } | |||||
| /*! @method HandleMIDIPacketList */ | |||||
| OSStatus HandleMIDIPacketList(const MIDIPacketList *pktlist); | |||||
| /*! @method SysEx */ | |||||
| virtual OSStatus SysEx( const UInt8 * inData, | |||||
| UInt32 inLength); | |||||
| #if TARGET_API_MAC_OSX | |||||
| /*! @method DelegateGetPropertyInfo */ | |||||
| virtual OSStatus DelegateGetPropertyInfo(AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 & outDataSize, | |||||
| Boolean & outWritable); | |||||
| /*! @method DelegateGetProperty */ | |||||
| virtual OSStatus DelegateGetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| void * outData); | |||||
| /*! @method DelegateSetProperty */ | |||||
| virtual OSStatus DelegateSetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const void * inData, | |||||
| UInt32 inDataSize); | |||||
| #endif | |||||
| protected: | |||||
| // MIDI dispatch | |||||
| /*! @method HandleMidiEvent */ | |||||
| virtual OSStatus HandleMidiEvent( UInt8 inStatus, | |||||
| UInt8 inChannel, | |||||
| UInt8 inData1, | |||||
| UInt8 inData2, | |||||
| UInt32 inStartFrame); | |||||
| /*! @method HandleNonNoteEvent */ | |||||
| virtual OSStatus HandleNonNoteEvent ( UInt8 status, | |||||
| UInt8 channel, | |||||
| UInt8 data1, | |||||
| UInt8 data2, | |||||
| UInt32 inStartFrame); | |||||
| #if TARGET_API_MAC_OSX | |||||
| /*! @method GetXMLNames */ | |||||
| virtual OSStatus GetXMLNames(CFURLRef *outNameDocument) | |||||
| { return kAudioUnitErr_InvalidProperty; } // if not overridden, it's unsupported | |||||
| #endif | |||||
| // channel messages | |||||
| /*! @method HandleNoteOn */ | |||||
| virtual OSStatus HandleNoteOn( UInt8 inChannel, | |||||
| UInt8 inNoteNumber, | |||||
| UInt8 inVelocity, | |||||
| UInt32 inStartFrame) { return noErr; } | |||||
| /*! @method HandleNoteOff */ | |||||
| virtual OSStatus HandleNoteOff( UInt8 inChannel, | |||||
| UInt8 inNoteNumber, | |||||
| UInt8 inVelocity, | |||||
| UInt32 inStartFrame) { return noErr; } | |||||
| /*! @method HandleControlChange */ | |||||
| virtual OSStatus HandleControlChange( UInt8 inChannel, | |||||
| UInt8 inController, | |||||
| UInt8 inValue, | |||||
| UInt32 inStartFrame) { return noErr; } | |||||
| /*! @method HandlePitchWheel */ | |||||
| virtual OSStatus HandlePitchWheel( UInt8 inChannel, | |||||
| UInt8 inPitch1, | |||||
| UInt8 inPitch2, | |||||
| UInt32 inStartFrame) { return noErr; } | |||||
| /*! @method HandleChannelPressure */ | |||||
| virtual OSStatus HandleChannelPressure( UInt8 inChannel, | |||||
| UInt8 inValue, | |||||
| UInt32 inStartFrame) { return noErr; } | |||||
| /*! @method HandleProgramChange */ | |||||
| virtual OSStatus HandleProgramChange( UInt8 inChannel, | |||||
| UInt8 inValue) { return noErr; } | |||||
| /*! @method HandlePolyPressure */ | |||||
| virtual OSStatus HandlePolyPressure( UInt8 inChannel, | |||||
| UInt8 inKey, | |||||
| UInt8 inValue, | |||||
| UInt32 inStartFrame) { return noErr; } | |||||
| /*! @method HandleResetAllControllers */ | |||||
| virtual OSStatus HandleResetAllControllers(UInt8 inChannel) { return noErr; } | |||||
| /*! @method HandleAllNotesOff */ | |||||
| virtual OSStatus HandleAllNotesOff( UInt8 inChannel) { return noErr; } | |||||
| /*! @method HandleAllSoundOff */ | |||||
| virtual OSStatus HandleAllSoundOff( UInt8 inChannel) { return noErr; } | |||||
| //System messages | |||||
| /*! @method HandleSysEx */ | |||||
| virtual OSStatus HandleSysEx( const UInt8 * inData, | |||||
| UInt32 inLength ) { return noErr; } | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| /* map manager */ | |||||
| CAAUMIDIMapManager *GetMIDIMapManager() {return mMapManager;}; | |||||
| #endif | |||||
| private: | |||||
| /*! @var mAUBaseInstance */ | |||||
| AUBase & mAUBaseInstance; | |||||
| #if CA_AUTO_MIDI_MAP | |||||
| /* map manager */ | |||||
| CAAUMIDIMapManager * mMapManager; | |||||
| #endif | |||||
| public: | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| // component dispatcher | |||||
| /*! @method ComponentEntryDispatch */ | |||||
| static OSStatus ComponentEntryDispatch( ComponentParameters *params, | |||||
| AUMIDIBase *This); | |||||
| #endif | |||||
| }; | |||||
| #endif // __AUMIDIBase_h__ | |||||
| @@ -0,0 +1,164 @@ | |||||
| /* | |||||
| File: AUMIDIEffectBase.cpp | |||||
| Abstract: AUMIDIEffectBase.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUMIDIEffectBase.h" | |||||
| // compatibility with older OS SDK releases | |||||
| typedef OSStatus | |||||
| (*TEMP_MusicDeviceMIDIEventProc)( void * inComponentStorage, | |||||
| UInt32 inStatus, | |||||
| UInt32 inData1, | |||||
| UInt32 inData2, | |||||
| UInt32 inOffsetSampleFrame); | |||||
| static OSStatus AUMIDIEffectBaseMIDIEvent(void * inComponentStorage, | |||||
| UInt32 inStatus, | |||||
| UInt32 inData1, | |||||
| UInt32 inData2, | |||||
| UInt32 inOffsetSampleFrame); | |||||
| AUMIDIEffectBase::AUMIDIEffectBase( AudioComponentInstance inInstance, | |||||
| bool inProcessesInPlace ) | |||||
| : AUEffectBase(inInstance, inProcessesInPlace), | |||||
| AUMIDIBase(this) | |||||
| { | |||||
| } | |||||
| OSStatus AUMIDIEffectBase::GetPropertyInfo(AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 & outDataSize, | |||||
| Boolean & outWritable) | |||||
| { | |||||
| OSStatus result; | |||||
| result = AUEffectBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable); | |||||
| if (result == kAudioUnitErr_InvalidProperty) | |||||
| result = AUMIDIBase::DelegateGetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable); | |||||
| return result; | |||||
| } | |||||
| OSStatus AUMIDIEffectBase::GetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| void * outData) | |||||
| { | |||||
| OSStatus result; | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| if (inID == kAudioUnitProperty_FastDispatch) { | |||||
| if (inElement == kMusicDeviceMIDIEventSelect) { | |||||
| *(TEMP_MusicDeviceMIDIEventProc *)outData = AUMIDIEffectBaseMIDIEvent; | |||||
| return noErr; | |||||
| } | |||||
| return kAudioUnitErr_InvalidElement; | |||||
| } | |||||
| #endif | |||||
| result = AUEffectBase::GetProperty (inID, inScope, inElement, outData); | |||||
| if (result == kAudioUnitErr_InvalidProperty) | |||||
| result = AUMIDIBase::DelegateGetProperty (inID, inScope, inElement, outData); | |||||
| return result; | |||||
| } | |||||
| OSStatus AUMIDIEffectBase::SetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const void * inData, | |||||
| UInt32 inDataSize) | |||||
| { | |||||
| OSStatus result = AUEffectBase::SetProperty (inID, inScope, inElement, inData, inDataSize); | |||||
| if (result == kAudioUnitErr_InvalidProperty) | |||||
| result = AUMIDIBase::DelegateSetProperty (inID, inScope, inElement, inData, inDataSize); | |||||
| return result; | |||||
| } | |||||
| #if !TARGET_OS_IPHONE | |||||
| OSStatus AUMIDIEffectBase::ComponentEntryDispatch(ComponentParameters * params, | |||||
| AUMIDIEffectBase * This) | |||||
| { | |||||
| if (This == NULL) return paramErr; | |||||
| OSStatus result; | |||||
| switch (params->what) { | |||||
| case kMusicDeviceMIDIEventSelect: | |||||
| case kMusicDeviceSysExSelect: | |||||
| result = AUMIDIBase::ComponentEntryDispatch (params, This); | |||||
| break; | |||||
| default: | |||||
| result = AUEffectBase::ComponentEntryDispatch(params, This); | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| #endif | |||||
| // fast dispatch | |||||
| static OSStatus AUMIDIEffectBaseMIDIEvent(void * inComponentStorage, | |||||
| UInt32 inStatus, | |||||
| UInt32 inData1, | |||||
| UInt32 inData2, | |||||
| UInt32 inOffsetSampleFrame) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUMIDIEffectBase *This = static_cast<AUMIDIEffectBase *>(inComponentStorage); | |||||
| if (This == NULL) return paramErr; | |||||
| result = This->AUMIDIBase::MIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| @@ -0,0 +1,104 @@ | |||||
| /* | |||||
| File: AUMIDIEffectBase.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUMIDIEffectBase_h__ | |||||
| #define __AUMIDIEffectBase_h__ | |||||
| #include "AUMIDIBase.h" | |||||
| #include "AUEffectBase.h" | |||||
| // ________________________________________________________________________ | |||||
| // AUMIDIEffectBase | |||||
| // | |||||
| /*! @class AUMIDIEffectBase */ | |||||
| class AUMIDIEffectBase : public AUEffectBase, public AUMIDIBase { | |||||
| public: | |||||
| /*! @ctor AUMIDIEffectBase */ | |||||
| AUMIDIEffectBase( AudioComponentInstance inInstance, | |||||
| bool inProcessesInPlace = false ); | |||||
| /*! @method MIDIEvent */ | |||||
| virtual OSStatus MIDIEvent(UInt32 inStatus, | |||||
| UInt32 inData1, | |||||
| UInt32 inData2, | |||||
| UInt32 inOffsetSampleFrame) | |||||
| { | |||||
| return AUMIDIBase::MIDIEvent (inStatus, inData1, inData2, inOffsetSampleFrame); | |||||
| } | |||||
| /*! @method SysEx */ | |||||
| virtual OSStatus SysEx(const UInt8 * inData, | |||||
| UInt32 inLength) | |||||
| { | |||||
| return AUMIDIBase::SysEx (inData, inLength); | |||||
| } | |||||
| /*! @method GetPropertyInfo */ | |||||
| virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 & outDataSize, | |||||
| Boolean & outWritable); | |||||
| /*! @method GetProperty */ | |||||
| virtual OSStatus GetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| void * outData); | |||||
| /*! @method SetProperty */ | |||||
| virtual OSStatus SetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const void * inData, | |||||
| UInt32 inDataSize); | |||||
| #if !TARGET_OS_IPHONE | |||||
| // component dispatcher | |||||
| /*! @method ComponentEntryDispatch */ | |||||
| static OSStatus ComponentEntryDispatch( ComponentParameters * params, | |||||
| AUMIDIEffectBase * This); | |||||
| #endif | |||||
| }; | |||||
| #endif // __AUMIDIEffectBase_h__ | |||||
| @@ -0,0 +1,76 @@ | |||||
| /* | |||||
| File: AUOutputBase.cpp | |||||
| Abstract: AUOutputBase.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| #include "AUOutputBase.h" | |||||
| OSStatus AUOutputBase::ComponentEntryDispatch(ComponentParameters *params, AUOutputBase *This) | |||||
| { | |||||
| if (This == NULL) return paramErr; | |||||
| OSStatus result; | |||||
| switch (params->what) { | |||||
| case kAudioOutputUnitStartSelect: | |||||
| { | |||||
| result = This->Start(); | |||||
| } | |||||
| break; | |||||
| case kAudioOutputUnitStopSelect: | |||||
| { | |||||
| result = This->Stop(); | |||||
| } | |||||
| break; | |||||
| default: | |||||
| result = badComponentSelector; | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| #endif | |||||
| @@ -0,0 +1,82 @@ | |||||
| /* | |||||
| File: AUOutputBase.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUOutputBase_h__ | |||||
| #define __AUOutputBase_h__ | |||||
| #include "AUBase.h" | |||||
| // ________________________________________________________________________ | |||||
| // AUOutputBase | |||||
| // this is now a mix-in rather than an AUBase subclass | |||||
| /*! @class AUOutputBase */ | |||||
| class AUOutputBase { | |||||
| public: | |||||
| /*! @ctor AUOutputBase */ | |||||
| AUOutputBase(AUBase *inBase) : mAUBaseInstance(*inBase) { } | |||||
| virtual ~AUOutputBase() { } | |||||
| // additional component entry points | |||||
| /*! @method Start */ | |||||
| virtual OSStatus Start() = 0; | |||||
| /*! @method Stop */ | |||||
| virtual OSStatus Stop() = 0; | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| // component dispatcher | |||||
| /*! @method ComponentEntryDispatch */ | |||||
| static OSStatus ComponentEntryDispatch( ComponentParameters * params, | |||||
| AUOutputBase * This); | |||||
| #endif | |||||
| private: | |||||
| /*! @var mAUBaseInstance */ | |||||
| AUBase & mAUBaseInstance; | |||||
| }; | |||||
| #endif // __AUOutputBase_h__ | |||||
| @@ -0,0 +1,62 @@ | |||||
| /* | |||||
| File: AUOutputElement.cpp | |||||
| Abstract: AUOutputElement.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUOutputElement.h" | |||||
| #include "AUBase.h" | |||||
| AUOutputElement::AUOutputElement(AUBase *audioUnit) : | |||||
| AUIOElement(audioUnit) | |||||
| { | |||||
| AllocateBuffer(); | |||||
| } | |||||
| OSStatus AUOutputElement::SetStreamFormat(const CAStreamBasicDescription &desc) | |||||
| { | |||||
| OSStatus result = AUIOElement::SetStreamFormat(desc); // inherited | |||||
| if (result == AUBase::noErr) | |||||
| AllocateBuffer(); | |||||
| return result; | |||||
| } | |||||
| @@ -0,0 +1,66 @@ | |||||
| /* | |||||
| File: AUOutputElement.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUOutput_h__ | |||||
| #define __AUOutput_h__ | |||||
| #include "AUScopeElement.h" | |||||
| #include "AUBuffer.h" | |||||
| /*! @class AUOutputElement */ | |||||
| class AUOutputElement : public AUIOElement { | |||||
| public: | |||||
| /*! @ctor AUOutputElement */ | |||||
| AUOutputElement(AUBase *audioUnit); | |||||
| // AUElement override | |||||
| /*! @method SetStreamFormat */ | |||||
| virtual OSStatus SetStreamFormat(const CAStreamBasicDescription &desc); | |||||
| /*! @method NeedsBufferSpace */ | |||||
| virtual bool NeedsBufferSpace() const { return true; } | |||||
| }; | |||||
| #endif // __AUOutput_h__ | |||||
| @@ -0,0 +1,668 @@ | |||||
| /* | |||||
| File: AUPlugInDispatch.cpp | |||||
| Abstract: AUPlugInDispatch.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUPlugInDispatch.h" | |||||
| #include "CAXException.h" | |||||
| #include "ComponentBase.h" | |||||
| #include "AUBase.h" | |||||
| #define ACPI ((AudioComponentPlugInInstance *)self) | |||||
| #define AUI ((AUBase *)&ACPI->mInstanceStorage) | |||||
| #define AUI_LOCK CAMutex::Locker auLock(AUI->GetMutex()); | |||||
| // ------------------------------------------------------------------------------------------------ | |||||
| static OSStatus AUMethodInitialize(void *self) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = AUI->DoInitialize(); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodUninitialize(void *self) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| AUI->DoCleanup(); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodGetPropertyInfo(void *self, AudioUnitPropertyID prop, AudioUnitScope scope, AudioUnitElement elem, UInt32 *outDataSize, Boolean *outWritable) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| UInt32 dataSize = 0; // 13517289 GetPropetyInfo was returning an uninitialized value when there is an error. This is a problem for auval. | |||||
| Boolean writable = false; | |||||
| AUI_LOCK | |||||
| result = AUI->DispatchGetPropertyInfo(prop, scope, elem, dataSize, writable); | |||||
| if (outDataSize != NULL) | |||||
| *outDataSize = dataSize; | |||||
| if (outWritable != NULL) | |||||
| *outWritable = writable; | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodGetProperty(void *self, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void *outData, UInt32 *ioDataSize) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| UInt32 actualPropertySize, clientBufferSize; | |||||
| Boolean writable; | |||||
| char *tempBuffer; | |||||
| void *destBuffer; | |||||
| AUI_LOCK | |||||
| if (ioDataSize == NULL) { | |||||
| ca_debug_string("AudioUnitGetProperty: null size pointer"); | |||||
| result = kAudio_ParamError; | |||||
| goto finishGetProperty; | |||||
| } | |||||
| if (outData == NULL) { | |||||
| UInt32 dataSize; | |||||
| result = AUI->DispatchGetPropertyInfo(inID, inScope, inElement, dataSize, writable); | |||||
| *ioDataSize = dataSize; | |||||
| goto finishGetProperty; | |||||
| } | |||||
| clientBufferSize = *ioDataSize; | |||||
| if (clientBufferSize == 0) | |||||
| { | |||||
| ca_debug_string("AudioUnitGetProperty: *ioDataSize == 0 on entry"); | |||||
| // $$$ or should we allow this as a shortcut for finding the size? | |||||
| result = kAudio_ParamError; | |||||
| goto finishGetProperty; | |||||
| } | |||||
| result = AUI->DispatchGetPropertyInfo(inID, inScope, inElement, actualPropertySize, writable); | |||||
| if (result != noErr) | |||||
| goto finishGetProperty; | |||||
| if (clientBufferSize < actualPropertySize) | |||||
| { | |||||
| tempBuffer = new char[actualPropertySize]; | |||||
| destBuffer = tempBuffer; | |||||
| } else { | |||||
| tempBuffer = NULL; | |||||
| destBuffer = outData; | |||||
| } | |||||
| result = AUI->DispatchGetProperty(inID, inScope, inElement, destBuffer); | |||||
| if (result == noErr) { | |||||
| if (clientBufferSize < actualPropertySize && tempBuffer != NULL) | |||||
| { | |||||
| memcpy(outData, tempBuffer, clientBufferSize); | |||||
| delete[] tempBuffer; | |||||
| // ioDataSize remains correct, the number of bytes we wrote | |||||
| } else | |||||
| *ioDataSize = actualPropertySize; | |||||
| } else | |||||
| *ioDataSize = 0; | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| finishGetProperty: | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodSetProperty(void *self, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void *inData, UInt32 inDataSize) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| if (inData && inDataSize) | |||||
| result = AUI->DispatchSetProperty(inID, inScope, inElement, inData, inDataSize); | |||||
| else { | |||||
| if (inData == NULL && inDataSize == 0) { | |||||
| result = AUI->DispatchRemovePropertyValue(inID, inScope, inElement); | |||||
| } else { | |||||
| if (inData == NULL) { | |||||
| ca_debug_string("AudioUnitSetProperty: inData == NULL"); | |||||
| result = kAudio_ParamError; | |||||
| goto finishSetProperty; | |||||
| } | |||||
| if (inDataSize == 0) { | |||||
| ca_debug_string("AudioUnitSetProperty: inDataSize == 0"); | |||||
| result = kAudio_ParamError; | |||||
| goto finishSetProperty; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| finishSetProperty: | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodAddPropertyListener(void *self, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc, void *userData) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = AUI->AddPropertyListener(prop, proc, userData); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodRemovePropertyListener(void *self, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = AUI->RemovePropertyListener(prop, proc, NULL, false); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodRemovePropertyListenerWithUserData(void *self, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc, void *userData) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = AUI->RemovePropertyListener(prop, proc, userData, true); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodAddRenderNotify(void *self, AURenderCallback proc, void *userData) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = AUI->SetRenderNotification(proc, userData); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodRemoveRenderNotify(void *self, AURenderCallback proc, void *userData) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = AUI->RemoveRenderNotification(proc, userData); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodGetParameter(void *self, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue *value) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = (value == NULL ? kAudio_ParamError : AUI->GetParameter(param, scope, elem, *value)); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodSetParameter(void *self, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue value, UInt32 bufferOffset) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| // this is a (potentially) realtime method; no lock | |||||
| result = AUI->SetParameter(param, scope, elem, value, bufferOffset); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodScheduleParameters(void *self, const AudioUnitParameterEvent *events, UInt32 numEvents) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| // this is a (potentially) realtime method; no lock | |||||
| result = AUI->ScheduleParameter(events, numEvents); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodRender(void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| #if !TARGET_OS_IPHONE | |||||
| try { | |||||
| #endif | |||||
| // this is a processing method; no lock | |||||
| AudioUnitRenderActionFlags tempFlags; | |||||
| if (inTimeStamp == NULL || ioData == NULL) | |||||
| result = kAudio_ParamError; | |||||
| else { | |||||
| if (ioActionFlags == NULL) { | |||||
| tempFlags = 0; | |||||
| ioActionFlags = &tempFlags; | |||||
| } | |||||
| result = AUI->DoRender(*ioActionFlags, *inTimeStamp, inOutputBusNumber, inNumberFrames, *ioData); | |||||
| } | |||||
| #if !TARGET_OS_IPHONE | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| #endif | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodComplexRender(void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberOfPackets, UInt32 *outNumberOfPackets, AudioStreamPacketDescription *outPacketDescriptions, AudioBufferList *ioData, void *outMetadata, UInt32 *outMetadataByteSize) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| #if !TARGET_OS_IPHONE | |||||
| try { | |||||
| #endif | |||||
| // this is a processing method; no lock | |||||
| AudioUnitRenderActionFlags tempFlags; | |||||
| if (inTimeStamp == NULL || ioData == NULL) | |||||
| result = kAudio_ParamError; | |||||
| else { | |||||
| if (ioActionFlags == NULL) { | |||||
| tempFlags = 0; | |||||
| ioActionFlags = &tempFlags; | |||||
| } | |||||
| result = AUI->ComplexRender(*ioActionFlags, *inTimeStamp, inOutputBusNumber, inNumberOfPackets, outNumberOfPackets, outPacketDescriptions, *ioData, outMetadata, outMetadataByteSize); | |||||
| } | |||||
| #if !TARGET_OS_IPHONE | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| #endif | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodReset(void *self, AudioUnitScope scope, AudioUnitElement elem) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = AUI->Reset(scope, elem); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodProcess (void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| #if !TARGET_OS_IPHONE | |||||
| try { | |||||
| #endif | |||||
| // this is a processing method; no lock | |||||
| bool doParamCheck = true; | |||||
| AudioUnitRenderActionFlags tempFlags; | |||||
| if (ioActionFlags == NULL) { | |||||
| tempFlags = 0; | |||||
| ioActionFlags = &tempFlags; | |||||
| } else { | |||||
| if (*ioActionFlags & (1 << 9)/*kAudioUnitRenderAction_DoNotCheckRenderArgs*/) | |||||
| doParamCheck = false; | |||||
| } | |||||
| if (doParamCheck && (inTimeStamp == NULL || ioData == NULL)) | |||||
| result = kAudio_ParamError; | |||||
| else { | |||||
| result = AUI->DoProcess(*ioActionFlags, *inTimeStamp, inNumberFrames, *ioData); | |||||
| } | |||||
| #if !TARGET_OS_IPHONE | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| #endif | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodProcessMultiple (void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, UInt32 inNumberInputBufferLists, const AudioBufferList **inInputBufferLists, UInt32 inNumberOutputBufferLists, AudioBufferList **ioOutputBufferLists) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| #if !TARGET_OS_IPHONE | |||||
| try { | |||||
| #endif | |||||
| // this is a processing method; no lock | |||||
| bool doParamCheck = true; | |||||
| AudioUnitRenderActionFlags tempFlags; | |||||
| if (ioActionFlags == NULL) { | |||||
| tempFlags = 0; | |||||
| ioActionFlags = &tempFlags; | |||||
| } else { | |||||
| if (*ioActionFlags & (1 << 9)/*kAudioUnitRenderAction_DoNotCheckRenderArgs*/) | |||||
| doParamCheck = false; | |||||
| } | |||||
| if (doParamCheck && (inTimeStamp == NULL || inInputBufferLists == NULL || ioOutputBufferLists == NULL)) | |||||
| result = kAudio_ParamError; | |||||
| else { | |||||
| result = AUI->DoProcessMultiple(*ioActionFlags, *inTimeStamp, inNumberFrames, inNumberInputBufferLists, inInputBufferLists, inNumberOutputBufferLists, ioOutputBufferLists); | |||||
| } | |||||
| #if !TARGET_OS_IPHONE | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| #endif | |||||
| return result; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------ | |||||
| static OSStatus AUMethodStart(void *self) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = AUI->Start(); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodStop(void *self) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| AUI_LOCK | |||||
| result = AUI->Stop(); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------ | |||||
| #if !CA_BASIC_AU_FEATURES | |||||
| // I don't know what I'm doing here; conflicts with the multiple inheritence in MusicDeviceBase. | |||||
| static OSStatus AUMethodMIDIEvent(void *self, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| // this is a potential render-time method; no lock | |||||
| result = AUI->MIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodSysEx(void *self, const UInt8 *inData, UInt32 inLength) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| // this is a potential render-time method; no lock | |||||
| result = AUI->SysEx(inData, inLength); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodStartNote(void *self, MusicDeviceInstrumentID inInstrument, MusicDeviceGroupID inGroupID, NoteInstanceID *outNoteInstanceID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams *inParams) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| // this is a potential render-time method; no lock | |||||
| if (inParams == NULL || outNoteInstanceID == NULL) | |||||
| result = kAudio_ParamError; | |||||
| else | |||||
| result = AUI->StartNote(inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodStopNote(void *self, MusicDeviceGroupID inGroupID, NoteInstanceID inNoteInstanceID, UInt32 inOffsetSampleFrame) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| // this is a potential render-time method; no lock | |||||
| result = AUI->StopNote(inGroupID, inNoteInstanceID, inOffsetSampleFrame); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| #if !TARGET_OS_IPHONE | |||||
| static OSStatus AUMethodPrepareInstrument (void *self, MusicDeviceInstrumentID inInstrument) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| // this is a potential render-time method; no lock | |||||
| result = AUI->PrepareInstrument(inInstrument); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| static OSStatus AUMethodReleaseInstrument (void *self, MusicDeviceInstrumentID inInstrument) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| // this is a potential render-time method; no lock | |||||
| result = AUI->ReleaseInstrument(inInstrument); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| #endif // TARGET_OS_IPHONE | |||||
| #endif // CA_BASIC_AU_FEATURES | |||||
| //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |||||
| #pragma mark - | |||||
| #pragma mark Lookup Methods | |||||
| AudioComponentMethod AUBaseLookup::Lookup (SInt16 selector) | |||||
| { | |||||
| switch (selector) { | |||||
| case kAudioUnitInitializeSelect: return (AudioComponentMethod)AUMethodInitialize; | |||||
| case kAudioUnitUninitializeSelect: return (AudioComponentMethod)AUMethodUninitialize; | |||||
| case kAudioUnitGetPropertyInfoSelect: return (AudioComponentMethod)AUMethodGetPropertyInfo; | |||||
| case kAudioUnitGetPropertySelect: return (AudioComponentMethod)AUMethodGetProperty; | |||||
| case kAudioUnitSetPropertySelect: return (AudioComponentMethod)AUMethodSetProperty; | |||||
| case kAudioUnitAddPropertyListenerSelect:return (AudioComponentMethod)AUMethodAddPropertyListener; | |||||
| case kAudioUnitRemovePropertyListenerSelect: | |||||
| return (AudioComponentMethod)AUMethodRemovePropertyListener; | |||||
| case kAudioUnitRemovePropertyListenerWithUserDataSelect: | |||||
| return (AudioComponentMethod)AUMethodRemovePropertyListenerWithUserData; | |||||
| case kAudioUnitAddRenderNotifySelect: return (AudioComponentMethod)AUMethodAddRenderNotify; | |||||
| case kAudioUnitRemoveRenderNotifySelect:return (AudioComponentMethod)AUMethodRemoveRenderNotify; | |||||
| case kAudioUnitGetParameterSelect: return (AudioComponentMethod)AUMethodGetParameter; | |||||
| case kAudioUnitSetParameterSelect: return (AudioComponentMethod)AUMethodSetParameter; | |||||
| case kAudioUnitScheduleParametersSelect:return (AudioComponentMethod)AUMethodScheduleParameters; | |||||
| case kAudioUnitRenderSelect: return (AudioComponentMethod)AUMethodRender; | |||||
| case kAudioUnitResetSelect: return (AudioComponentMethod)AUMethodReset; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| AudioComponentMethod AUOutputLookup::Lookup (SInt16 selector) | |||||
| { | |||||
| AudioComponentMethod method = AUBaseLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| switch (selector) { | |||||
| case kAudioOutputUnitStartSelect: return (AudioComponentMethod)AUMethodStart; | |||||
| case kAudioOutputUnitStopSelect: return (AudioComponentMethod)AUMethodStop; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| AudioComponentMethod AUComplexOutputLookup::Lookup (SInt16 selector) | |||||
| { | |||||
| AudioComponentMethod method = AUBaseLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| method = AUOutputLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| if (selector == kAudioUnitComplexRenderSelect) | |||||
| return (AudioComponentMethod)AUMethodComplexRender; | |||||
| return NULL; | |||||
| } | |||||
| AudioComponentMethod AUBaseProcessLookup::Lookup (SInt16 selector) | |||||
| { | |||||
| AudioComponentMethod method = AUBaseLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| if (selector == kAudioUnitProcessSelect) | |||||
| return (AudioComponentMethod)AUMethodProcess; | |||||
| return NULL; | |||||
| } | |||||
| AudioComponentMethod AUBaseProcessMultipleLookup::Lookup (SInt16 selector) | |||||
| { | |||||
| AudioComponentMethod method = AUBaseLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| if (selector == kAudioUnitProcessMultipleSelect) | |||||
| return (AudioComponentMethod)AUMethodProcessMultiple; | |||||
| return NULL; | |||||
| } | |||||
| AudioComponentMethod AUBaseProcessAndMultipleLookup::Lookup (SInt16 selector) | |||||
| { | |||||
| AudioComponentMethod method = AUBaseLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| method = AUBaseProcessMultipleLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| method = AUBaseProcessLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| return NULL; | |||||
| } | |||||
| #if !CA_BASIC_AU_FEATURES | |||||
| inline AudioComponentMethod MIDI_Lookup (SInt16 selector) | |||||
| { | |||||
| switch (selector) { | |||||
| case kMusicDeviceMIDIEventSelect: return (AudioComponentMethod)AUMethodMIDIEvent; | |||||
| case kMusicDeviceSysExSelect: return (AudioComponentMethod)AUMethodSysEx; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| AudioComponentMethod AUMIDILookup::Lookup (SInt16 selector) | |||||
| { | |||||
| AudioComponentMethod method = AUBaseLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| return MIDI_Lookup(selector); | |||||
| } | |||||
| AudioComponentMethod AUMIDIProcessLookup::Lookup (SInt16 selector) | |||||
| { | |||||
| AudioComponentMethod method = AUBaseProcessLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| return MIDI_Lookup(selector); | |||||
| } | |||||
| AudioComponentMethod AUMusicLookup::Lookup (SInt16 selector) | |||||
| { | |||||
| AudioComponentMethod method = AUBaseLookup::Lookup(selector); | |||||
| if (method) return method; | |||||
| switch (selector) { | |||||
| case kMusicDeviceStartNoteSelect: return (AudioComponentMethod)AUMethodStartNote; | |||||
| case kMusicDeviceStopNoteSelect: return (AudioComponentMethod)AUMethodStopNote; | |||||
| #if !TARGET_OS_IPHONE | |||||
| case kMusicDevicePrepareInstrumentSelect: return (AudioComponentMethod)AUMethodPrepareInstrument; | |||||
| case kMusicDeviceReleaseInstrumentSelect: return (AudioComponentMethod)AUMethodReleaseInstrument; | |||||
| #endif | |||||
| default: | |||||
| break; | |||||
| } | |||||
| return MIDI_Lookup (selector); | |||||
| } | |||||
| AudioComponentMethod AUAuxBaseLookup::Lookup (SInt16 selector) | |||||
| { | |||||
| switch (selector) { | |||||
| case kAudioUnitGetPropertyInfoSelect: return (AudioComponentMethod)AUMethodGetPropertyInfo; | |||||
| case kAudioUnitGetPropertySelect: return (AudioComponentMethod)AUMethodGetProperty; | |||||
| case kAudioUnitSetPropertySelect: return (AudioComponentMethod)AUMethodSetProperty; | |||||
| case kAudioUnitGetParameterSelect: return (AudioComponentMethod)AUMethodGetParameter; | |||||
| case kAudioUnitSetParameterSelect: return (AudioComponentMethod)AUMethodSetParameter; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| #endif | |||||
| @@ -0,0 +1,144 @@ | |||||
| /* | |||||
| File: AUPlugInDispatch.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUPlugInBase_h__ | |||||
| #define __AUPlugInBase_h__ | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <AudioUnit/AudioComponent.h> | |||||
| #if !CA_BASIC_AU_FEATURES | |||||
| #include <AudioUnit/MusicDevice.h> | |||||
| #endif | |||||
| #else | |||||
| #include "AudioComponent.h" | |||||
| #include "MusicDevice.h" | |||||
| #endif | |||||
| #include "ComponentBase.h" | |||||
| struct AUBaseLookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUBaseFactory : public APFactory<AUBaseLookup, Implementor> | |||||
| { | |||||
| }; | |||||
| struct AUOutputLookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUOutputBaseFactory : public APFactory<AUOutputLookup, Implementor> | |||||
| { | |||||
| }; | |||||
| struct AUComplexOutputLookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUOutputComplexBaseFactory : public APFactory<AUComplexOutputLookup, Implementor> | |||||
| { | |||||
| }; | |||||
| struct AUBaseProcessLookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUBaseProcessFactory : public APFactory<AUBaseProcessLookup, Implementor> | |||||
| { | |||||
| }; | |||||
| struct AUBaseProcessMultipleLookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUBaseProcessMultipleFactory : public APFactory<AUBaseProcessMultipleLookup, Implementor> | |||||
| { | |||||
| }; | |||||
| struct AUBaseProcessAndMultipleLookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUBaseProcessAndMultipleFactory : public APFactory<AUBaseProcessAndMultipleLookup, Implementor> | |||||
| { | |||||
| }; | |||||
| #if !CA_BASIC_AU_FEATURES | |||||
| struct AUMIDILookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUMIDIEffectFactory : public APFactory<AUMIDILookup, Implementor> | |||||
| { | |||||
| }; | |||||
| struct AUMIDIProcessLookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUMIDIProcessFactory : public APFactory<AUMIDIProcessLookup, Implementor> | |||||
| { | |||||
| }; | |||||
| struct AUMusicLookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUMusicDeviceFactory : public APFactory<AUMusicLookup, Implementor> | |||||
| { | |||||
| }; | |||||
| struct AUAuxBaseLookup { | |||||
| static AudioComponentMethod Lookup (SInt16 selector); | |||||
| }; | |||||
| template <class Implementor> | |||||
| class AUAuxBaseFactory : public APFactory<AUAuxBaseLookup, Implementor> | |||||
| { | |||||
| }; | |||||
| #endif // CA_BASIC_AU_FEATURES | |||||
| #endif // __AUPlugInBase_h__ | |||||
| @@ -0,0 +1,565 @@ | |||||
| /* | |||||
| File: AUScopeElement.cpp | |||||
| Abstract: AUScopeElement.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "AUScopeElement.h" | |||||
| #include "AUBase.h" | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| // By default, parameterIDs may be arbitrarily spaced, and an STL map | |||||
| // will be used for access. Calling UseIndexedParameters() will | |||||
| // instead use an STL vector for faster indexed access. | |||||
| // This assumes the paramIDs are numbered 0.....inNumberOfParameters-1 | |||||
| // Call this before defining/adding any parameters with SetParameter() | |||||
| // | |||||
| void AUElement::UseIndexedParameters(int inNumberOfParameters) | |||||
| { | |||||
| mIndexedParameters.resize (inNumberOfParameters); | |||||
| mUseIndexedParameters = true; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| // Helper method. | |||||
| // returns the ParameterMapEvent object associated with the paramID | |||||
| // | |||||
| inline ParameterMapEvent& AUElement::GetParamEvent(AudioUnitParameterID paramID) | |||||
| { | |||||
| ParameterMapEvent *event; | |||||
| if(mUseIndexedParameters) | |||||
| { | |||||
| if(paramID >= mIndexedParameters.size() ) | |||||
| COMPONENT_THROW(kAudioUnitErr_InvalidParameter); | |||||
| event = &mIndexedParameters[paramID]; | |||||
| } | |||||
| else | |||||
| { | |||||
| ParameterMap::iterator i = mParameters.find(paramID); | |||||
| if (i == mParameters.end()) | |||||
| COMPONENT_THROW(kAudioUnitErr_InvalidParameter); | |||||
| event = &(*i).second; | |||||
| } | |||||
| return *event; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| // Helper method. | |||||
| // returns whether the specified paramID is known to the element | |||||
| // | |||||
| bool AUElement::HasParameterID (AudioUnitParameterID paramID) const | |||||
| { | |||||
| if(mUseIndexedParameters) | |||||
| { | |||||
| if(paramID >= mIndexedParameters.size() ) | |||||
| return false; | |||||
| return true; | |||||
| } | |||||
| ParameterMap::const_iterator i = mParameters.find(paramID); | |||||
| if (i == mParameters.end()) | |||||
| return false; | |||||
| return true; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| // caller assumes that this is actually an immediate parameter | |||||
| // | |||||
| AudioUnitParameterValue AUElement::GetParameter(AudioUnitParameterID paramID) | |||||
| { | |||||
| ParameterMapEvent &event = GetParamEvent(paramID); | |||||
| return event.GetValue(); | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUElement::GetRampSliceStartEnd( AudioUnitParameterID paramID, | |||||
| AudioUnitParameterValue & outStartValue, | |||||
| AudioUnitParameterValue & outEndValue, | |||||
| AudioUnitParameterValue & outValuePerFrameDelta ) | |||||
| { | |||||
| ParameterMapEvent &event = GetParamEvent(paramID); | |||||
| // works even if the value is constant (immediate parameter value) | |||||
| event.GetRampSliceStartEnd(outStartValue, outEndValue, outValuePerFrameDelta ); | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| AudioUnitParameterValue AUElement::GetEndValue( AudioUnitParameterID paramID) | |||||
| { | |||||
| ParameterMapEvent &event = GetParamEvent(paramID); | |||||
| // works even if the value is constant (immediate parameter value) | |||||
| return event.GetEndValue(); | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUElement::SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue inValue, bool okWhenInitialized) | |||||
| { | |||||
| if(mUseIndexedParameters) | |||||
| { | |||||
| ParameterMapEvent &event = GetParamEvent(paramID); | |||||
| event.SetValue(inValue); | |||||
| } | |||||
| else | |||||
| { | |||||
| ParameterMap::iterator i = mParameters.find(paramID); | |||||
| if (i == mParameters.end()) | |||||
| { | |||||
| if (mAudioUnit->IsInitialized() && !okWhenInitialized) { | |||||
| // The AU should not be creating new parameters once initialized. | |||||
| // If a client tries to set an undefined parameter, we could throw as follows, | |||||
| // but this might cause a regression. So it is better to just fail silently. | |||||
| // COMPONENT_THROW(kAudioUnitErr_InvalidParameter); | |||||
| #if DEBUG | |||||
| fprintf(stderr, "WARNING: %s SetParameter for undefined param ID %d while initialized. Ignoring..\n", | |||||
| mAudioUnit->GetLoggingString(), (int)paramID); | |||||
| #endif | |||||
| } else { | |||||
| // create new entry in map for the paramID (only happens first time) | |||||
| ParameterMapEvent event(inValue); | |||||
| mParameters[paramID] = event; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| // paramID already exists in map so simply change its value | |||||
| ParameterMapEvent &event = (*i).second; | |||||
| event.SetValue(inValue); | |||||
| } | |||||
| } | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUElement::SetScheduledEvent( AudioUnitParameterID paramID, | |||||
| const AudioUnitParameterEvent &inEvent, | |||||
| UInt32 inSliceOffsetInBuffer, | |||||
| UInt32 inSliceDurationFrames, | |||||
| bool okWhenInitialized ) | |||||
| { | |||||
| if(mUseIndexedParameters) | |||||
| { | |||||
| ParameterMapEvent &event = GetParamEvent(paramID); | |||||
| event.SetScheduledEvent(inEvent, inSliceOffsetInBuffer, inSliceDurationFrames ); | |||||
| } | |||||
| else | |||||
| { | |||||
| ParameterMap::iterator i = mParameters.find(paramID); | |||||
| if (i == mParameters.end()) | |||||
| { | |||||
| if (mAudioUnit->IsInitialized() && !okWhenInitialized) { | |||||
| // The AU should not be creating new parameters once initialized. | |||||
| // If a client tries to set an undefined parameter, we could throw as follows, | |||||
| // but this might cause a regression. So it is better to just fail silently. | |||||
| // COMPONENT_THROW(kAudioUnitErr_InvalidParameter); | |||||
| #if DEBUG | |||||
| fprintf(stderr, "WARNING: %s SetScheduledEvent for undefined param ID %d while initialized. Ignoring..\n", | |||||
| mAudioUnit->GetLoggingString(), (int)paramID); | |||||
| #endif | |||||
| } else { | |||||
| // create new entry in map for the paramID (only happens first time) | |||||
| ParameterMapEvent event(inEvent, inSliceOffsetInBuffer, inSliceDurationFrames); | |||||
| mParameters[paramID] = event; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| // paramID already exists in map so simply change its value | |||||
| ParameterMapEvent &event = (*i).second; | |||||
| event.SetScheduledEvent(inEvent, inSliceOffsetInBuffer, inSliceDurationFrames ); | |||||
| } | |||||
| } | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUElement::GetParameterList(AudioUnitParameterID *outList) | |||||
| { | |||||
| if(mUseIndexedParameters) | |||||
| { | |||||
| UInt32 nparams = static_cast<UInt32>(mIndexedParameters.size()); | |||||
| for (UInt32 i = 0; i < nparams; i++ ) | |||||
| *outList++ = (AudioUnitParameterID)i; | |||||
| } | |||||
| else | |||||
| { | |||||
| for (ParameterMap::iterator i = mParameters.begin(); i != mParameters.end(); ++i) | |||||
| *outList++ = (*i).first; | |||||
| } | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUElement::SaveState(CFMutableDataRef data) | |||||
| { | |||||
| if(mUseIndexedParameters) | |||||
| { | |||||
| UInt32 nparams = static_cast<UInt32>(mIndexedParameters.size()); | |||||
| UInt32 theData = CFSwapInt32HostToBig(nparams); | |||||
| CFDataAppendBytes(data, (UInt8 *)&theData, sizeof(nparams)); | |||||
| for (UInt32 i = 0; i < nparams; i++) | |||||
| { | |||||
| struct { | |||||
| UInt32 paramID; | |||||
| //CFSwappedFloat32 value; crashes gcc3 PFE | |||||
| UInt32 value; // really a big-endian float | |||||
| } entry; | |||||
| entry.paramID = CFSwapInt32HostToBig(i); | |||||
| AudioUnitParameterValue v = mIndexedParameters[i].GetValue(); | |||||
| entry.value = CFSwapInt32HostToBig(*(UInt32 *)&v ); | |||||
| CFDataAppendBytes(data, (UInt8 *)&entry, sizeof(entry)); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| UInt32 nparams = CFSwapInt32HostToBig(static_cast<uint32_t>(mParameters.size())); | |||||
| CFDataAppendBytes(data, (UInt8 *)&nparams, sizeof(nparams)); | |||||
| for (ParameterMap::iterator i = mParameters.begin(); i != mParameters.end(); ++i) { | |||||
| struct { | |||||
| UInt32 paramID; | |||||
| //CFSwappedFloat32 value; crashes gcc3 PFE | |||||
| UInt32 value; // really a big-endian float | |||||
| } entry; | |||||
| entry.paramID = CFSwapInt32HostToBig((*i).first); | |||||
| AudioUnitParameterValue v = (*i).second.GetValue(); | |||||
| entry.value = CFSwapInt32HostToBig(*(UInt32 *)&v ); | |||||
| CFDataAppendBytes(data, (UInt8 *)&entry, sizeof(entry)); | |||||
| } | |||||
| } | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| const UInt8 * AUElement::RestoreState(const UInt8 *state) | |||||
| { | |||||
| union FloatInt32 { UInt32 i; AudioUnitParameterValue f; }; | |||||
| const UInt8 *p = state; | |||||
| UInt32 nparams = CFSwapInt32BigToHost(*(UInt32 *)p); | |||||
| p += sizeof(UInt32); | |||||
| for (UInt32 i = 0; i < nparams; ++i) { | |||||
| struct { | |||||
| AudioUnitParameterID paramID; | |||||
| AudioUnitParameterValue value; | |||||
| } entry; | |||||
| entry.paramID = CFSwapInt32BigToHost(*(UInt32 *)p); | |||||
| p += sizeof(UInt32); | |||||
| FloatInt32 temp; | |||||
| temp.i = CFSwapInt32BigToHost(*(UInt32 *)p); | |||||
| entry.value = temp.f; | |||||
| p += sizeof(AudioUnitParameterValue); | |||||
| SetParameter(entry.paramID, entry.value); | |||||
| } | |||||
| return p; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUElement::SetName (CFStringRef inName) | |||||
| { | |||||
| if (mElementName) CFRelease (mElementName); | |||||
| mElementName = inName; | |||||
| if (mElementName) CFRetain (mElementName); | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| AUIOElement::AUIOElement(AUBase *audioUnit) : | |||||
| AUElement(audioUnit), | |||||
| mWillAllocate (true) | |||||
| { | |||||
| mStreamFormat.SetAUCanonical(2, // stereo | |||||
| audioUnit->AudioUnitAPIVersion() == 1); | |||||
| // interleaved if API version 1, deinterleaved if version 2 | |||||
| mStreamFormat.mSampleRate = kAUDefaultSampleRate; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| OSStatus AUIOElement::SetStreamFormat(const CAStreamBasicDescription &desc) | |||||
| { | |||||
| mStreamFormat = desc; | |||||
| return AUBase::noErr; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // inFramesToAllocate == 0 implies the AudioUnit's max-frames-per-slice will be used | |||||
| void AUIOElement::AllocateBuffer(UInt32 inFramesToAllocate) | |||||
| { | |||||
| if (GetAudioUnit()->HasBegunInitializing()) | |||||
| { | |||||
| UInt32 framesToAllocate = inFramesToAllocate > 0 ? inFramesToAllocate : GetAudioUnit()->GetMaxFramesPerSlice(); | |||||
| // printf ("will allocate: %d\n", (int)((mWillAllocate && NeedsBufferSpace()) ? framesToAllocate : 0)); | |||||
| mIOBuffer.Allocate(mStreamFormat, (mWillAllocate && NeedsBufferSpace()) ? framesToAllocate : 0); | |||||
| } | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUIOElement::DeallocateBuffer() | |||||
| { | |||||
| mIOBuffer.Deallocate(); | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| // AudioChannelLayout support | |||||
| // outLayoutTagsPtr WILL be NULL if called to find out how many | |||||
| // layouts that Audio Unit will report | |||||
| // return 0 (ie. NO channel layouts) if the AU doesn't require channel layout knowledge | |||||
| UInt32 AUIOElement::GetChannelLayoutTags (AudioChannelLayoutTag *outLayoutTagsPtr) | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| // As the AudioChannelLayout can be a variable length structure | |||||
| // (though in most cases it won't be!!!) | |||||
| // The size of the ACL is always returned by the method | |||||
| // if outMapPtr is NOT-NULL, then AU should copy into this pointer (outMapPtr) the current ACL that it has in use. | |||||
| // the AU should also return whether the property is writable (that is the client can provide any arbitrary ACL that the audio unit will then honour) | |||||
| // or if the property is read only - which is the generally preferred mode. | |||||
| // If the AU doesn't require an AudioChannelLayout, then just return 0. | |||||
| UInt32 AUIOElement::GetAudioChannelLayout (AudioChannelLayout *outMapPtr, | |||||
| Boolean &outWritable) | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| // the incoming channel map will be at least as big as a basic AudioChannelLayout | |||||
| // but its contents will determine its actual size | |||||
| // Subclass should overide if channel map is writable | |||||
| OSStatus AUIOElement::SetAudioChannelLayout (const AudioChannelLayout &inData) | |||||
| { | |||||
| return kAudioUnitErr_InvalidProperty; | |||||
| } | |||||
| // Some units support optional usage of channel maps - typically converter units | |||||
| // that can do channel remapping between different maps. In that optional case | |||||
| // the user should be able to remove a channel map if that is possible. | |||||
| // Typically this is NOT the case (e.g., the 3DMixer even in the stereo case | |||||
| // needs to know if it is rendering to speakers or headphones) | |||||
| OSStatus AUIOElement::RemoveAudioChannelLayout () | |||||
| { | |||||
| return kAudioUnitErr_InvalidPropertyValue; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| AUScope::~AUScope() | |||||
| { | |||||
| for (ElementVector::iterator it = mElements.begin(); it != mElements.end(); ++it) | |||||
| delete *it; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUScope::SetNumberOfElements(UInt32 numElements) | |||||
| { | |||||
| if (mDelegate) | |||||
| return mDelegate->SetNumberOfElements(numElements); | |||||
| if (numElements > mElements.size()) { | |||||
| mElements.reserve(numElements); | |||||
| while (numElements > mElements.size()) { | |||||
| AUElement *elem = mCreator->CreateElement(GetScope(), static_cast<UInt32>(mElements.size())); | |||||
| mElements.push_back(elem); | |||||
| } | |||||
| } else | |||||
| while (numElements < mElements.size()) { | |||||
| AUElement *elem = mElements.back(); | |||||
| mElements.pop_back(); | |||||
| delete elem; | |||||
| } | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| bool AUScope::HasElementWithName () const | |||||
| { | |||||
| for (UInt32 i = 0; i < GetNumberOfElements(); ++i) { | |||||
| AUElement * el = const_cast<AUScope*>(this)->GetElement (i); | |||||
| if (el && el->HasName()) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| void AUScope::AddElementNamesToDict (CFMutableDictionaryRef & inNameDict) | |||||
| { | |||||
| if (HasElementWithName()) | |||||
| { | |||||
| static char string[32]; | |||||
| CFMutableDictionaryRef elementDict = CFDictionaryCreateMutable (NULL, 0, | |||||
| &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); | |||||
| CFStringRef str; | |||||
| for (UInt32 i = 0; i < GetNumberOfElements(); ++i) { | |||||
| AUElement * el = GetElement (i); | |||||
| if (el && el->HasName()) { | |||||
| snprintf (string, sizeof(string), "%d", int(i)); | |||||
| str = CFStringCreateWithCString (NULL, string, kCFStringEncodingASCII); | |||||
| CFDictionarySetValue (elementDict, str, el->GetName()); | |||||
| CFRelease (str); | |||||
| } | |||||
| } | |||||
| snprintf (string, sizeof(string), "%d", int(mScope)); | |||||
| str = CFStringCreateWithCString (NULL, string, kCFStringEncodingASCII); | |||||
| CFDictionarySetValue (inNameDict, str, elementDict); | |||||
| CFRelease (str); | |||||
| CFRelease (elementDict); | |||||
| } | |||||
| } | |||||
| //_____________________________________________________________________________ | |||||
| // | |||||
| bool AUScope::RestoreElementNames (CFDictionaryRef& inNameDict) | |||||
| { | |||||
| static char string[32]; | |||||
| //first we have to see if we have enough elements | |||||
| bool didAddElements = false; | |||||
| unsigned int maxElNum = GetNumberOfElements(); | |||||
| int dictSize = static_cast<int>(CFDictionaryGetCount(inNameDict)); | |||||
| CFStringRef * keys = (CFStringRef*)CA_malloc (dictSize * sizeof (CFStringRef)); | |||||
| CFDictionaryGetKeysAndValues (inNameDict, reinterpret_cast<const void**>(keys), NULL); | |||||
| for (int i = 0; i < dictSize; i++) | |||||
| { | |||||
| unsigned int intKey = 0; | |||||
| CFStringGetCString (keys[i], string, 32, kCFStringEncodingASCII); | |||||
| int result = sscanf (string, "%u", &intKey); | |||||
| // check if sscanf succeeded and element index is less than max elements. | |||||
| if (result && UInt32(intKey) < maxElNum) | |||||
| { | |||||
| CFStringRef elName = reinterpret_cast<CFStringRef>(CFDictionaryGetValue (inNameDict, keys[i])); | |||||
| AUElement* element = GetElement (intKey); | |||||
| if (element) | |||||
| element->SetName (elName); | |||||
| } | |||||
| } | |||||
| free (keys); | |||||
| return didAddElements; | |||||
| } | |||||
| void AUScope::SaveState(CFMutableDataRef data) | |||||
| { | |||||
| AudioUnitElement nElems = GetNumberOfElements(); | |||||
| for (AudioUnitElement ielem = 0; ielem < nElems; ++ielem) { | |||||
| AUElement *element = GetElement(ielem); | |||||
| UInt32 nparams = element->GetNumberOfParameters(); | |||||
| if (nparams > 0) { | |||||
| struct { | |||||
| UInt32 scope; | |||||
| UInt32 element; | |||||
| } hdr; | |||||
| hdr.scope = CFSwapInt32HostToBig(GetScope()); | |||||
| hdr.element = CFSwapInt32HostToBig(ielem); | |||||
| CFDataAppendBytes(data, (UInt8 *)&hdr, sizeof(hdr)); | |||||
| element->SaveState(data); | |||||
| } | |||||
| } | |||||
| } | |||||
| const UInt8 * AUScope::RestoreState(const UInt8 *state) | |||||
| { | |||||
| const UInt8 *p = state; | |||||
| UInt32 elementIdx = CFSwapInt32BigToHost(*(UInt32 *)p); p += sizeof(UInt32); | |||||
| AUElement *element = GetElement(elementIdx); | |||||
| if (!element) { | |||||
| struct { | |||||
| AudioUnitParameterID paramID; | |||||
| AudioUnitParameterValue value; | |||||
| } entry; | |||||
| UInt32 nparams = CFSwapInt32BigToHost(*(UInt32 *)p); | |||||
| p += sizeof(UInt32); | |||||
| p += nparams * sizeof(entry); | |||||
| } else | |||||
| p = element->RestoreState(p); | |||||
| return p; | |||||
| } | |||||
| @@ -0,0 +1,553 @@ | |||||
| /* | |||||
| File: AUScopeElement.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUScopeElement_h__ | |||||
| #define __AUScopeElement_h__ | |||||
| #include <map> | |||||
| #include <vector> | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <AudioUnit/AudioUnit.h> | |||||
| #else | |||||
| #include <AudioUnit.h> | |||||
| #endif | |||||
| #include "ComponentBase.h" | |||||
| #include "AUBuffer.h" | |||||
| class AUBase; | |||||
| // ____________________________________________________________________________ | |||||
| // | |||||
| // represents a parameter's value (either constant or ramped) | |||||
| /*! @class ParameterMapEvent */ | |||||
| class ParameterMapEvent | |||||
| { | |||||
| public: | |||||
| /*! @ctor ParameterMapEvent */ | |||||
| ParameterMapEvent() | |||||
| : mEventType(kParameterEvent_Immediate), mBufferOffset(0), mDurationInFrames(0), mValue1(0.0f), mValue2(0.0f), mSliceDurationFrames(0) | |||||
| {} | |||||
| /*! @ctor ParameterMapEvent */ | |||||
| ParameterMapEvent(AudioUnitParameterValue inValue) | |||||
| : mEventType(kParameterEvent_Immediate), mBufferOffset(0), mDurationInFrames(0), mValue1(inValue), mValue2(inValue), mSliceDurationFrames(0) | |||||
| {} | |||||
| // constructor for scheduled event | |||||
| /*! @ctor ParameterMapEvent */ | |||||
| ParameterMapEvent( const AudioUnitParameterEvent &inEvent, | |||||
| UInt32 inSliceOffsetInBuffer, | |||||
| UInt32 inSliceDurationFrames ) | |||||
| { | |||||
| SetScheduledEvent(inEvent, inSliceOffsetInBuffer, inSliceDurationFrames ); | |||||
| }; | |||||
| /*! @method SetScheduledEvent */ | |||||
| void SetScheduledEvent( const AudioUnitParameterEvent &inEvent, | |||||
| UInt32 inSliceOffsetInBuffer, | |||||
| UInt32 inSliceDurationFrames ) | |||||
| { | |||||
| mEventType = inEvent.eventType; | |||||
| mSliceDurationFrames = inSliceDurationFrames; | |||||
| if(mEventType == kParameterEvent_Immediate ) | |||||
| { | |||||
| // constant immediate value for the whole slice | |||||
| mValue1 = inEvent.eventValues.immediate.value; | |||||
| mValue2 = mValue1; | |||||
| mDurationInFrames = inSliceDurationFrames; | |||||
| mBufferOffset = 0; | |||||
| } | |||||
| else | |||||
| { | |||||
| mDurationInFrames = inEvent.eventValues.ramp.durationInFrames; | |||||
| mBufferOffset = inEvent.eventValues.ramp.startBufferOffset - inSliceOffsetInBuffer; // shift over for this slice | |||||
| mValue1 = inEvent.eventValues.ramp.startValue; | |||||
| mValue2 = inEvent.eventValues.ramp.endValue; | |||||
| } | |||||
| }; | |||||
| /*! @method GetEventType */ | |||||
| AUParameterEventType GetEventType() const {return mEventType;}; | |||||
| /*! @method GetValue */ | |||||
| AudioUnitParameterValue GetValue() const {return mValue1;}; // only valid if immediate event type | |||||
| /*! @method GetEndValue */ | |||||
| AudioUnitParameterValue GetEndValue() const {return mValue2;}; // only valid if immediate event type | |||||
| /*! @method SetValue */ | |||||
| void SetValue(AudioUnitParameterValue inValue) | |||||
| { | |||||
| mEventType = kParameterEvent_Immediate; | |||||
| mValue1 = inValue; | |||||
| mValue2 = inValue; | |||||
| } | |||||
| // interpolates the start and end values corresponding to the current processing slice | |||||
| // most ramp parameter implementations will want to use this method | |||||
| // the start value will correspond to the start of the slice | |||||
| // the end value will correspond to the end of the slice | |||||
| /*! @method GetRampSliceStartEnd */ | |||||
| void GetRampSliceStartEnd( AudioUnitParameterValue & outStartValue, | |||||
| AudioUnitParameterValue & outEndValue, | |||||
| AudioUnitParameterValue & outValuePerFrameDelta ) | |||||
| { | |||||
| if (mEventType == kParameterEvent_Ramped) { | |||||
| outValuePerFrameDelta = (mValue2 - mValue1) / mDurationInFrames; | |||||
| outStartValue = mValue1 + outValuePerFrameDelta * (-mBufferOffset); // corresponds to frame 0 of this slice | |||||
| outEndValue = outStartValue + outValuePerFrameDelta * mSliceDurationFrames; | |||||
| } else { | |||||
| outValuePerFrameDelta = 0; | |||||
| outStartValue = outEndValue = mValue1; | |||||
| } | |||||
| }; | |||||
| // Some ramp parameter implementations will want to interpret the ramp using their | |||||
| // own interpolation method (perhaps non-linear) | |||||
| // This method gives the raw ramp information, relative to this processing slice | |||||
| // for the client to interpret as desired | |||||
| /*! @method GetRampInfo */ | |||||
| void GetRampInfo( SInt32 & outBufferOffset, | |||||
| UInt32 & outDurationInFrames, | |||||
| AudioUnitParameterValue & outStartValue, | |||||
| AudioUnitParameterValue & outEndValue ) | |||||
| { | |||||
| outBufferOffset = mBufferOffset; | |||||
| outDurationInFrames = mDurationInFrames; | |||||
| outStartValue = mValue1; | |||||
| outEndValue = mValue2; | |||||
| }; | |||||
| #if DEBUG | |||||
| void Print() | |||||
| { | |||||
| printf("ParameterEvent @ %p\n", this); | |||||
| printf(" mEventType = %d\n", (int)mEventType); | |||||
| printf(" mBufferOffset = %d\n", (int)mBufferOffset); | |||||
| printf(" mDurationInFrames = %d\n", (int)mDurationInFrames); | |||||
| printf(" mSliceDurationFrames = %d\n", (int)mSliceDurationFrames); | |||||
| printf(" mValue1 = %.5f\n", mValue1); | |||||
| printf(" mValue2 = %.5f\n", mValue2); | |||||
| } | |||||
| #endif | |||||
| private: | |||||
| AUParameterEventType mEventType; | |||||
| SInt32 mBufferOffset; // ramp start offset relative to start of this slice (may be negative) | |||||
| UInt32 mDurationInFrames; // total duration of ramp parameter | |||||
| AudioUnitParameterValue mValue1; // value if immediate : startValue if ramp | |||||
| AudioUnitParameterValue mValue2; // endValue (only used for ramp) | |||||
| UInt32 mSliceDurationFrames; // duration of this processing slice | |||||
| }; | |||||
| // ____________________________________________________________________________ | |||||
| // | |||||
| class AUIOElement; | |||||
| /*! @class AUElement */ | |||||
| class AUElement { | |||||
| public: | |||||
| /*! @ctor AUElement */ | |||||
| AUElement(AUBase *audioUnit) : mAudioUnit(audioUnit), | |||||
| mUseIndexedParameters(false), mElementName(0) { } | |||||
| /*! @dtor ~AUElement */ | |||||
| virtual ~AUElement() { if (mElementName) CFRelease (mElementName); } | |||||
| /*! @method GetNumberOfParameters */ | |||||
| virtual UInt32 GetNumberOfParameters() | |||||
| { | |||||
| if(mUseIndexedParameters) return static_cast<UInt32>(mIndexedParameters.size()); else return static_cast<UInt32>(mParameters.size()); | |||||
| } | |||||
| /*! @method GetParameterList */ | |||||
| virtual void GetParameterList(AudioUnitParameterID *outList); | |||||
| /*! @method HasParameterID */ | |||||
| bool HasParameterID (AudioUnitParameterID paramID) const; | |||||
| /*! @method GetParameter */ | |||||
| AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID); | |||||
| /*! @method SetParameter */ | |||||
| void SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value, bool okWhenInitialized = false); | |||||
| // Only set okWhenInitialized to true when you know the outside world cannot access this element. Otherwise the parameter map could get corrupted. | |||||
| // interpolates the start and end values corresponding to the current processing slice | |||||
| // most ramp parameter implementations will want to use this method | |||||
| /*! @method GetRampSliceStartEnd */ | |||||
| void GetRampSliceStartEnd( AudioUnitParameterID paramID, | |||||
| AudioUnitParameterValue & outStartValue, | |||||
| AudioUnitParameterValue & outEndValue, | |||||
| AudioUnitParameterValue & outValuePerFrameDelta ); | |||||
| /*! @method GetEndValue */ | |||||
| AudioUnitParameterValue GetEndValue( AudioUnitParameterID paramID); | |||||
| /*! @method SetRampParameter */ | |||||
| void SetScheduledEvent( AudioUnitParameterID paramID, | |||||
| const AudioUnitParameterEvent &inEvent, | |||||
| UInt32 inSliceOffsetInBuffer, | |||||
| UInt32 inSliceDurationFrames, | |||||
| bool okWhenInitialized = false ); | |||||
| // Only set okWhenInitialized to true when you know the outside world cannot access this element. Otherwise the parameter map could get corrupted. | |||||
| /*! @method GetAudioUnit */ | |||||
| AUBase * GetAudioUnit() const { return mAudioUnit; }; | |||||
| /*! @method SaveState */ | |||||
| void SaveState(CFMutableDataRef data); | |||||
| /*! @method RestoreState */ | |||||
| const UInt8 * RestoreState(const UInt8 *state); | |||||
| /*! @method GetName */ | |||||
| CFStringRef GetName () const { return mElementName; } | |||||
| /*! @method SetName */ | |||||
| void SetName (CFStringRef inName); | |||||
| /*! @method HasName */ | |||||
| bool HasName () const { return mElementName != 0; } | |||||
| /*! @method UseIndexedParameters */ | |||||
| virtual void UseIndexedParameters(int inNumberOfParameters); | |||||
| /*! @method AsIOElement*/ | |||||
| virtual AUIOElement* AsIOElement () { return NULL; } | |||||
| protected: | |||||
| inline ParameterMapEvent& GetParamEvent(AudioUnitParameterID paramID); | |||||
| private: | |||||
| typedef std::map<AudioUnitParameterID, ParameterMapEvent, std::less<AudioUnitParameterID> > ParameterMap; | |||||
| /*! @var mAudioUnit */ | |||||
| AUBase * mAudioUnit; | |||||
| /*! @var mParameters */ | |||||
| ParameterMap mParameters; | |||||
| /*! @var mUseIndexedParameters */ | |||||
| bool mUseIndexedParameters; | |||||
| /*! @var mIndexedParameters */ | |||||
| std::vector<ParameterMapEvent> mIndexedParameters; | |||||
| /*! @var mElementName */ | |||||
| CFStringRef mElementName; | |||||
| }; | |||||
| // ____________________________________________________________________________ | |||||
| // | |||||
| /*! @class AUIOElement */ | |||||
| class AUIOElement : public AUElement { | |||||
| public: | |||||
| /*! @ctor AUIOElement */ | |||||
| AUIOElement(AUBase *audioUnit); | |||||
| /*! @method GetStreamFormat */ | |||||
| const CAStreamBasicDescription &GetStreamFormat() const { return mStreamFormat; } | |||||
| /*! @method SetStreamFormat */ | |||||
| virtual OSStatus SetStreamFormat(const CAStreamBasicDescription &desc); | |||||
| /*! @method AllocateBuffer */ | |||||
| virtual void AllocateBuffer(UInt32 inFramesToAllocate = 0); | |||||
| /*! @method DeallocateBuffer */ | |||||
| void DeallocateBuffer(); | |||||
| /*! @method NeedsBufferSpace */ | |||||
| virtual bool NeedsBufferSpace() const = 0; | |||||
| /*! @method SetWillAllocateBuffer */ | |||||
| void SetWillAllocateBuffer(bool inFlag) { | |||||
| mWillAllocate = inFlag; | |||||
| } | |||||
| /*! @method WillAllocateBuffer */ | |||||
| bool WillAllocateBuffer() const { | |||||
| return mWillAllocate; | |||||
| } | |||||
| /*! @method UseExternalBuffer */ | |||||
| void UseExternalBuffer(const AudioUnitExternalBuffer &buf) { | |||||
| mIOBuffer.UseExternalBuffer(mStreamFormat, buf); | |||||
| } | |||||
| /*! @method PrepareBuffer */ | |||||
| AudioBufferList & PrepareBuffer(UInt32 nFrames) { | |||||
| if (mWillAllocate) | |||||
| return mIOBuffer.PrepareBuffer(mStreamFormat, nFrames); | |||||
| throw OSStatus(kAudioUnitErr_InvalidPropertyValue); | |||||
| } | |||||
| /*! @method PrepareNullBuffer */ | |||||
| AudioBufferList & PrepareNullBuffer(UInt32 nFrames) { | |||||
| return mIOBuffer.PrepareNullBuffer(mStreamFormat, nFrames); | |||||
| } | |||||
| /*! @method SetBufferList */ | |||||
| AudioBufferList & SetBufferList(AudioBufferList &abl) { return mIOBuffer.SetBufferList(abl); } | |||||
| /*! @method SetBuffer */ | |||||
| void SetBuffer(UInt32 index, AudioBuffer &ab) { mIOBuffer.SetBuffer(index, ab); } | |||||
| /*! @method InvalidateBufferList */ | |||||
| void InvalidateBufferList() { mIOBuffer.InvalidateBufferList(); } | |||||
| /*! @method GetBufferList */ | |||||
| AudioBufferList & GetBufferList() const { return mIOBuffer.GetBufferList(); } | |||||
| /*! @method GetChannelData */ | |||||
| AudioUnitSampleType * GetChannelData(int ch) const { | |||||
| if (mStreamFormat.IsInterleaved()) | |||||
| return static_cast<AudioUnitSampleType *>(mIOBuffer.GetBufferList().mBuffers[0].mData) + ch; | |||||
| else | |||||
| return static_cast<AudioUnitSampleType *>(mIOBuffer.GetBufferList().mBuffers[ch].mData); | |||||
| } | |||||
| Float32 * GetFloat32ChannelData(int ch) const { | |||||
| if (mStreamFormat.IsInterleaved()) | |||||
| return static_cast<Float32 *>(mIOBuffer.GetBufferList().mBuffers[0].mData) + ch; | |||||
| else | |||||
| return static_cast<Float32 *>(mIOBuffer.GetBufferList().mBuffers[ch].mData); | |||||
| } | |||||
| SInt32 * GetSInt32ChannelData(int ch) const { | |||||
| if (mStreamFormat.IsInterleaved()) | |||||
| return static_cast<SInt32 *>(mIOBuffer.GetBufferList().mBuffers[0].mData) + ch; | |||||
| else | |||||
| return static_cast<SInt32 *>(mIOBuffer.GetBufferList().mBuffers[ch].mData); | |||||
| } | |||||
| SInt16 * GetInt16ChannelData(int ch) const { | |||||
| if (mStreamFormat.IsInterleaved()) | |||||
| return static_cast<SInt16 *>(mIOBuffer.GetBufferList().mBuffers[0].mData) + ch; | |||||
| else | |||||
| return static_cast<SInt16 *>(mIOBuffer.GetBufferList().mBuffers[ch].mData); | |||||
| } | |||||
| /*! @method CopyBufferListTo */ | |||||
| void CopyBufferListTo(AudioBufferList &abl) const { | |||||
| mIOBuffer.CopyBufferListTo(abl); | |||||
| } | |||||
| /*! @method CopyBufferContentsTo */ | |||||
| void CopyBufferContentsTo(AudioBufferList &abl) const { | |||||
| mIOBuffer.CopyBufferContentsTo(abl); | |||||
| } | |||||
| /* UInt32 BytesToFrames(UInt32 nBytes) { return nBytes / mStreamFormat.mBytesPerFrame; } | |||||
| UInt32 BytesToFrames(AudioBufferList &abl) { | |||||
| return BytesToFrames(abl.mBuffers[0].mDataByteSize); | |||||
| } | |||||
| UInt32 FramesToBytes(UInt32 nFrames) { return nFrames * mStreamFormat.mBytesPerFrame; }*/ | |||||
| /*! @method IsInterleaved */ | |||||
| bool IsInterleaved() const { return mStreamFormat.IsInterleaved(); } | |||||
| /*! @method NumberChannels */ | |||||
| UInt32 NumberChannels() const { return mStreamFormat.NumberChannels(); } | |||||
| /*! @method NumberInterleavedChannels */ | |||||
| UInt32 NumberInterleavedChannels() const { return mStreamFormat.NumberInterleavedChannels(); } | |||||
| /*! @method GetChannelMapTags */ | |||||
| virtual UInt32 GetChannelLayoutTags (AudioChannelLayoutTag *outLayoutTagsPtr); | |||||
| /*! @method GetAudioChannelLayout */ | |||||
| virtual UInt32 GetAudioChannelLayout (AudioChannelLayout *outMapPtr, Boolean &outWritable); | |||||
| /*! @method SetAudioChannelLayout */ | |||||
| virtual OSStatus SetAudioChannelLayout (const AudioChannelLayout &inData); | |||||
| /*! @method RemoveAudioChannelLayout */ | |||||
| virtual OSStatus RemoveAudioChannelLayout (); | |||||
| /*! @method AsIOElement*/ | |||||
| virtual AUIOElement* AsIOElement () { return this; } | |||||
| protected: | |||||
| /*! @var mStreamFormat */ | |||||
| CAStreamBasicDescription mStreamFormat; | |||||
| /*! @var mIOBuffer */ | |||||
| AUBufferList mIOBuffer; // for input: input proc buffer, only allocated when needed | |||||
| // for output: output cache, usually allocated early on | |||||
| /*! @var mWillAllocate */ | |||||
| bool mWillAllocate; | |||||
| }; | |||||
| // ____________________________________________________________________________ | |||||
| // | |||||
| // AUScopeDelegates are a way to get virtual scopes. | |||||
| /*! @class AUScopeDelegate */ | |||||
| class AUScopeDelegate { | |||||
| public: | |||||
| /*! @ctor AUScopeDelegate */ | |||||
| AUScopeDelegate() : mCreator(NULL), mScope(0) { } | |||||
| /*! @dtor ~AUScopeDelegate */ | |||||
| virtual ~AUScopeDelegate() {} | |||||
| /*! @method Initialize */ | |||||
| void Initialize( AUBase *creator, | |||||
| AudioUnitScope scope, | |||||
| UInt32 numElements) | |||||
| { | |||||
| mCreator = creator; | |||||
| mScope = scope; | |||||
| SetNumberOfElements(numElements); | |||||
| } | |||||
| /*! @method SetNumberOfElements */ | |||||
| virtual void SetNumberOfElements(UInt32 numElements) = 0; | |||||
| /*! @method GetNumberOfElements */ | |||||
| virtual UInt32 GetNumberOfElements() = 0; | |||||
| /*! @method GetElement */ | |||||
| virtual AUElement * GetElement(UInt32 elementIndex) = 0; | |||||
| AUBase * GetCreator() const { return mCreator; } | |||||
| AudioUnitScope GetScope() const { return mScope; } | |||||
| private: | |||||
| /*! @var mCreator */ | |||||
| AUBase * mCreator; | |||||
| /*! @var mScope */ | |||||
| AudioUnitScope mScope; | |||||
| }; | |||||
| // ____________________________________________________________________________ | |||||
| // | |||||
| /*! @class AUScope */ | |||||
| class AUScope { | |||||
| public: | |||||
| /*! @ctor AUScope */ | |||||
| AUScope() : mCreator(NULL), mScope(0), mDelegate(0) { } | |||||
| /*! @dtor ~AUScope */ | |||||
| ~AUScope(); | |||||
| /*! @method Initialize */ | |||||
| void Initialize(AUBase *creator, | |||||
| AudioUnitScope scope, | |||||
| UInt32 numElements) | |||||
| { | |||||
| mCreator = creator; | |||||
| mScope = scope; | |||||
| if (mDelegate) | |||||
| return mDelegate->Initialize(creator, scope, numElements); | |||||
| SetNumberOfElements(numElements); | |||||
| } | |||||
| /*! @method SetNumberOfElements */ | |||||
| void SetNumberOfElements(UInt32 numElements); | |||||
| /*! @method GetNumberOfElements */ | |||||
| UInt32 GetNumberOfElements() const | |||||
| { | |||||
| if (mDelegate) | |||||
| return mDelegate->GetNumberOfElements(); | |||||
| return static_cast<UInt32>(mElements.size()); | |||||
| } | |||||
| /*! @method GetElement */ | |||||
| AUElement * GetElement(UInt32 elementIndex) const | |||||
| { | |||||
| if (mDelegate) | |||||
| return mDelegate->GetElement(elementIndex); | |||||
| ElementVector::const_iterator i = mElements.begin() + elementIndex; | |||||
| // catch passing -1 in as the elementIndex - causes a wrap around | |||||
| return (i >= mElements.end() || i < mElements.begin()) ? NULL : *i; | |||||
| } | |||||
| /*! @method SafeGetElement */ | |||||
| AUElement * SafeGetElement(UInt32 elementIndex) | |||||
| { | |||||
| AUElement *element = GetElement(elementIndex); | |||||
| if (element == NULL) | |||||
| COMPONENT_THROW(kAudioUnitErr_InvalidElement); | |||||
| return element; | |||||
| } | |||||
| /*! @method GetIOElement */ | |||||
| AUIOElement * GetIOElement(UInt32 elementIndex) const | |||||
| { | |||||
| AUElement *element = GetElement(elementIndex); | |||||
| AUIOElement *ioel = element ? element->AsIOElement () : NULL; | |||||
| if (!ioel) | |||||
| COMPONENT_THROW (kAudioUnitErr_InvalidElement); | |||||
| return ioel; | |||||
| } | |||||
| /*! @method HasElementWithName */ | |||||
| bool HasElementWithName () const; | |||||
| /*! @method AddElementNamesToDict */ | |||||
| void AddElementNamesToDict (CFMutableDictionaryRef & inNameDict); | |||||
| bool RestoreElementNames (CFDictionaryRef& inNameDict); | |||||
| AudioUnitScope GetScope() const { return mScope; } | |||||
| void SetDelegate(AUScopeDelegate* inDelegate) { mDelegate = inDelegate; } | |||||
| /*! @method SaveState */ | |||||
| void SaveState(CFMutableDataRef data); | |||||
| /*! @method RestoreState */ | |||||
| const UInt8 * RestoreState(const UInt8 *state); | |||||
| private: | |||||
| typedef std::vector<AUElement *> ElementVector; | |||||
| /*! @var mCreator */ | |||||
| AUBase * mCreator; | |||||
| /*! @var mScope */ | |||||
| AudioUnitScope mScope; | |||||
| /*! @var mElements */ | |||||
| ElementVector mElements; | |||||
| /*! @var mDelegate */ | |||||
| AUScopeDelegate * mDelegate; | |||||
| }; | |||||
| #endif // __AUScopeElement_h__ | |||||
| @@ -0,0 +1,93 @@ | |||||
| /* | |||||
| File: AUSilentTimeout.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUSilentTimeout | |||||
| #define __AUSilentTimeout | |||||
| class AUSilentTimeout | |||||
| { | |||||
| public: | |||||
| AUSilentTimeout() | |||||
| : mTimeoutCounter(0), | |||||
| mResetTimer(true) | |||||
| {}; | |||||
| void Process(UInt32 inFramesToProcess, UInt32 inTimeoutLimit, bool &ioSilence ) | |||||
| { | |||||
| if(ioSilence ) | |||||
| { | |||||
| if(mResetTimer ) | |||||
| { | |||||
| mTimeoutCounter = inTimeoutLimit; | |||||
| mResetTimer = false; | |||||
| } | |||||
| if(mTimeoutCounter > 0 ) | |||||
| { | |||||
| mTimeoutCounter -= inFramesToProcess; | |||||
| ioSilence = false; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| // signal to reset the next time we receive silence | |||||
| mResetTimer = true; | |||||
| } | |||||
| } | |||||
| void Reset() | |||||
| { | |||||
| mResetTimer = true; | |||||
| }; | |||||
| private: | |||||
| SInt32 mTimeoutCounter; | |||||
| bool mResetTimer; | |||||
| }; | |||||
| #endif // __AUSilentTimeout | |||||
| @@ -0,0 +1,163 @@ | |||||
| /* | |||||
| File: AUTimestampGenerator.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUTimestampGenerator_h__ | |||||
| #define __AUTimestampGenerator_h__ | |||||
| #include <math.h> | |||||
| #include "CAHostTimeBase.h" | |||||
| #include <stdio.h> | |||||
| #define TSGFMT "0x%10qx" | |||||
| //#define TSGFMT "%10qd" | |||||
| // This class generates a continuously increasing series of timestamps based | |||||
| // on a series of potentially discontinuous timestamps (as can be delivered from | |||||
| // CoreAudio in the event of an overload or major engine change). | |||||
| // N.B.: "output" = downstream (source) timestamp | |||||
| // "input" = upstream (derived) timestamp | |||||
| class AUTimestampGenerator { | |||||
| public: | |||||
| AUTimestampGenerator(bool hostTimeDiscontinuityCorrection = false) | |||||
| { | |||||
| mState.mStartInputAtZero = true; | |||||
| mState.mBypassed = false; | |||||
| mState.mHostTimeDiscontinuityCorrection = hostTimeDiscontinuityCorrection; | |||||
| #if DEBUG | |||||
| mVerbosity = 0; | |||||
| snprintf(mDebugName, sizeof(mDebugName), "tsg @ %p", this); | |||||
| #endif | |||||
| // CAHostTimeBase should be used instead of the calls in <CoreAudio/HostTime.h> | |||||
| // we make this call here to ensure that this is initialized, otherwise the first time | |||||
| // you do actually call CAHostTimeBase to do work, can be on the render thread, and lead to unwanted VM faults | |||||
| CAHostTimeBase::GetFrequency(); | |||||
| Reset(); | |||||
| } | |||||
| void SetStartInputAtZero(bool b) { mState.mStartInputAtZero = b; } | |||||
| bool GetStartInputAtZero() const { return mState.mStartInputAtZero; } | |||||
| // bypassing is intended for a narrow special case. the upstream sample time will always be the same as the downstream time. | |||||
| void SetBypassed(bool b) { mState.mBypassed = b; } | |||||
| bool GetBypassed() const { return mState.mBypassed; } | |||||
| // Call this to reset the timeline. | |||||
| void Reset() | |||||
| { | |||||
| mState.mCurrentInputTime.mSampleTime = 0.; | |||||
| mState.mNextInputSampleTime = 0.; | |||||
| mState.mCurrentOutputTime.mSampleTime = 0.; | |||||
| mState.mNextOutputSampleTime = 0.; | |||||
| mState.mLastOutputTime.mFlags = 0; | |||||
| mState.mRateScalarAdj = 1.; | |||||
| mFirstTime = true; | |||||
| #if DEBUG | |||||
| if (mVerbosity) | |||||
| printf("%-20.20s: Reset\n", mDebugName); | |||||
| #endif | |||||
| } | |||||
| // Call this once per render cycle with the downstream timestamp. | |||||
| // expectedDeltaFrames is the expected difference between the current and NEXT | |||||
| // downstream timestamps. | |||||
| // sampleRate is the OUTPUT sample rate. | |||||
| void AddOutputTime(const AudioTimeStamp &inTimeStamp, Float64 expectedDeltaFrames, double outputSampleRate, double rateScalarAdj=1.0); | |||||
| // Call this once per render cycle to obtain the upstream timestamp. | |||||
| // framesToAdvance is the number of frames the input timeline is to be | |||||
| // advanced during this render cycle. | |||||
| // sampleRate is the INPUT sample rate. | |||||
| const AudioTimeStamp & GenerateInputTime(Float64 framesToAdvance, double inputSampleRate, bool advanceHostTime = false); | |||||
| // this can be called to override the setting of the next input sample time in GenerateInputTime | |||||
| void Advance(Float64 framesToAdvance) | |||||
| { | |||||
| #if DEBUG | |||||
| if (mVerbosity > 1) | |||||
| printf("%-20.20s: ADVANCE in = " TSGFMT " advance = " TSGFMT "\n", mDebugName, (SInt64)mState.mCurrentInputTime.mSampleTime, (SInt64)framesToAdvance); | |||||
| #endif | |||||
| mState.mNextInputSampleTime = mState.mCurrentInputTime.mSampleTime + framesToAdvance; | |||||
| } | |||||
| struct State { | |||||
| AudioTimeStamp mCurrentInputTime; | |||||
| Float64 mNextInputSampleTime; | |||||
| Float64 mNextOutputSampleTime; | |||||
| Float64 mInputSampleTimeForOutputPull; | |||||
| AudioTimeStamp mLastOutputTime; | |||||
| AudioTimeStamp mCurrentOutputTime; | |||||
| bool mStartInputAtZero; // if true, input timeline starts at 0, else it starts | |||||
| // synced with the output timeline | |||||
| bool mDiscontinuous; | |||||
| bool mBypassed; | |||||
| Float64 mDiscontinuityDeltaSamples; | |||||
| double mRateScalarAdj; | |||||
| bool mHostTimeDiscontinuityCorrection; // If true, propagate timestamp discontinuities using host time. | |||||
| }; | |||||
| void GetState(State& outState) const { outState = mState; } | |||||
| void SetState(State const& inState) { mState = inState; mFirstTime = false; } | |||||
| private: | |||||
| struct State mState; | |||||
| bool mFirstTime; | |||||
| #if DEBUG | |||||
| public: | |||||
| int mVerbosity; | |||||
| char mDebugName[64]; | |||||
| #endif | |||||
| }; | |||||
| #endif // __AUTimestampGenerator_h__ | |||||
| @@ -0,0 +1,88 @@ | |||||
| /* | |||||
| File: AUViewLocalizedStringKeys.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __AUViewLocalizedStringKeys_h__ | |||||
| #define __AUViewLocalizedStringKeys_h__ | |||||
| // ACCESS POINT: | |||||
| #define kLocalizedStringBundle_AUView CFSTR("com.apple.audio.units.Components") | |||||
| #define kLocalizedStringTable_AUView CFSTR("CustomUI") | |||||
| // UNLOCALIZED STRINGS: | |||||
| #define kAUViewUnlocalizedString_TitleSeparator CFSTR(": ") | |||||
| // Generic View: | |||||
| #define kAUViewLocalizedStringKey_AudioUnit CFSTR("Audio Unit") | |||||
| #define kAUViewLocalizedStringKey_Manufacturer CFSTR("Manufacturer") | |||||
| #define kAUViewLocalizedStringKey_FactoryPreset CFSTR("Factory Preset") | |||||
| #define kAUViewLocalizedStringKey_Properties CFSTR("Properties") | |||||
| #define kAUViewLocalizedStringKey_Parameters CFSTR("Parameters") | |||||
| #define kAUViewLocalizedStringKey_Standard CFSTR("Standard") | |||||
| #define kAUViewLocalizedStringKey_Expert CFSTR("Expert") | |||||
| // AULoadCPU: | |||||
| #define kAUViewLocalizedStringKey_RestrictCPULoad CFSTR("Restrict CPU Load") | |||||
| #define kAUViewLocalizedStringKey_PercentSymbol CFSTR("%") | |||||
| #define kAUViewLocalizedStringKey_NotApplicable CFSTR("n/a") | |||||
| // AUDiskStreamingCheckbox: | |||||
| #define kAUViewLocalizedStringKey_StreamFromDisk CFSTR("Stream From Disk") | |||||
| // AURenderQualityPopup: | |||||
| #define kAUViewLocalizedStringKey_RenderQuality CFSTR("Render Quality") | |||||
| #define kAUViewLocalizedStringKey_Maximum CFSTR("Maximum") | |||||
| #define kAUViewLocalizedStringKey_High CFSTR("High") | |||||
| #define kAUViewLocalizedStringKey_Medium CFSTR("Medium") | |||||
| #define kAUViewLocalizedStringKey_Low CFSTR("Low") | |||||
| #define kAUViewLocalizedStringKey_Minimum CFSTR("Minimum") | |||||
| // AUChannelLayoutPopUp: | |||||
| #define kAUViewLocalizedStringKey_AudioChannelLayout CFSTR("Audio Channel Layout") | |||||
| #endif //__AUViewLocalizedStringKeys_h__ | |||||
| @@ -0,0 +1,400 @@ | |||||
| /* | |||||
| File: CAAUParameter.cpp | |||||
| Abstract: CAAUParameter.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "CAAUParameter.h" | |||||
| CAAUParameter::CAAUParameter() | |||||
| { | |||||
| memset(this, 0, sizeof(CAAUParameter)); | |||||
| } | |||||
| CAAUParameter::CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element) | |||||
| { | |||||
| memset(this, 0, sizeof(CAAUParameter)); | |||||
| Init (au, param, scope, element); | |||||
| } | |||||
| CAAUParameter::CAAUParameter (AudioUnitParameter &inParam) | |||||
| { | |||||
| memset(this, 0, sizeof(CAAUParameter)); | |||||
| Init (inParam.mAudioUnit, inParam.mParameterID, inParam.mScope, inParam.mElement); | |||||
| } | |||||
| CAAUParameter::CAAUParameter(const CAAUParameter &a) | |||||
| { | |||||
| memset(this, 0, sizeof(CAAUParameter)); | |||||
| *this = a; | |||||
| } | |||||
| CAAUParameter & CAAUParameter::operator = (const CAAUParameter &a) | |||||
| { | |||||
| if (mParamName) CFRelease(mParamName); | |||||
| if (mParamTag) CFRelease(mParamTag); | |||||
| if (mNamedParams) CFRelease(mNamedParams); | |||||
| memcpy(this, &a, sizeof(CAAUParameter)); | |||||
| if (mParamName) CFRetain(mParamName); | |||||
| if (mParamTag) CFRetain(mParamTag); | |||||
| if (mNamedParams) CFRetain(mNamedParams); | |||||
| return *this; | |||||
| } | |||||
| CAAUParameter::~CAAUParameter() | |||||
| { | |||||
| if (mParamName) CFRelease(mParamName); | |||||
| if (mParamTag) CFRelease(mParamTag); | |||||
| if (mNamedParams) CFRelease (mNamedParams); | |||||
| } | |||||
| void CAAUParameter::Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element) | |||||
| { | |||||
| mAudioUnit = au; | |||||
| mParameterID = param; | |||||
| mScope = scope; | |||||
| mElement = element; | |||||
| UInt32 propertySize = sizeof(mParamInfo); | |||||
| OSStatus err = AudioUnitGetProperty(au, kAudioUnitProperty_ParameterInfo, | |||||
| scope, param, &mParamInfo, &propertySize); | |||||
| if (err) | |||||
| memset(&mParamInfo, 0, sizeof(mParamInfo)); | |||||
| if (mParamInfo.flags & kAudioUnitParameterFlag_HasCFNameString) { | |||||
| mParamName = mParamInfo.cfNameString; | |||||
| if (!(mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease)) | |||||
| CFRetain (mParamName); | |||||
| } else | |||||
| mParamName = CFStringCreateWithCString(NULL, mParamInfo.name, kCFStringEncodingUTF8); | |||||
| const char* str = 0; | |||||
| switch (mParamInfo.unit) | |||||
| { | |||||
| case kAudioUnitParameterUnit_Boolean: | |||||
| str = "T/F"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Percent: | |||||
| case kAudioUnitParameterUnit_EqualPowerCrossfade: | |||||
| str = "%"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Seconds: | |||||
| str = "Secs"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_SampleFrames: | |||||
| str = "Samps"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Phase: | |||||
| case kAudioUnitParameterUnit_Degrees: | |||||
| str = "Degr."; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Hertz: | |||||
| str = "Hz"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Cents: | |||||
| case kAudioUnitParameterUnit_AbsoluteCents: | |||||
| str = "Cents"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_RelativeSemiTones: | |||||
| str = "S-T"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_MIDINoteNumber: | |||||
| case kAudioUnitParameterUnit_MIDIController: | |||||
| str = "MIDI"; | |||||
| //these are inclusive, so add one value here | |||||
| mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue); | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Decibels: | |||||
| str = "dB"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_MixerFaderCurve1: | |||||
| case kAudioUnitParameterUnit_LinearGain: | |||||
| str = "Gain"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Pan: | |||||
| str = "L/R"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Meters: | |||||
| str = "Mtrs"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Octaves: | |||||
| str = "8ve"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_BPM: | |||||
| str = "BPM"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Beats: | |||||
| str = "Beats"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Milliseconds: | |||||
| str = "msecs"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Ratio: | |||||
| str = "Ratio"; | |||||
| break; | |||||
| case kAudioUnitParameterUnit_Indexed: | |||||
| { | |||||
| propertySize = sizeof(mNamedParams); | |||||
| err = AudioUnitGetProperty (au, | |||||
| kAudioUnitProperty_ParameterValueStrings, | |||||
| scope, | |||||
| param, | |||||
| &mNamedParams, | |||||
| &propertySize); | |||||
| if (!err && mNamedParams) { | |||||
| mNumIndexedParams = CFArrayGetCount(mNamedParams); | |||||
| } else { | |||||
| //these are inclusive, so add one value here | |||||
| mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue); | |||||
| } | |||||
| str = NULL; | |||||
| } | |||||
| break; | |||||
| case kAudioUnitParameterUnit_CustomUnit: | |||||
| { | |||||
| CFStringRef unitName = mParamInfo.unitName; | |||||
| static char paramStr[256]; | |||||
| CFStringGetCString (unitName, paramStr, 256, kCFStringEncodingUTF8); | |||||
| if (mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease) | |||||
| CFRelease (unitName); | |||||
| str = paramStr; | |||||
| break; | |||||
| } | |||||
| case kAudioUnitParameterUnit_Generic: | |||||
| case kAudioUnitParameterUnit_Rate: | |||||
| default: | |||||
| str = NULL; | |||||
| break; | |||||
| } | |||||
| if (str) | |||||
| mParamTag = CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8); | |||||
| else | |||||
| mParamTag = NULL; | |||||
| } | |||||
| Float32 CAAUParameter::GetValue() const | |||||
| { | |||||
| Float32 value = 0.; | |||||
| //OSStatus err = | |||||
| AudioUnitGetParameter(mAudioUnit, mParameterID, mScope, mElement, &value); | |||||
| return value; | |||||
| } | |||||
| CFStringRef CreateLocalizedStringForParameterValue ( double inParameterValue, | |||||
| const CAAUParameter * inParameter, | |||||
| UInt32 inDigits, | |||||
| UInt32 minDigits) { | |||||
| if (!inParameter) return nil; | |||||
| AudioUnitParameterInfo info = inParameter->ParamInfo(); | |||||
| int pow10; | |||||
| switch (info.unit) { | |||||
| case kAudioUnitParameterUnit_Hertz: | |||||
| // number of significant digits based on value | |||||
| pow10 = int(log10(fmax(inParameterValue, .000001))); | |||||
| break; | |||||
| default: | |||||
| // number of significant digits based on parameter range | |||||
| pow10 = int(log10(fmax(double(info.maxValue - info.minValue), .000001))); | |||||
| break; | |||||
| } | |||||
| // pow10 range nDigitsAfterDecimal | |||||
| // -2 .0100-.0999 4 | |||||
| // -1 .100-.999 3 | |||||
| // 0 1.00-9.99 2 | |||||
| // 1 10.0-99.9 1 | |||||
| // 2 100-999 0 | |||||
| // 3 1000-9990 -1 | |||||
| // 4 10000-99900 -2 | |||||
| int nDigitsAfterDecimal = inDigits - (pow10 + 1); | |||||
| if (nDigitsAfterDecimal < 0) | |||||
| nDigitsAfterDecimal = 0; // the least number of digits possible is zero | |||||
| if (info.flags & kAudioUnitParameterFlag_IsHighResolution) | |||||
| nDigitsAfterDecimal = 4; | |||||
| CFLocaleRef currentLocale = CFLocaleCopyCurrent(); | |||||
| CFNumberFormatterRef numberFormatter = CFNumberFormatterCreate (NULL, currentLocale, kCFNumberFormatterDecimalStyle); | |||||
| CFNumberRef maxFractionDigits = CFNumberCreate (NULL, kCFNumberIntType, &nDigitsAfterDecimal); | |||||
| if (nDigitsAfterDecimal > 0) | |||||
| nDigitsAfterDecimal = minDigits; | |||||
| CFNumberRef minFractionDigits = CFNumberCreate (NULL, kCFNumberIntType, &nDigitsAfterDecimal); | |||||
| CFNumberFormatterSetProperty (numberFormatter, kCFNumberFormatterMinFractionDigits, minFractionDigits); | |||||
| CFNumberFormatterSetProperty (numberFormatter, kCFNumberFormatterMaxFractionDigits, maxFractionDigits); | |||||
| CFStringRef formattedNumberString = CFNumberFormatterCreateStringWithValue (NULL, numberFormatter, kCFNumberDoubleType, &inParameterValue); | |||||
| CFRelease(currentLocale); | |||||
| CFRelease(numberFormatter); | |||||
| CFRelease(maxFractionDigits); | |||||
| CFRelease(minFractionDigits); | |||||
| return formattedNumberString; | |||||
| } | |||||
| CFStringRef CreateLocalizedStringForParameterValue ( double inParameterValue, | |||||
| const CAAUParameter * inParameter, | |||||
| UInt32 inDigits) { | |||||
| return CreateLocalizedStringForParameterValue (inParameterValue, inParameter, inDigits, 1); | |||||
| } | |||||
| double ValueForLocalizedParameterString (CFStringRef string, const CAAUParameter * inParameter) { | |||||
| CFLocaleRef currentLocale = CFLocaleCopyCurrent(); | |||||
| CFNumberFormatterRef numberFormatter = CFNumberFormatterCreate (NULL, currentLocale, kCFNumberFormatterDecimalStyle); | |||||
| double value = 0; | |||||
| Boolean worked = CFNumberFormatterGetValueFromString (numberFormatter, string, NULL, kCFNumberDoubleType, &value); | |||||
| CFRelease(currentLocale); | |||||
| CFRelease(numberFormatter); | |||||
| if (worked) | |||||
| return value; | |||||
| else { | |||||
| AudioUnitParameterInfo info = inParameter->ParamInfo(); | |||||
| return info.defaultValue; | |||||
| } | |||||
| } | |||||
| CFStringRef CAAUParameter::GetStringFromValueCopy(const Float32 *value) const | |||||
| { | |||||
| if (HasNamedParams()) | |||||
| { | |||||
| Float32 val = (value == NULL ? GetValue() : *value); | |||||
| int index = int(mParamInfo.minValue) + int(val); | |||||
| CFStringRef str = GetParamName (index); | |||||
| if (str) { | |||||
| CFRetain (str); | |||||
| return str; | |||||
| } | |||||
| } | |||||
| else if (ValuesHaveStrings()) | |||||
| { | |||||
| AudioUnitParameterStringFromValue stringValue; | |||||
| stringValue.inParamID = mParameterID; | |||||
| stringValue.inValue = value; | |||||
| stringValue.outString = NULL; | |||||
| UInt32 propertySize = sizeof(stringValue); | |||||
| OSStatus err = AudioUnitGetProperty (mAudioUnit, | |||||
| kAudioUnitProperty_ParameterStringFromValue, | |||||
| mScope, | |||||
| 0, | |||||
| &stringValue, | |||||
| &propertySize); | |||||
| if (!err && stringValue.outString != NULL) | |||||
| return stringValue.outString; | |||||
| } | |||||
| Float32 val = (value == NULL ? GetValue() : *value); | |||||
| AudioUnitParameterUnit unit = this->ParamInfo().unit; | |||||
| if (unit == kAudioUnitParameterUnit_Cents || unit == kAudioUnitParameterUnit_AbsoluteCents) | |||||
| return CreateLocalizedStringForParameterValue(val, this, 4, 0); | |||||
| else | |||||
| return CreateLocalizedStringForParameterValue(val, this, 4); | |||||
| } | |||||
| Float32 CAAUParameter::GetValueFromString(CFStringRef str) const | |||||
| { | |||||
| if (ValuesHaveStrings()) | |||||
| { | |||||
| AudioUnitParameterValueFromString valueString; | |||||
| valueString.inParamID = mParameterID; | |||||
| valueString.inString = str; | |||||
| UInt32 propertySize = sizeof(valueString); | |||||
| OSStatus err = AudioUnitGetProperty (mAudioUnit, | |||||
| kAudioUnitProperty_ParameterValueFromString, | |||||
| mScope, | |||||
| 0, | |||||
| &valueString, | |||||
| &propertySize); | |||||
| if (!err) { | |||||
| return valueString.outValue; | |||||
| } | |||||
| } | |||||
| return (Float32) ValueForLocalizedParameterString(str, this); | |||||
| } | |||||
| void CAAUParameter::SetValue( AUParameterListenerRef inListener, | |||||
| void * inObject, | |||||
| Float32 inValue) const | |||||
| { | |||||
| // clip inValue as: maxValue >= inValue >= minValue before setting | |||||
| Float32 valueToSet = inValue; | |||||
| if (valueToSet > mParamInfo.maxValue) | |||||
| valueToSet = mParamInfo.maxValue; | |||||
| if (valueToSet < mParamInfo.minValue) | |||||
| valueToSet = mParamInfo.minValue; | |||||
| AUParameterSet(inListener, inObject, this, valueToSet, 0); | |||||
| } | |||||
| #if DEBUG | |||||
| void CAAUParameter::Print() const | |||||
| { | |||||
| UInt32 clump = 0; | |||||
| GetClumpID (clump); | |||||
| UInt32 len = static_cast<UInt32>(CFStringGetLength(mParamName)); | |||||
| char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars | |||||
| if (!CFStringGetCString (mParamName, chars, len * 2, kCFStringEncodingUTF8)) | |||||
| chars[0] = 0; | |||||
| printf ("ID: %ld, Clump: %u, Name: %s\n", (long unsigned int) mParameterID, (unsigned int) clump, chars); | |||||
| free (chars); | |||||
| } | |||||
| #endif | |||||
| @@ -0,0 +1,191 @@ | |||||
| /* | |||||
| File: CAAUParameter.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAAUParameter_h__ | |||||
| #define __CAAUParameter_h__ | |||||
| #include <AudioToolbox/AudioUnitUtilities.h> | |||||
| // ____________________________________________________________________________ | |||||
| // CAAUParameter | |||||
| // complete parameter specification | |||||
| /*! @class CAAUParameter */ | |||||
| class CAAUParameter : public AudioUnitParameter { | |||||
| public: | |||||
| /*! @ctor CAAUParameter.0 */ | |||||
| CAAUParameter(); | |||||
| /*! @ctor CAAUParameter.1 */ | |||||
| CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element); | |||||
| /*! @ctor CAAUParameter.2 */ | |||||
| CAAUParameter(AudioUnitParameter &inParam); | |||||
| /*! @ctor CAAUParameter.3 */ | |||||
| CAAUParameter(const CAAUParameter &a); | |||||
| /*! @dtor ~CAAUParameter */ | |||||
| ~CAAUParameter(); | |||||
| /*! @method operator <@ */ | |||||
| bool operator < (const CAAUParameter &a) const | |||||
| { | |||||
| return memcmp(this, &a, sizeof(AudioUnitParameter)) < 0; | |||||
| } | |||||
| /*! @method operator ==@ */ | |||||
| bool operator == (const CAAUParameter &a) const | |||||
| { | |||||
| return !memcmp(this, &a, sizeof(AudioUnitParameter)); | |||||
| } | |||||
| /*! @method operator =@ */ | |||||
| CAAUParameter & operator = (const CAAUParameter &a); | |||||
| /*! @method GetValue */ | |||||
| Float32 GetValue() const; | |||||
| /*! @method SetValue */ | |||||
| void SetValue( AUParameterListenerRef inListener, | |||||
| void * inObject, | |||||
| Float32 inValue) const; | |||||
| /*! @method GetName */ | |||||
| CFStringRef GetName() const { return mParamName; } | |||||
| // borrowed reference! | |||||
| /*! @method GetStringFromValueCopy */ | |||||
| CFStringRef GetStringFromValueCopy(const Float32 *value = NULL) const; | |||||
| // returns a copy of the name of the current parameter value | |||||
| // or null if there is no name associated | |||||
| // caller must release | |||||
| /*! @method ValuesHaveStrings */ | |||||
| bool ValuesHaveStrings () const | |||||
| { | |||||
| return (mParamInfo.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0; | |||||
| } | |||||
| /*! @method GetValueFromString */ | |||||
| Float32 GetValueFromString (CFStringRef str) const; | |||||
| // caller must release | |||||
| /*! @method ParamInfo */ | |||||
| const AudioUnitParameterInfo & | |||||
| ParamInfo() const { return mParamInfo; } | |||||
| /*! @method GetParamTag */ | |||||
| CFStringRef GetParamTag() const { return mParamTag; } | |||||
| // this may return null! - | |||||
| // in which case there is no descriptive tag for the parameter | |||||
| /*! @method GetParamName */ | |||||
| CFStringRef GetParamName (int inIndex) const | |||||
| // this can return null if there is no name for the parameter | |||||
| { | |||||
| return (mNamedParams && inIndex < mNumIndexedParams) | |||||
| ? (CFStringRef) CFArrayGetValueAtIndex(mNamedParams, inIndex) | |||||
| : 0; | |||||
| } | |||||
| /*! @method GetNumIndexedParams */ | |||||
| int GetNumIndexedParams () const { return mNumIndexedParams; } | |||||
| /*! @method IsIndexedParam */ | |||||
| bool IsIndexedParam () const { return mNumIndexedParams != 0; } | |||||
| /*! @method HasNamedParams */ | |||||
| bool HasNamedParams () const { return IsIndexedParam() && mNamedParams; } | |||||
| /*! @method GetClumpID */ | |||||
| bool GetClumpID (UInt32 &outClumpID) const | |||||
| { | |||||
| if (mParamInfo.flags & kAudioUnitParameterFlag_HasClump) { | |||||
| outClumpID = mParamInfo.clumpID; | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| /*! @method HasDisplayTransformation */ | |||||
| bool HasDisplayTransformation () const | |||||
| { | |||||
| return GetAudioUnitParameterDisplayType (mParamInfo.flags); | |||||
| } | |||||
| /*! @method IsExpert */ | |||||
| bool IsExpert () const | |||||
| { | |||||
| return mParamInfo.flags & kAudioUnitParameterFlag_ExpertMode; | |||||
| } | |||||
| #if DEBUG | |||||
| void Print () const; | |||||
| #endif | |||||
| // these methods are defined in CAPersistence.cpp | |||||
| // they will persist and restore only the scope, element and param ID's of the AudioUnitParameter | |||||
| // however, this is sufficient to be able to save/restore a CAAUParameter object | |||||
| void Save (CFPropertyListRef &outData) const; | |||||
| static void Save (const AudioUnitParameter &inParam, CFPropertyListRef &outData); | |||||
| static OSStatus Restore (const CFPropertyListRef inData, AudioUnitParameter &outParam); | |||||
| protected: | |||||
| // cached parameter info | |||||
| /*! @var mParamInfo */ | |||||
| AudioUnitParameterInfo mParamInfo; | |||||
| /*! @var mParamName */ | |||||
| CFStringRef mParamName; | |||||
| /*! @var mParamTag */ | |||||
| CFStringRef mParamTag; | |||||
| /*! @var mNumIndexedParams */ | |||||
| short mNumIndexedParams; | |||||
| /*! @var mNamedParams */ | |||||
| CFArrayRef mNamedParams; | |||||
| private: | |||||
| void Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element); | |||||
| }; | |||||
| #endif // __CAAUParameter_h__ | |||||
| @@ -0,0 +1,305 @@ | |||||
| /* | |||||
| File: CAAtomic.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| /* | |||||
| This file implements all Atomic operations using Interlocked functions specified in | |||||
| Winbase.h | |||||
| NOTE: According to Microsoft documentation, all Interlocked functions generates a | |||||
| full barrier. | |||||
| On Windows: | |||||
| As the Interlocked functions returns the Old value, Extra checks and operations | |||||
| are made after the atomic operation to return value consistent with OSX counterparts. | |||||
| */ | |||||
| #ifndef __CAAtomic_h__ | |||||
| #define __CAAtomic_h__ | |||||
| #if TARGET_OS_WIN32 | |||||
| #include <windows.h> | |||||
| #include <intrin.h> | |||||
| #pragma intrinsic(_InterlockedOr) | |||||
| #pragma intrinsic(_InterlockedAnd) | |||||
| #else | |||||
| #include <CoreFoundation/CFBase.h> | |||||
| #include <libkern/OSAtomic.h> | |||||
| #endif | |||||
| inline void CAMemoryBarrier() | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| MemoryBarrier(); | |||||
| #else | |||||
| OSMemoryBarrier(); | |||||
| #endif | |||||
| } | |||||
| inline SInt32 CAAtomicAdd32Barrier(SInt32 theAmt, volatile SInt32* theValue) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| long lRetVal = InterlockedExchangeAdd((volatile long*)theValue, theAmt); | |||||
| // InterlockedExchangeAdd returns the original value which differs from OSX version. | |||||
| // At this point the addition would have occured and hence returning the new value | |||||
| // to keep it sync with OSX. | |||||
| return lRetVal + theAmt; | |||||
| #else | |||||
| return OSAtomicAdd32Barrier(theAmt, (volatile int32_t *)theValue); | |||||
| #endif | |||||
| } | |||||
| inline SInt32 CAAtomicOr32Barrier(UInt32 theMask, volatile UInt32* theValue) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| // InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic | |||||
| // function instead. | |||||
| long j = _InterlockedOr((volatile long*)theValue, theMask); | |||||
| // _InterlockedOr returns the original value which differs from OSX version. | |||||
| // Returning the new value similar to OSX | |||||
| return (SInt32)(j | theMask); | |||||
| #else | |||||
| return OSAtomicOr32Barrier(theMask, (volatile uint32_t *)theValue); | |||||
| #endif | |||||
| } | |||||
| inline SInt32 CAAtomicAnd32Barrier(UInt32 theMask, volatile UInt32* theValue) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| // InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic | |||||
| // function instead. | |||||
| long j = _InterlockedAnd((volatile long*)theValue, theMask); | |||||
| // _InterlockedAnd returns the original value which differs from OSX version. | |||||
| // Returning the new value similar to OSX | |||||
| return (SInt32)(j & theMask); | |||||
| #else | |||||
| return OSAtomicAnd32Barrier(theMask, (volatile uint32_t *)theValue); | |||||
| #endif | |||||
| } | |||||
| inline bool CAAtomicCompareAndSwap32Barrier(SInt32 oldValue, SInt32 newValue, volatile SInt32 *theValue) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| // InterlockedCompareExchange returns the old value. But we need to return bool value. | |||||
| long lRetVal = InterlockedCompareExchange((volatile long*)theValue, newValue, oldValue); | |||||
| // Hence we check if the new value is set and if it is we return true else false. | |||||
| // If theValue is equal to oldValue then the swap happens. Otherwise swap doesn't happen. | |||||
| return (oldValue == lRetVal); | |||||
| #else | |||||
| return OSAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile int32_t *)theValue); | |||||
| #endif | |||||
| } | |||||
| inline SInt32 CAAtomicIncrement32(volatile SInt32* theValue) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| return (SInt32)InterlockedIncrement((volatile long*)theValue); | |||||
| #else | |||||
| return OSAtomicIncrement32((volatile int32_t *)theValue); | |||||
| #endif | |||||
| } | |||||
| inline SInt32 CAAtomicDecrement32(volatile SInt32* theValue) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| return (SInt32)InterlockedDecrement((volatile long*)theValue); | |||||
| #else | |||||
| return OSAtomicDecrement32((volatile int32_t *)theValue); | |||||
| #endif | |||||
| } | |||||
| inline SInt32 CAAtomicIncrement32Barrier(volatile SInt32* theValue) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| return CAAtomicIncrement32(theValue); | |||||
| #else | |||||
| return OSAtomicIncrement32Barrier((volatile int32_t *)theValue); | |||||
| #endif | |||||
| } | |||||
| inline SInt32 CAAtomicDecrement32Barrier(volatile SInt32* theValue) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| return CAAtomicDecrement32(theValue); | |||||
| #else | |||||
| return OSAtomicDecrement32Barrier((volatile int32_t *)theValue); | |||||
| #endif | |||||
| } | |||||
| inline bool CAAtomicTestAndClearBarrier(int bitToClear, void* theAddress) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| BOOL bOldVal = InterlockedBitTestAndReset((long*)theAddress, bitToClear); | |||||
| return (bOldVal ? true : false); | |||||
| #else | |||||
| return OSAtomicTestAndClearBarrier(bitToClear, (volatile void *)theAddress); | |||||
| #endif | |||||
| } | |||||
| inline bool CAAtomicTestAndClear(int bitToClear, void* theAddress) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| BOOL bOldVal = CAAtomicTestAndClearBarrier(bitToClear, (long*)theAddress); | |||||
| return (bOldVal ? true : false); | |||||
| #else | |||||
| return OSAtomicTestAndClear(bitToClear, (volatile void *)theAddress); | |||||
| #endif | |||||
| } | |||||
| inline bool CAAtomicTestAndSetBarrier(int bitToSet, void* theAddress) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| BOOL bOldVal = InterlockedBitTestAndSet((long*)theAddress, bitToSet); | |||||
| return (bOldVal ? true : false); | |||||
| #else | |||||
| return OSAtomicTestAndSetBarrier(bitToSet, (volatile void *)theAddress); | |||||
| #endif | |||||
| } | |||||
| // int32_t flavors -- for C++ only since we can't overload in C | |||||
| // CFBase.h defines SInt32 as signed int which is similar to int32_t. If CFBase.h is included, then | |||||
| // this will generate redefinition error. But on Mac, CFBase.h, still includes MacTypes.h where | |||||
| // SInt32 is defined as signed long so this would work there. | |||||
| // So in order to fix the redefinition errors, we define these functions only if MacTypes.h is included. | |||||
| #if defined(__cplusplus) && defined(__MACTYPES__) && !__LP64__ | |||||
| inline int32_t CAAtomicAdd32Barrier(int32_t theAmt, volatile int32_t* theValue) | |||||
| { | |||||
| return CAAtomicAdd32Barrier(theAmt, (volatile SInt32 *)theValue); | |||||
| } | |||||
| inline int32_t CAAtomicOr32Barrier(uint32_t theMask, volatile uint32_t* theValue) | |||||
| { | |||||
| return CAAtomicOr32Barrier(theMask, (volatile UInt32 *)theValue); | |||||
| } | |||||
| inline int32_t CAAtomicAnd32Barrier(uint32_t theMask, volatile uint32_t* theValue) | |||||
| { | |||||
| return CAAtomicAnd32Barrier(theMask, (volatile UInt32 *)theValue); | |||||
| } | |||||
| inline bool CAAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatile int32_t *theValue) | |||||
| { | |||||
| return CAAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile SInt32 *)theValue); | |||||
| } | |||||
| inline int32_t CAAtomicIncrement32(volatile int32_t* theValue) | |||||
| { | |||||
| return CAAtomicIncrement32((volatile SInt32 *)theValue); | |||||
| } | |||||
| inline int32_t CAAtomicDecrement32(volatile int32_t* theValue) | |||||
| { | |||||
| return CAAtomicDecrement32((volatile SInt32 *)theValue); | |||||
| } | |||||
| inline int32_t CAAtomicIncrement32Barrier(volatile int32_t* theValue) | |||||
| { | |||||
| return CAAtomicIncrement32Barrier((volatile SInt32 *)theValue); | |||||
| } | |||||
| inline int32_t CAAtomicDecrement32Barrier(volatile int32_t* theValue) | |||||
| { | |||||
| return CAAtomicDecrement32Barrier((volatile SInt32 *)theValue); | |||||
| } | |||||
| #endif // __cplusplus && !__LP64__ | |||||
| #if __LP64__ | |||||
| inline bool CAAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ) | |||||
| { | |||||
| return OSAtomicCompareAndSwap64Barrier(__oldValue, __newValue, __theValue); | |||||
| } | |||||
| #endif | |||||
| inline bool CAAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, volatile void ** __theValue) | |||||
| { | |||||
| #if __LP64__ | |||||
| return CAAtomicCompareAndSwap64Barrier((int64_t)__oldValue, (int64_t)__newValue, (int64_t *)__theValue); | |||||
| #else | |||||
| return CAAtomicCompareAndSwap32Barrier((int32_t)__oldValue, (int32_t)__newValue, (int32_t *)__theValue); | |||||
| #endif | |||||
| } | |||||
| /* Spinlocks. These use memory barriers as required to synchronize access to shared | |||||
| * memory protected by the lock. The lock operation spins, but employs various strategies | |||||
| * to back off if the lock is held, making it immune to most priority-inversion livelocks. | |||||
| * The try operation immediately returns false if the lock was held, true if it took the | |||||
| * lock. The convention is that unlocked is zero, locked is nonzero. | |||||
| */ | |||||
| #define CA_SPINLOCK_INIT 0 | |||||
| typedef int32_t CASpinLock; | |||||
| bool CASpinLockTry( volatile CASpinLock *__lock ); | |||||
| void CASpinLockLock( volatile CASpinLock *__lock ); | |||||
| void CASpinLockUnlock( volatile CASpinLock *__lock ); | |||||
| inline void CASpinLockLock( volatile CASpinLock *__lock ) | |||||
| { | |||||
| #if TARGET_OS_MAC | |||||
| OSSpinLockLock(__lock); | |||||
| #else | |||||
| while (CAAtomicTestAndSetBarrier(0, (void*)__lock)) | |||||
| usleep(1000); // ??? | |||||
| #endif | |||||
| } | |||||
| inline void CASpinLockUnlock( volatile CASpinLock *__lock ) | |||||
| { | |||||
| #if TARGET_OS_MAC | |||||
| OSSpinLockUnlock(__lock); | |||||
| #else | |||||
| CAAtomicTestAndClearBarrier(0, (void*)__lock); | |||||
| #endif | |||||
| } | |||||
| inline bool CASpinLockTry( volatile CASpinLock *__lock ) | |||||
| { | |||||
| #if TARGET_OS_MAC | |||||
| return OSSpinLockTry(__lock); | |||||
| #else | |||||
| return (CAAtomicTestAndSetBarrier(0, (void*)__lock) == 0); | |||||
| #endif | |||||
| } | |||||
| #endif // __CAAtomic_h__ | |||||
| @@ -0,0 +1,239 @@ | |||||
| /* | |||||
| File: CAAtomicStack.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAAtomicStack_h__ | |||||
| #define __CAAtomicStack_h__ | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <libkern/OSAtomic.h> | |||||
| #else | |||||
| #include <CAAtomic.h> | |||||
| #endif | |||||
| #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4 | |||||
| #include <CoreServices/CoreServices.h> | |||||
| #endif | |||||
| // linked list LIFO or FIFO (pop_all_reversed) stack, elements are pushed and popped atomically | |||||
| // class T must implement T *& next(). | |||||
| template <class T> | |||||
| class TAtomicStack { | |||||
| public: | |||||
| TAtomicStack() : mHead(NULL) { } | |||||
| // non-atomic routines, for use when initializing/deinitializing, operate NON-atomically | |||||
| void push_NA(T *item) | |||||
| { | |||||
| item->next() = mHead; | |||||
| mHead = item; | |||||
| } | |||||
| T * pop_NA() | |||||
| { | |||||
| T *result = mHead; | |||||
| if (result) | |||||
| mHead = result->next(); | |||||
| return result; | |||||
| } | |||||
| bool empty() const { return mHead == NULL; } | |||||
| T * head() { return mHead; } | |||||
| // atomic routines | |||||
| void push_atomic(T *item) | |||||
| { | |||||
| T *head_; | |||||
| do { | |||||
| head_ = mHead; | |||||
| item->next() = head_; | |||||
| } while (!compare_and_swap(head_, item, &mHead)); | |||||
| } | |||||
| void push_multiple_atomic(T *item) | |||||
| // pushes entire linked list headed by item | |||||
| { | |||||
| T *head_, *p = item, *tail; | |||||
| // find the last one -- when done, it will be linked to head | |||||
| do { | |||||
| tail = p; | |||||
| p = p->next(); | |||||
| } while (p); | |||||
| do { | |||||
| head_ = mHead; | |||||
| tail->next() = head_; | |||||
| } while (!compare_and_swap(head_, item, &mHead)); | |||||
| } | |||||
| T * pop_atomic_single_reader() | |||||
| // this may only be used when only one thread may potentially pop from the stack. | |||||
| // if multiple threads may pop, this suffers from the ABA problem. | |||||
| // <rdar://problem/4606346> TAtomicStack suffers from the ABA problem | |||||
| { | |||||
| T *result; | |||||
| do { | |||||
| if ((result = mHead) == NULL) | |||||
| break; | |||||
| } while (!compare_and_swap(result, result->next(), &mHead)); | |||||
| return result; | |||||
| } | |||||
| T * pop_atomic() | |||||
| // This is inefficient for large linked lists. | |||||
| // prefer pop_all() to a series of calls to pop_atomic. | |||||
| // push_multiple_atomic has to traverse the entire list. | |||||
| { | |||||
| T *result = pop_all(); | |||||
| if (result) { | |||||
| T *next = result->next(); | |||||
| if (next) | |||||
| // push all the remaining items back onto the stack | |||||
| push_multiple_atomic(next); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| T * pop_all() | |||||
| { | |||||
| T *result; | |||||
| do { | |||||
| if ((result = mHead) == NULL) | |||||
| break; | |||||
| } while (!compare_and_swap(result, NULL, &mHead)); | |||||
| return result; | |||||
| } | |||||
| T* pop_all_reversed() | |||||
| { | |||||
| TAtomicStack<T> reversed; | |||||
| T *p = pop_all(), *next; | |||||
| while (p != NULL) { | |||||
| next = p->next(); | |||||
| reversed.push_NA(p); | |||||
| p = next; | |||||
| } | |||||
| return reversed.mHead; | |||||
| } | |||||
| static bool compare_and_swap(T *oldvalue, T *newvalue, T **pvalue) | |||||
| { | |||||
| #if TARGET_OS_MAC | |||||
| #if __LP64__ | |||||
| return ::OSAtomicCompareAndSwap64Barrier(int64_t(oldvalue), int64_t(newvalue), (int64_t *)pvalue); | |||||
| #elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 | |||||
| return ::OSAtomicCompareAndSwap32Barrier(int32_t(oldvalue), int32_t(newvalue), (int32_t *)pvalue); | |||||
| #else | |||||
| return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue); | |||||
| #endif | |||||
| #else | |||||
| //return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue); | |||||
| return CAAtomicCompareAndSwap32Barrier(SInt32(oldvalue), SInt32(newvalue), (SInt32*)pvalue); | |||||
| #endif | |||||
| } | |||||
| protected: | |||||
| T * mHead; | |||||
| }; | |||||
| #if ((MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) && !TARGET_OS_WIN32) | |||||
| #include <libkern/OSAtomic.h> | |||||
| class CAAtomicStack { | |||||
| public: | |||||
| CAAtomicStack(size_t nextPtrOffset) : mNextPtrOffset(nextPtrOffset) { | |||||
| /*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/ | |||||
| mHead.opaque1 = 0; mHead.opaque2 = 0; | |||||
| } | |||||
| // a subset of the above | |||||
| void push_atomic(void *p) { OSAtomicEnqueue(&mHead, p, mNextPtrOffset); } | |||||
| void push_NA(void *p) { push_atomic(p); } | |||||
| void * pop_atomic() { return OSAtomicDequeue(&mHead, mNextPtrOffset); } | |||||
| void * pop_atomic_single_reader() { return pop_atomic(); } | |||||
| void * pop_NA() { return pop_atomic(); } | |||||
| private: | |||||
| OSQueueHead mHead; | |||||
| size_t mNextPtrOffset; | |||||
| }; | |||||
| // a more efficient subset of TAtomicStack using OSQueue. | |||||
| template <class T> | |||||
| class TAtomicStack2 { | |||||
| public: | |||||
| TAtomicStack2() { | |||||
| /*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/ | |||||
| mHead.opaque1 = 0; mHead.opaque2 = 0; | |||||
| mNextPtrOffset = -1; | |||||
| } | |||||
| void push_atomic(T *item) { | |||||
| if (mNextPtrOffset < 0) { | |||||
| T **pnext = &item->next(); // hack around offsetof not working with C++ | |||||
| mNextPtrOffset = (Byte *)pnext - (Byte *)item; | |||||
| } | |||||
| OSAtomicEnqueue(&mHead, item, mNextPtrOffset); | |||||
| } | |||||
| void push_NA(T *item) { push_atomic(item); } | |||||
| T * pop_atomic() { return (T *)OSAtomicDequeue(&mHead, mNextPtrOffset); } | |||||
| T * pop_atomic_single_reader() { return pop_atomic(); } | |||||
| T * pop_NA() { return pop_atomic(); } | |||||
| // caution: do not try to implement pop_all_reversed here. the writer could add new elements | |||||
| // while the reader is trying to pop old ones! | |||||
| private: | |||||
| OSQueueHead mHead; | |||||
| ssize_t mNextPtrOffset; | |||||
| }; | |||||
| #else | |||||
| #define TAtomicStack2 TAtomicStack | |||||
| #endif // MAC_OS_X_VERSION_MAX_ALLOWED && !TARGET_OS_WIN32 | |||||
| #endif // __CAAtomicStack_h__ | |||||
| @@ -0,0 +1,153 @@ | |||||
| /* | |||||
| File: CAAudioChannelLayout.cpp | |||||
| Abstract: CAAudioChannelLayout.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| //============================================================================= | |||||
| // Includes | |||||
| //============================================================================= | |||||
| // Self Include | |||||
| #include "CAAudioChannelLayout.h" | |||||
| #include "CAAutoDisposer.h" | |||||
| #include <stdlib.h> | |||||
| #include <string.h> | |||||
| //============================================================================= | |||||
| // CAAudioChannelLayout | |||||
| //============================================================================= | |||||
| AudioChannelLayout* CAAudioChannelLayout::Create(UInt32 inNumberChannelDescriptions) | |||||
| { | |||||
| UInt32 theSize = CalculateByteSize(inNumberChannelDescriptions); | |||||
| AudioChannelLayout* theAnswer = static_cast<AudioChannelLayout*>(CA_calloc(1, theSize)); | |||||
| if(theAnswer != NULL) | |||||
| { | |||||
| SetAllToUnknown(*theAnswer, inNumberChannelDescriptions); | |||||
| } | |||||
| return theAnswer; | |||||
| } | |||||
| void CAAudioChannelLayout::Destroy(AudioChannelLayout* inChannelLayout) | |||||
| { | |||||
| free(inChannelLayout); | |||||
| } | |||||
| void CAAudioChannelLayout::SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions) | |||||
| { | |||||
| outChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions; | |||||
| outChannelLayout.mChannelBitmap = 0; | |||||
| outChannelLayout.mNumberChannelDescriptions = inNumberChannelDescriptions; | |||||
| for(UInt32 theChannelIndex = 0; theChannelIndex < inNumberChannelDescriptions; ++theChannelIndex) | |||||
| { | |||||
| outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelLabel = kAudioChannelLabel_Unknown; | |||||
| outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelFlags = 0; | |||||
| outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[0] = 0; | |||||
| outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[1] = 0; | |||||
| outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[2] = 0; | |||||
| } | |||||
| } | |||||
| bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y) | |||||
| { | |||||
| // compare based on the number of channel descriptions present | |||||
| // (this may be too strict a comparison if all you care about are matching layout tags) | |||||
| UInt32 theSize1 = CAAudioChannelLayout::CalculateByteSize(x.mNumberChannelDescriptions); | |||||
| UInt32 theSize2 = CAAudioChannelLayout::CalculateByteSize(y.mNumberChannelDescriptions); | |||||
| if (theSize1 != theSize2) | |||||
| return false; | |||||
| return !memcmp (&x, &y, theSize1); | |||||
| } | |||||
| bool operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y) | |||||
| { | |||||
| return !(x == y); | |||||
| } | |||||
| // counting the one bits in a word | |||||
| inline UInt32 CountOnes(UInt32 x) | |||||
| { | |||||
| // secret magic algorithm for counting bits in a word. | |||||
| UInt32 t; | |||||
| x = x - ((x >> 1) & 0x55555555); | |||||
| t = ((x >> 2) & 0x33333333); | |||||
| x = (x & 0x33333333) + t; | |||||
| x = (x + (x >> 4)) & 0x0F0F0F0F; | |||||
| x = x + (x << 8); | |||||
| x = x + (x << 16); | |||||
| return x >> 24; | |||||
| } | |||||
| UInt32 CAAudioChannelLayout::NumberChannels (const AudioChannelLayout& inLayout) | |||||
| { | |||||
| if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) | |||||
| return inLayout.mNumberChannelDescriptions; | |||||
| if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) | |||||
| return CountOnes (inLayout.mChannelBitmap); | |||||
| return AudioChannelLayoutTag_GetNumberOfChannels(inLayout.mChannelLayoutTag); | |||||
| } | |||||
| void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout) | |||||
| { | |||||
| if (layout == NULL) | |||||
| { | |||||
| fprintf (file, "\tNULL layout\n"); | |||||
| return; | |||||
| } | |||||
| fprintf (file, "\tTag=0x%X, ", (int)layout->mChannelLayoutTag); | |||||
| if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) | |||||
| fprintf (file, "Using Bitmap:0x%X\n", (int)layout->mChannelBitmap); | |||||
| else { | |||||
| fprintf (file, "Num Chan Descs=%d\n", (int)layout->mNumberChannelDescriptions); | |||||
| const AudioChannelDescription *desc = layout->mChannelDescriptions; | |||||
| for (unsigned int i = 0; i < layout->mNumberChannelDescriptions; ++i, ++desc) { | |||||
| fprintf (file, "\t\tLabel=%d, Flags=0x%X, ", (int)desc->mChannelLabel, (int)desc->mChannelFlags); | |||||
| fprintf (file, "[az=%f,el=%f,dist=%f]\n", desc->mCoordinates[0], desc->mCoordinates[1], desc->mCoordinates[2]); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,199 @@ | |||||
| /* | |||||
| File: CAAudioChannelLayout.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #if !defined(__CAAudioChannelLayout_h__) | |||||
| #define __CAAudioChannelLayout_h__ | |||||
| //============================================================================= | |||||
| // Includes | |||||
| //============================================================================= | |||||
| // System Includes | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreAudio/CoreAudioTypes.h> | |||||
| #include <CoreFoundation/CoreFoundation.h> | |||||
| #else | |||||
| #include <CoreAudioTypes.h> | |||||
| #include <CoreFoundation.h> | |||||
| #endif | |||||
| #include <stdio.h> | |||||
| #include <stdlib.h> | |||||
| #include <string.h> | |||||
| #include "CADebugMacros.h" | |||||
| #include "CAAutoDisposer.h" | |||||
| #if !HAL_Build | |||||
| #include "CAReferenceCounted.h" | |||||
| #endif | |||||
| //============================================================================= | |||||
| // CAAudioChannelLayout | |||||
| //============================================================================= | |||||
| bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y); | |||||
| bool operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y); | |||||
| extern "C" void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout); | |||||
| class CAAudioChannelLayout | |||||
| { | |||||
| // static Construction/Destruction | |||||
| public: | |||||
| static AudioChannelLayout* Create(UInt32 inNumberChannelDescriptions); | |||||
| static void Destroy(AudioChannelLayout* inChannelLayout); | |||||
| static UInt32 CalculateByteSize(UInt32 inNumberChannelDescriptions) { | |||||
| return SizeOf32(AudioChannelLayout) - SizeOf32(AudioChannelDescription) + (inNumberChannelDescriptions * SizeOf32(AudioChannelDescription)); | |||||
| } | |||||
| static void SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions); | |||||
| static UInt32 NumberChannels(const AudioChannelLayout& inLayout); | |||||
| #if !HAL_Build | |||||
| // object methods | |||||
| public: | |||||
| CAAudioChannelLayout (); | |||||
| CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround); | |||||
| // if inChooseSurround is false, then symmetrical speaker arrangements | |||||
| // are chosen in place of surround layouts if there is a choice | |||||
| // This call chooses layouts based on the expected defaults in | |||||
| // AudioUnit usage | |||||
| CAAudioChannelLayout (AudioChannelLayoutTag inTag); | |||||
| CAAudioChannelLayout (const CAAudioChannelLayout &c); | |||||
| CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout); | |||||
| ~CAAudioChannelLayout(); | |||||
| CAAudioChannelLayout& operator= (const AudioChannelLayout* inChannelLayout); | |||||
| CAAudioChannelLayout& operator= (const CAAudioChannelLayout& c); | |||||
| bool operator== (const CAAudioChannelLayout &c) const; | |||||
| bool operator!= (const CAAudioChannelLayout &c) const; | |||||
| void SetWithTag(AudioChannelLayoutTag inTag); | |||||
| bool IsValid() const { return NumberChannels() > 0; } | |||||
| UInt32 Size() const { return mLayout ? mLayout->Size() : 0; } | |||||
| UInt32 NumberChannels() const { return mLayout ? mLayout->NumberChannels() : 0; } | |||||
| AudioChannelLayoutTag Tag() const { return Layout().mChannelLayoutTag; } | |||||
| const AudioChannelLayout& Layout() const { return mLayout->Layout(); } | |||||
| operator const AudioChannelLayout *() const { return &Layout(); } | |||||
| void Print () const { Print (stdout); } | |||||
| void Print (FILE* file) const; | |||||
| OSStatus Save (CFPropertyListRef *outData) const; | |||||
| OSStatus Restore (CFPropertyListRef &inData); | |||||
| private: | |||||
| class RefCountedLayout : public CAReferenceCounted { | |||||
| void * operator new(size_t /* size */, size_t aclSize) | |||||
| { | |||||
| return CA_malloc(sizeof(RefCountedLayout) - sizeof(AudioChannelLayout) + aclSize); | |||||
| } | |||||
| void operator delete(void *mem) | |||||
| { | |||||
| free(mem); | |||||
| } | |||||
| RefCountedLayout(UInt32 inDataSize) : | |||||
| mByteSize(inDataSize) | |||||
| { | |||||
| memset(&mACL, 0, inDataSize); | |||||
| } | |||||
| public: | |||||
| static RefCountedLayout *CreateWithNumberChannelDescriptions(unsigned nChannels) { | |||||
| size_t size = CAAudioChannelLayout::CalculateByteSize(nChannels); | |||||
| return new(size) RefCountedLayout((UInt32)size); | |||||
| } | |||||
| static RefCountedLayout *CreateWithLayout(const AudioChannelLayout *layout) { | |||||
| size_t size = CAAudioChannelLayout::CalculateByteSize(layout->mNumberChannelDescriptions); | |||||
| RefCountedLayout *acl = new(size) RefCountedLayout((UInt32)size); | |||||
| memcpy(&acl->mACL, layout, size); | |||||
| return acl; | |||||
| } | |||||
| static RefCountedLayout *CreateWithLayoutTag(AudioChannelLayoutTag layoutTag) { | |||||
| RefCountedLayout *acl = CreateWithNumberChannelDescriptions(0); | |||||
| acl->mACL.mChannelLayoutTag = layoutTag; | |||||
| return acl; | |||||
| } | |||||
| const AudioChannelLayout & Layout() const { return mACL; } | |||||
| UInt32 Size () const { return mByteSize; } | |||||
| UInt32 NumberChannels() { return CAAudioChannelLayout::NumberChannels(Layout()); } | |||||
| private: | |||||
| const UInt32 mByteSize; | |||||
| AudioChannelLayout mACL; | |||||
| // * * * mACL is variable length and thus must be last * * * | |||||
| // only the constructors can change the actual state of the layout | |||||
| friend CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround); | |||||
| friend OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData); | |||||
| friend CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout); | |||||
| friend void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag); | |||||
| AudioChannelLayout * GetLayout() { return &mACL; } | |||||
| private: | |||||
| // prohibited methods: private and unimplemented. | |||||
| RefCountedLayout(); | |||||
| RefCountedLayout(const RefCountedLayout& c); | |||||
| RefCountedLayout& operator=(const RefCountedLayout& c); | |||||
| }; | |||||
| RefCountedLayout *mLayout; | |||||
| #endif // HAL_Build | |||||
| }; | |||||
| #endif | |||||
| @@ -0,0 +1,508 @@ | |||||
| /* | |||||
| File: CAAutoDisposer.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #if !defined(__CAPtr_h__) | |||||
| #define __CAPtr_h__ | |||||
| #include <stdlib.h> // for malloc | |||||
| #include <new> // for bad_alloc | |||||
| #include <string.h> // for memset | |||||
| inline void* CA_malloc(size_t size) | |||||
| { | |||||
| void* p = malloc(size); | |||||
| if (!p && size) throw std::bad_alloc(); | |||||
| return p; | |||||
| } | |||||
| inline void* CA_realloc(void* old, size_t size) | |||||
| { | |||||
| #if TARGET_OS_WIN32 | |||||
| void* p = realloc(old, size); | |||||
| #else | |||||
| void* p = reallocf(old, size); // reallocf ensures the old pointer is freed if memory is full (p is NULL). | |||||
| #endif | |||||
| if (!p && size) throw std::bad_alloc(); | |||||
| return p; | |||||
| } | |||||
| #ifndef UINTPTR_MAX | |||||
| #if __LP64__ | |||||
| #define UINTPTR_MAX 18446744073709551615ULL | |||||
| #else | |||||
| #define UINTPTR_MAX 4294967295U | |||||
| #endif | |||||
| #endif | |||||
| inline void* CA_calloc(size_t n, size_t size) | |||||
| { | |||||
| // ensure that multiplication will not overflow | |||||
| if (n && UINTPTR_MAX / n < size) throw std::bad_alloc(); | |||||
| size_t nsize = n*size; | |||||
| void* p = malloc(nsize); | |||||
| if (!p && nsize) throw std::bad_alloc(); | |||||
| memset(p, 0, nsize); | |||||
| return p; | |||||
| } | |||||
| // helper class for automatic conversions | |||||
| template <typename T> | |||||
| struct CAPtrRef | |||||
| { | |||||
| T* ptr_; | |||||
| explicit CAPtrRef(T* ptr) : ptr_(ptr) {} | |||||
| }; | |||||
| template <typename T> | |||||
| class CAAutoFree | |||||
| { | |||||
| private: | |||||
| T* ptr_; | |||||
| public: | |||||
| CAAutoFree() : ptr_(0) {} | |||||
| explicit CAAutoFree(T* ptr) : ptr_(ptr) {} | |||||
| template<typename U> | |||||
| CAAutoFree(CAAutoFree<U>& that) : ptr_(that.release()) {} // take ownership | |||||
| // C++ std says: a template constructor is never a copy constructor | |||||
| CAAutoFree(CAAutoFree<T>& that) : ptr_(that.release()) {} // take ownership | |||||
| CAAutoFree(size_t n, bool clear = false) | |||||
| // this becomes an ambiguous call if n == 0 | |||||
| : ptr_(0) | |||||
| { | |||||
| size_t maxItems = ~size_t(0) / sizeof(T); | |||||
| if (n > maxItems) | |||||
| throw std::bad_alloc(); | |||||
| ptr_ = static_cast<T*>(clear ? CA_calloc(n, sizeof(T)) : CA_malloc(n * sizeof(T))); | |||||
| } | |||||
| ~CAAutoFree() { free(); } | |||||
| void alloc(size_t numItems, bool clear = false) | |||||
| { | |||||
| size_t maxItems = ~size_t(0) / sizeof(T); | |||||
| if (numItems > maxItems) throw std::bad_alloc(); | |||||
| free(); | |||||
| ptr_ = static_cast<T*>(clear ? CA_calloc(numItems, sizeof(T)) : CA_malloc(numItems * sizeof(T))); | |||||
| } | |||||
| void allocBytes(size_t numBytes, bool clear = false) | |||||
| { | |||||
| free(); | |||||
| ptr_ = static_cast<T*>(clear ? CA_calloc(1, numBytes) : CA_malloc(numBytes)); | |||||
| } | |||||
| void reallocBytes(size_t numBytes) | |||||
| { | |||||
| ptr_ = static_cast<T*>(CA_realloc(ptr_, numBytes)); | |||||
| } | |||||
| void reallocItems(size_t numItems) | |||||
| { | |||||
| size_t maxItems = ~size_t(0) / sizeof(T); | |||||
| if (numItems > maxItems) throw std::bad_alloc(); | |||||
| ptr_ = static_cast<T*>(CA_realloc(ptr_, numItems * sizeof(T))); | |||||
| } | |||||
| template <typename U> | |||||
| CAAutoFree& operator=(CAAutoFree<U>& that) | |||||
| { | |||||
| set(that.release()); // take ownership | |||||
| return *this; | |||||
| } | |||||
| CAAutoFree& operator=(CAAutoFree& that) | |||||
| { | |||||
| set(that.release()); // take ownership | |||||
| return *this; | |||||
| } | |||||
| CAAutoFree& operator=(T* ptr) | |||||
| { | |||||
| set(ptr); | |||||
| return *this; | |||||
| } | |||||
| template <typename U> | |||||
| CAAutoFree& operator=(U* ptr) | |||||
| { | |||||
| set(ptr); | |||||
| return *this; | |||||
| } | |||||
| T& operator*() const { return *ptr_; } | |||||
| T* operator->() const { return ptr_; } | |||||
| T* operator()() const { return ptr_; } | |||||
| T* get() const { return ptr_; } | |||||
| operator T*() const { return ptr_; } | |||||
| bool operator==(CAAutoFree const& that) const { return ptr_ == that.ptr_; } | |||||
| bool operator!=(CAAutoFree const& that) const { return ptr_ != that.ptr_; } | |||||
| bool operator==(T* ptr) const { return ptr_ == ptr; } | |||||
| bool operator!=(T* ptr) const { return ptr_ != ptr; } | |||||
| T* release() | |||||
| { | |||||
| // release ownership | |||||
| T* result = ptr_; | |||||
| ptr_ = 0; | |||||
| return result; | |||||
| } | |||||
| void set(T* ptr) | |||||
| { | |||||
| if (ptr != ptr_) | |||||
| { | |||||
| ::free(ptr_); | |||||
| ptr_ = ptr; | |||||
| } | |||||
| } | |||||
| void free() | |||||
| { | |||||
| set(0); | |||||
| } | |||||
| // automatic conversions to allow assignment from results of functions. | |||||
| // hard to explain. see auto_ptr implementation and/or Josuttis' STL book. | |||||
| CAAutoFree(CAPtrRef<T> ref) : ptr_(ref.ptr_) { } | |||||
| CAAutoFree& operator=(CAPtrRef<T> ref) | |||||
| { | |||||
| set(ref.ptr_); | |||||
| return *this; | |||||
| } | |||||
| template<typename U> | |||||
| operator CAPtrRef<U>() | |||||
| { return CAPtrRef<U>(release()); } | |||||
| template<typename U> | |||||
| operator CAAutoFree<U>() | |||||
| { return CAAutoFree<U>(release()); } | |||||
| }; | |||||
| template <typename T> | |||||
| class CAAutoDelete | |||||
| { | |||||
| private: | |||||
| T* ptr_; | |||||
| public: | |||||
| CAAutoDelete() : ptr_(0) {} | |||||
| explicit CAAutoDelete(T* ptr) : ptr_(ptr) {} | |||||
| template<typename U> | |||||
| CAAutoDelete(CAAutoDelete<U>& that) : ptr_(that.release()) {} // take ownership | |||||
| // C++ std says: a template constructor is never a copy constructor | |||||
| CAAutoDelete(CAAutoDelete<T>& that) : ptr_(that.release()) {} // take ownership | |||||
| ~CAAutoDelete() { free(); } | |||||
| template <typename U> | |||||
| CAAutoDelete& operator=(CAAutoDelete<U>& that) | |||||
| { | |||||
| set(that.release()); // take ownership | |||||
| return *this; | |||||
| } | |||||
| CAAutoDelete& operator=(CAAutoDelete& that) | |||||
| { | |||||
| set(that.release()); // take ownership | |||||
| return *this; | |||||
| } | |||||
| CAAutoDelete& operator=(T* ptr) | |||||
| { | |||||
| set(ptr); | |||||
| return *this; | |||||
| } | |||||
| template <typename U> | |||||
| CAAutoDelete& operator=(U* ptr) | |||||
| { | |||||
| set(ptr); | |||||
| return *this; | |||||
| } | |||||
| T& operator*() const { return *ptr_; } | |||||
| T* operator->() const { return ptr_; } | |||||
| T* operator()() const { return ptr_; } | |||||
| T* get() const { return ptr_; } | |||||
| operator T*() const { return ptr_; } | |||||
| bool operator==(CAAutoDelete const& that) const { return ptr_ == that.ptr_; } | |||||
| bool operator!=(CAAutoDelete const& that) const { return ptr_ != that.ptr_; } | |||||
| bool operator==(T* ptr) const { return ptr_ == ptr; } | |||||
| bool operator!=(T* ptr) const { return ptr_ != ptr; } | |||||
| T* release() | |||||
| { | |||||
| // release ownership | |||||
| T* result = ptr_; | |||||
| ptr_ = 0; | |||||
| return result; | |||||
| } | |||||
| void set(T* ptr) | |||||
| { | |||||
| if (ptr != ptr_) | |||||
| { | |||||
| delete ptr_; | |||||
| ptr_ = ptr; | |||||
| } | |||||
| } | |||||
| void free() | |||||
| { | |||||
| set(0); | |||||
| } | |||||
| // automatic conversions to allow assignment from results of functions. | |||||
| // hard to explain. see auto_ptr implementation and/or Josuttis' STL book. | |||||
| CAAutoDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { } | |||||
| CAAutoDelete& operator=(CAPtrRef<T> ref) | |||||
| { | |||||
| set(ref.ptr_); | |||||
| return *this; | |||||
| } | |||||
| template<typename U> | |||||
| operator CAPtrRef<U>() | |||||
| { return CAPtrRef<U>(release()); } | |||||
| template<typename U> | |||||
| operator CAAutoFree<U>() | |||||
| { return CAAutoFree<U>(release()); } | |||||
| }; | |||||
| template <typename T> | |||||
| class CAAutoArrayDelete | |||||
| { | |||||
| private: | |||||
| T* ptr_; | |||||
| public: | |||||
| CAAutoArrayDelete() : ptr_(0) {} | |||||
| explicit CAAutoArrayDelete(T* ptr) : ptr_(ptr) {} | |||||
| template<typename U> | |||||
| CAAutoArrayDelete(CAAutoArrayDelete<U>& that) : ptr_(that.release()) {} // take ownership | |||||
| // C++ std says: a template constructor is never a copy constructor | |||||
| CAAutoArrayDelete(CAAutoArrayDelete<T>& that) : ptr_(that.release()) {} // take ownership | |||||
| // this becomes an ambiguous call if n == 0 | |||||
| CAAutoArrayDelete(size_t n) : ptr_(new T[n]) {} | |||||
| ~CAAutoArrayDelete() { free(); } | |||||
| void alloc(size_t numItems) | |||||
| { | |||||
| free(); | |||||
| ptr_ = new T [numItems]; | |||||
| } | |||||
| template <typename U> | |||||
| CAAutoArrayDelete& operator=(CAAutoArrayDelete<U>& that) | |||||
| { | |||||
| set(that.release()); // take ownership | |||||
| return *this; | |||||
| } | |||||
| CAAutoArrayDelete& operator=(CAAutoArrayDelete& that) | |||||
| { | |||||
| set(that.release()); // take ownership | |||||
| return *this; | |||||
| } | |||||
| CAAutoArrayDelete& operator=(T* ptr) | |||||
| { | |||||
| set(ptr); | |||||
| return *this; | |||||
| } | |||||
| template <typename U> | |||||
| CAAutoArrayDelete& operator=(U* ptr) | |||||
| { | |||||
| set(ptr); | |||||
| return *this; | |||||
| } | |||||
| T& operator*() const { return *ptr_; } | |||||
| T* operator->() const { return ptr_; } | |||||
| T* operator()() const { return ptr_; } | |||||
| T* get() const { return ptr_; } | |||||
| operator T*() const { return ptr_; } | |||||
| bool operator==(CAAutoArrayDelete const& that) const { return ptr_ == that.ptr_; } | |||||
| bool operator!=(CAAutoArrayDelete const& that) const { return ptr_ != that.ptr_; } | |||||
| bool operator==(T* ptr) const { return ptr_ == ptr; } | |||||
| bool operator!=(T* ptr) const { return ptr_ != ptr; } | |||||
| T* release() | |||||
| { | |||||
| // release ownership | |||||
| T* result = ptr_; | |||||
| ptr_ = 0; | |||||
| return result; | |||||
| } | |||||
| void set(T* ptr) | |||||
| { | |||||
| if (ptr != ptr_) | |||||
| { | |||||
| delete [] ptr_; | |||||
| ptr_ = ptr; | |||||
| } | |||||
| } | |||||
| void free() | |||||
| { | |||||
| set(0); | |||||
| } | |||||
| // automatic conversions to allow assignment from results of functions. | |||||
| // hard to explain. see auto_ptr implementation and/or Josuttis' STL book. | |||||
| CAAutoArrayDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { } | |||||
| CAAutoArrayDelete& operator=(CAPtrRef<T> ref) | |||||
| { | |||||
| set(ref.ptr_); | |||||
| return *this; | |||||
| } | |||||
| template<typename U> | |||||
| operator CAPtrRef<U>() | |||||
| { return CAPtrRef<U>(release()); } | |||||
| template<typename U> | |||||
| operator CAAutoArrayDelete<U>() | |||||
| { return CAAutoFree<U>(release()); } | |||||
| }; | |||||
| // convenience function | |||||
| template <typename T> | |||||
| void free(CAAutoFree<T>& p) | |||||
| { | |||||
| p.free(); | |||||
| } | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| #if 0 | |||||
| // example program showing ownership transfer | |||||
| CAAutoFree<char> source() | |||||
| { | |||||
| // source allocates and returns ownership to the caller. | |||||
| const char* str = "this is a test"; | |||||
| size_t size = strlen(str) + 1; | |||||
| CAAutoFree<char> captr(size, false); | |||||
| strlcpy(captr(), str, size); | |||||
| printf("source %08X %08X '%s'\n", &captr, captr(), captr()); | |||||
| return captr; | |||||
| } | |||||
| void user(CAAutoFree<char> const& captr) | |||||
| { | |||||
| // passed by const reference. user can access the pointer but does not take ownership. | |||||
| printf("user: %08X %08X '%s'\n", &captr, captr(), captr()); | |||||
| } | |||||
| void sink(CAAutoFree<char> captr) | |||||
| { | |||||
| // passed by value. sink takes ownership and frees the pointer on return. | |||||
| printf("sink: %08X %08X '%s'\n", &captr, captr(), captr()); | |||||
| } | |||||
| int main (int argc, char * const argv[]) | |||||
| { | |||||
| CAAutoFree<char> captr(source()); | |||||
| printf("main captr A %08X %08X\n", &captr, captr()); | |||||
| user(captr); | |||||
| sink(captr); | |||||
| printf("main captr B %08X %08X\n", &captr, captr()); | |||||
| return 0; | |||||
| } | |||||
| #endif | |||||
| #endif | |||||
| @@ -0,0 +1,581 @@ | |||||
| /* | |||||
| File: CADebugMacros.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #if !defined(__CADebugMacros_h__) | |||||
| #define __CADebugMacros_h__ | |||||
| //============================================================================= | |||||
| // Includes | |||||
| //============================================================================= | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreAudio/CoreAudioTypes.h> | |||||
| #else | |||||
| #include "CoreAudioTypes.h" | |||||
| #endif | |||||
| //============================================================================= | |||||
| // CADebugMacros | |||||
| //============================================================================= | |||||
| //#define CoreAudio_StopOnFailure 1 | |||||
| //#define CoreAudio_TimeStampMessages 1 | |||||
| //#define CoreAudio_ThreadStampMessages 1 | |||||
| //#define CoreAudio_FlushDebugMessages 1 | |||||
| #if TARGET_RT_BIG_ENDIAN | |||||
| #define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 } | |||||
| #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; } | |||||
| #else | |||||
| #define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 } | |||||
| #define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; } | |||||
| #endif | |||||
| // This is a macro that does a sizeof and casts the result to a UInt32. This is useful for all the | |||||
| // places where -wshorten64-32 catches assigning a sizeof expression to a UInt32. | |||||
| // For want of a better place to park this, we'll park it here. | |||||
| #define SizeOf32(X) ((UInt32)sizeof(X)) | |||||
| // This is a macro that does a offsetof and casts the result to a UInt32. This is useful for all the | |||||
| // places where -wshorten64-32 catches assigning an offsetof expression to a UInt32. | |||||
| // For want of a better place to park this, we'll park it here. | |||||
| #define OffsetOf32(X, Y) ((UInt32)offsetof(X, Y)) | |||||
| // This macro casts the expression to a UInt32. It is called out specially to allow us to track casts | |||||
| // that have been added purely to avert -wshorten64-32 warnings on 64 bit platforms. | |||||
| // For want of a better place to park this, we'll park it here. | |||||
| #define ToUInt32(X) ((UInt32)(X)) | |||||
| #define ToSInt32(X) ((SInt32)(X)) | |||||
| #pragma mark Basic Definitions | |||||
| #if DEBUG || CoreAudio_Debug | |||||
| // can be used to break into debugger immediately, also see CADebugger | |||||
| #define BusError() { long* p=NULL; *p=0; } | |||||
| // basic debugging print routines | |||||
| #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON | |||||
| extern void DebugStr(const unsigned char* debuggerMsg); | |||||
| #define DebugMessage(msg) DebugStr("\p"msg) | |||||
| #define DebugMessageN1(msg, N1) | |||||
| #define DebugMessageN2(msg, N1, N2) | |||||
| #define DebugMessageN3(msg, N1, N2, N3) | |||||
| #else | |||||
| #include "CADebugPrintf.h" | |||||
| #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile) | |||||
| #define FlushRtn ,fflush(DebugPrintfFile) | |||||
| #else | |||||
| #define FlushRtn | |||||
| #endif | |||||
| #if CoreAudio_ThreadStampMessages | |||||
| #include <pthread.h> | |||||
| #include "CAHostTimeBase.h" | |||||
| #if TARGET_RT_64_BIT | |||||
| #define DebugPrintfThreadIDFormat "%16p" | |||||
| #else | |||||
| #define DebugPrintfThreadIDFormat "%8p" | |||||
| #endif | |||||
| #define DebugMsg(inFormat, ...) DebugPrintf("%17qd: " DebugPrintfThreadIDFormat " " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), pthread_self(), ## __VA_ARGS__) FlushRtn | |||||
| #elif CoreAudio_TimeStampMessages | |||||
| #include "CAHostTimeBase.h" | |||||
| #define DebugMsg(inFormat, ...) DebugPrintf("%17qd: " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), ## __VA_ARGS__) FlushRtn | |||||
| #else | |||||
| #define DebugMsg(inFormat, ...) DebugPrintf(inFormat, ## __VA_ARGS__) FlushRtn | |||||
| #endif | |||||
| #endif | |||||
| void DebugPrint(const char *fmt, ...); // can be used like printf | |||||
| #ifndef DEBUGPRINT | |||||
| #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h) | |||||
| #endif | |||||
| #if VERBOSE | |||||
| #define vprint(msg) DEBUGPRINT(msg) | |||||
| #else | |||||
| #define vprint(msg) | |||||
| #endif | |||||
| // Original macro keeps its function of turning on and off use of CADebuggerStop() for both asserts and throws. | |||||
| // For backwards compat, it overrides any setting of the two sub-macros. | |||||
| #if CoreAudio_StopOnFailure | |||||
| #include "CADebugger.h" | |||||
| #undef CoreAudio_StopOnAssert | |||||
| #define CoreAudio_StopOnAssert 1 | |||||
| #undef CoreAudio_StopOnThrow | |||||
| #define CoreAudio_StopOnThrow 1 | |||||
| #define STOP CADebuggerStop() | |||||
| #else | |||||
| #define STOP | |||||
| #endif | |||||
| #if CoreAudio_StopOnAssert | |||||
| #if !CoreAudio_StopOnFailure | |||||
| #include "CADebugger.h" | |||||
| #define STOP | |||||
| #endif | |||||
| #define __ASSERT_STOP CADebuggerStop() | |||||
| #else | |||||
| #define __ASSERT_STOP | |||||
| #endif | |||||
| #if CoreAudio_StopOnThrow | |||||
| #if !CoreAudio_StopOnFailure | |||||
| #include "CADebugger.h" | |||||
| #define STOP | |||||
| #endif | |||||
| #define __THROW_STOP CADebuggerStop() | |||||
| #else | |||||
| #define __THROW_STOP | |||||
| #endif | |||||
| #else | |||||
| #define DebugMsg(inFormat, ...) | |||||
| #ifndef DEBUGPRINT | |||||
| #define DEBUGPRINT(msg) | |||||
| #endif | |||||
| #define vprint(msg) | |||||
| #define STOP | |||||
| #define __ASSERT_STOP | |||||
| #define __THROW_STOP | |||||
| #endif | |||||
| // Old-style numbered DebugMessage calls are implemented in terms of DebugMsg() now | |||||
| #define DebugMessage(msg) DebugMsg(msg) | |||||
| #define DebugMessageN1(msg, N1) DebugMsg(msg, N1) | |||||
| #define DebugMessageN2(msg, N1, N2) DebugMsg(msg, N1, N2) | |||||
| #define DebugMessageN3(msg, N1, N2, N3) DebugMsg(msg, N1, N2, N3) | |||||
| #define DebugMessageN4(msg, N1, N2, N3, N4) DebugMsg(msg, N1, N2, N3, N4) | |||||
| #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugMsg(msg, N1, N2, N3, N4, N5) | |||||
| #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugMsg(msg, N1, N2, N3, N4, N5, N6) | |||||
| #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7) | |||||
| #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8) | |||||
| #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) | |||||
| void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging) | |||||
| void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging) | |||||
| #define NO_ACTION (void)0 | |||||
| #if DEBUG || CoreAudio_Debug | |||||
| #pragma mark Debug Macros | |||||
| #define Assert(inCondition, inMessage) \ | |||||
| if(!(inCondition)) \ | |||||
| { \ | |||||
| DebugMessage(inMessage); \ | |||||
| __ASSERT_STOP; \ | |||||
| } | |||||
| #define AssertFileLine(inCondition, inMessage) \ | |||||
| if(!(inCondition)) \ | |||||
| { \ | |||||
| DebugMessageN3("%s, line %d: %s", __FILE__, __LINE__, inMessage); \ | |||||
| __ASSERT_STOP; \ | |||||
| } | |||||
| #define AssertNoError(inError, inMessage) \ | |||||
| { \ | |||||
| SInt32 __Err = (inError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| char __4CC[5] = CA4CCToCString(__Err); \ | |||||
| DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ | |||||
| __ASSERT_STOP; \ | |||||
| } \ | |||||
| } | |||||
| #define AssertNoKernelError(inError, inMessage) \ | |||||
| { \ | |||||
| unsigned int __Err = (unsigned int)(inError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ | |||||
| __ASSERT_STOP; \ | |||||
| } \ | |||||
| } | |||||
| #define AssertNotNULL(inPtr, inMessage) \ | |||||
| { \ | |||||
| if((inPtr) == NULL) \ | |||||
| { \ | |||||
| DebugMessage(inMessage); \ | |||||
| __ASSERT_STOP; \ | |||||
| } \ | |||||
| } | |||||
| #define FailIf(inCondition, inHandler, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| DebugMessage(inMessage); \ | |||||
| STOP; \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailWithAction(inCondition, inAction, inHandler, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| DebugMessage(inMessage); \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ | |||||
| if((inPointer) == NULL) \ | |||||
| { \ | |||||
| DebugMessage(inMessage); \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ | |||||
| { \ | |||||
| unsigned int __Err = (inKernelError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } \ | |||||
| } | |||||
| #define FailIfError(inError, inAction, inHandler, inMessage) \ | |||||
| { \ | |||||
| SInt32 __Err = (inError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| char __4CC[5] = CA4CCToCString(__Err); \ | |||||
| DebugMessageN2(inMessage ", Error: %ld (%s)", (long int)__Err, __4CC); \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } \ | |||||
| } | |||||
| #define FailIfNoMessage(inCondition, inHandler, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage) \ | |||||
| if((inPointer) == NULL) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage) \ | |||||
| { \ | |||||
| unsigned int __Err = (inKernelError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } \ | |||||
| } | |||||
| #define FailIfErrorNoMessage(inError, inAction, inHandler, inMessage) \ | |||||
| { \ | |||||
| SInt32 __Err = (inError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } \ | |||||
| } | |||||
| #if defined(__cplusplus) | |||||
| #define Throw(inException) __THROW_STOP; throw (inException) | |||||
| #define ThrowIf(inCondition, inException, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| DebugMessage(inMessage); \ | |||||
| Throw(inException); \ | |||||
| } | |||||
| #define ThrowIfNULL(inPointer, inException, inMessage) \ | |||||
| if((inPointer) == NULL) \ | |||||
| { \ | |||||
| DebugMessage(inMessage); \ | |||||
| Throw(inException); \ | |||||
| } | |||||
| #define ThrowIfKernelError(inKernelError, inException, inMessage) \ | |||||
| { \ | |||||
| int __Err = (inKernelError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| DebugMessageN1(inMessage ", Error: 0x%X", __Err); \ | |||||
| Throw(inException); \ | |||||
| } \ | |||||
| } | |||||
| #define ThrowIfError(inError, inException, inMessage) \ | |||||
| { \ | |||||
| SInt32 __Err = (inError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| char __4CC[5] = CA4CCToCString(__Err); \ | |||||
| DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \ | |||||
| Throw(inException); \ | |||||
| } \ | |||||
| } | |||||
| #if TARGET_OS_WIN32 | |||||
| #define ThrowIfWinError(inError, inException, inMessage) \ | |||||
| { \ | |||||
| HRESULT __Err = (inError); \ | |||||
| if(FAILED(__Err)) \ | |||||
| { \ | |||||
| DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \ | |||||
| Throw(inException); \ | |||||
| } \ | |||||
| } | |||||
| #endif | |||||
| #define SubclassResponsibility(inMethodName, inException) \ | |||||
| { \ | |||||
| DebugMessage(inMethodName": Subclasses must implement this method"); \ | |||||
| Throw(inException); \ | |||||
| } | |||||
| #endif // defined(__cplusplus) | |||||
| #else | |||||
| #pragma mark Release Macros | |||||
| #define Assert(inCondition, inMessage) \ | |||||
| if(!(inCondition)) \ | |||||
| { \ | |||||
| __ASSERT_STOP; \ | |||||
| } | |||||
| #define AssertFileLine(inCondition, inMessage) Assert(inCondition, inMessage) | |||||
| #define AssertNoError(inError, inMessage) \ | |||||
| { \ | |||||
| SInt32 __Err = (inError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| __ASSERT_STOP; \ | |||||
| } \ | |||||
| } | |||||
| #define AssertNoKernelError(inError, inMessage) \ | |||||
| { \ | |||||
| unsigned int __Err = (unsigned int)(inError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| __ASSERT_STOP; \ | |||||
| } \ | |||||
| } | |||||
| #define AssertNotNULL(inPtr, inMessage) \ | |||||
| { \ | |||||
| if((inPtr) == NULL) \ | |||||
| { \ | |||||
| __ASSERT_STOP; \ | |||||
| } \ | |||||
| } | |||||
| #define FailIf(inCondition, inHandler, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailWithAction(inCondition, inAction, inHandler, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfNULL(inPointer, inAction, inHandler, inMessage) \ | |||||
| if((inPointer) == NULL) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \ | |||||
| if((inKernelError) != 0) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfError(inError, inAction, inHandler, inMessage) \ | |||||
| if((inError) != 0) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfNoMessage(inCondition, inHandler, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage) \ | |||||
| if((inPointer) == NULL) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } | |||||
| #define FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage) \ | |||||
| { \ | |||||
| unsigned int __Err = (inKernelError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } \ | |||||
| } | |||||
| #define FailIfErrorNoMessage(inError, inAction, inHandler, inMessage) \ | |||||
| { \ | |||||
| SInt32 __Err = (inError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| STOP; \ | |||||
| { inAction; } \ | |||||
| goto inHandler; \ | |||||
| } \ | |||||
| } | |||||
| #if defined(__cplusplus) | |||||
| #define Throw(inException) __THROW_STOP; throw (inException) | |||||
| #define ThrowIf(inCondition, inException, inMessage) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| Throw(inException); \ | |||||
| } | |||||
| #define ThrowIfNULL(inPointer, inException, inMessage) \ | |||||
| if((inPointer) == NULL) \ | |||||
| { \ | |||||
| Throw(inException); \ | |||||
| } | |||||
| #define ThrowIfKernelError(inKernelError, inException, inMessage) \ | |||||
| { \ | |||||
| int __Err = (inKernelError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| Throw(inException); \ | |||||
| } \ | |||||
| } | |||||
| #define ThrowIfError(inError, inException, inMessage) \ | |||||
| { \ | |||||
| SInt32 __Err = (inError); \ | |||||
| if(__Err != 0) \ | |||||
| { \ | |||||
| Throw(inException); \ | |||||
| } \ | |||||
| } | |||||
| #if TARGET_OS_WIN32 | |||||
| #define ThrowIfWinError(inError, inException, inMessage) \ | |||||
| { \ | |||||
| HRESULT __Err = (inError); \ | |||||
| if(FAILED(__Err)) \ | |||||
| { \ | |||||
| Throw(inException); \ | |||||
| } \ | |||||
| } | |||||
| #endif | |||||
| #define SubclassResponsibility(inMethodName, inException) \ | |||||
| { \ | |||||
| Throw(inException); \ | |||||
| } | |||||
| #endif // defined(__cplusplus) | |||||
| #endif // DEBUG || CoreAudio_Debug | |||||
| #endif | |||||
| @@ -0,0 +1,115 @@ | |||||
| /* | |||||
| File: CADebugPrintf.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #if !defined(__CADebugPrintf_h__) | |||||
| #define __CADebugPrintf_h__ | |||||
| //============================================================================= | |||||
| // Includes | |||||
| //============================================================================= | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreAudio/CoreAudioTypes.h> | |||||
| #else | |||||
| #include "CoreAudioTypes.h" | |||||
| #endif | |||||
| //============================================================================= | |||||
| // Macros to redirect debugging output to various logging services | |||||
| //============================================================================= | |||||
| //#define CoreAudio_UseSysLog 1 | |||||
| //#define CoreAudio_UseSideFile "/CoreAudio-%d.txt" | |||||
| #if DEBUG || CoreAudio_Debug | |||||
| #if TARGET_OS_WIN32 | |||||
| #if defined(__cplusplus) | |||||
| extern "C" | |||||
| #endif | |||||
| extern int CAWin32DebugPrintf(char* inFormat, ...); | |||||
| #define DebugPrintfRtn CAWin32DebugPrintf | |||||
| #define DebugPrintfFile | |||||
| #define DebugPrintfLineEnding "\n" | |||||
| #define DebugPrintfFileComma | |||||
| #else | |||||
| #if CoreAudio_UseSysLog | |||||
| #include <sys/syslog.h> | |||||
| #define DebugPrintfRtn syslog | |||||
| #define DebugPrintfFile LOG_NOTICE | |||||
| #define DebugPrintfLineEnding "" | |||||
| #define DebugPrintfFileComma DebugPrintfFile, | |||||
| #elif defined(CoreAudio_UseSideFile) | |||||
| #include <stdio.h> | |||||
| #if defined(__cplusplus) | |||||
| extern "C" | |||||
| #endif | |||||
| void OpenDebugPrintfSideFile(); | |||||
| extern FILE* sDebugPrintfSideFile; | |||||
| #define DebugPrintfRtn fprintf | |||||
| #define DebugPrintfFile ((sDebugPrintfSideFile != NULL) ? sDebugPrintfSideFile : stderr) | |||||
| #define DebugPrintfLineEnding "\n" | |||||
| #define DebugPrintfFileComma DebugPrintfFile, | |||||
| #else | |||||
| #include <stdio.h> | |||||
| #define DebugPrintfRtn fprintf | |||||
| #define DebugPrintfFile stderr | |||||
| #define DebugPrintfLineEnding "\n" | |||||
| #define DebugPrintfFileComma DebugPrintfFile, | |||||
| #endif | |||||
| #endif | |||||
| #define DebugPrintf(inFormat, ...) DebugPrintfRtn(DebugPrintfFileComma inFormat DebugPrintfLineEnding, ## __VA_ARGS__) | |||||
| #else | |||||
| #define DebugPrintfRtn | |||||
| #define DebugPrintfFile | |||||
| #define DebugPrintfLineEnding | |||||
| #define DebugPrintfFileComma | |||||
| #define DebugPrintf(inFormat, ...) | |||||
| #endif | |||||
| #endif | |||||
| @@ -0,0 +1,83 @@ | |||||
| /* | |||||
| File: CAException.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #if !defined(__CAException_h__) | |||||
| #define __CAException_h__ | |||||
| //============================================================================= | |||||
| // Includes | |||||
| //============================================================================= | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreAudio/CoreAudioTypes.h> | |||||
| #else | |||||
| #include "CoreAudioTypes.h" | |||||
| #endif | |||||
| //============================================================================= | |||||
| // CAException | |||||
| //============================================================================= | |||||
| class CAException | |||||
| { | |||||
| public: | |||||
| CAException(OSStatus inError) : mError(inError) {} | |||||
| CAException(const CAException& inException) : mError(inException.mError) {} | |||||
| CAException& operator=(const CAException& inException) { mError = inException.mError; return *this; } | |||||
| ~CAException() {} | |||||
| OSStatus GetError() const { return mError; } | |||||
| protected: | |||||
| OSStatus mError; | |||||
| }; | |||||
| #define CATry try{ | |||||
| #define CACatch } catch(...) {} | |||||
| #define CASwallowException(inExpression) try { inExpression; } catch(...) {} | |||||
| #endif | |||||
| @@ -0,0 +1,234 @@ | |||||
| /* | |||||
| File: CAHostTimeBase.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #if !defined(__CAHostTimeBase_h__) | |||||
| #define __CAHostTimeBase_h__ | |||||
| //============================================================================= | |||||
| // Includes | |||||
| //============================================================================= | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreAudio/CoreAudioTypes.h> | |||||
| #else | |||||
| #include <CoreAudioTypes.h> | |||||
| #endif | |||||
| #if TARGET_OS_MAC | |||||
| #include <mach/mach_time.h> | |||||
| #include <pthread.h> | |||||
| #elif TARGET_OS_WIN32 | |||||
| #include <windows.h> | |||||
| #include "WinPThreadDefs.h" | |||||
| #else | |||||
| #error Unsupported operating system | |||||
| #endif | |||||
| #include "CADebugPrintf.h" | |||||
| //============================================================================= | |||||
| // CAHostTimeBase | |||||
| // | |||||
| // This class provides platform independent access to the host's time base. | |||||
| //============================================================================= | |||||
| #if CoreAudio_Debug | |||||
| // #define Log_Host_Time_Base_Parameters 1 | |||||
| // #define Track_Host_TimeBase 1 | |||||
| #endif | |||||
| class CAHostTimeBase | |||||
| { | |||||
| public: | |||||
| static UInt64 ConvertToNanos(UInt64 inHostTime); | |||||
| static UInt64 ConvertFromNanos(UInt64 inNanos); | |||||
| static UInt64 GetTheCurrentTime(); | |||||
| #if TARGET_OS_MAC | |||||
| static UInt64 GetCurrentTime() { return GetTheCurrentTime(); } | |||||
| #endif | |||||
| static UInt64 GetCurrentTimeInNanos(); | |||||
| static Float64 GetFrequency() { pthread_once(&sIsInited, Initialize); return sFrequency; } | |||||
| static Float64 GetInverseFrequency() { pthread_once(&sIsInited, Initialize); return sInverseFrequency; } | |||||
| static UInt32 GetMinimumDelta() { pthread_once(&sIsInited, Initialize); return sMinDelta; } | |||||
| static UInt64 AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime); | |||||
| static SInt64 HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime); | |||||
| static UInt64 MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator); | |||||
| private: | |||||
| static void Initialize(); | |||||
| static pthread_once_t sIsInited; | |||||
| static Float64 sFrequency; | |||||
| static Float64 sInverseFrequency; | |||||
| static UInt32 sMinDelta; | |||||
| static UInt32 sToNanosNumerator; | |||||
| static UInt32 sToNanosDenominator; | |||||
| #if Track_Host_TimeBase | |||||
| static UInt64 sLastTime; | |||||
| #endif | |||||
| }; | |||||
| inline UInt64 CAHostTimeBase::GetTheCurrentTime() | |||||
| { | |||||
| UInt64 theTime = 0; | |||||
| #if TARGET_OS_MAC | |||||
| theTime = mach_absolute_time(); | |||||
| #elif TARGET_OS_WIN32 | |||||
| LARGE_INTEGER theValue; | |||||
| QueryPerformanceCounter(&theValue); | |||||
| theTime = *((UInt64*)&theValue); | |||||
| #endif | |||||
| #if Track_Host_TimeBase | |||||
| if(sLastTime != 0) | |||||
| { | |||||
| if(theTime <= sLastTime) | |||||
| { | |||||
| DebugPrintf("CAHostTimeBase::GetTheCurrentTime: the current time is earlier than the last time, now: %qd, then: %qd", theTime, sLastTime); | |||||
| } | |||||
| sLastTime = theTime; | |||||
| } | |||||
| else | |||||
| { | |||||
| sLastTime = theTime; | |||||
| } | |||||
| #endif | |||||
| return theTime; | |||||
| } | |||||
| inline UInt64 CAHostTimeBase::ConvertToNanos(UInt64 inHostTime) | |||||
| { | |||||
| pthread_once(&sIsInited, Initialize); | |||||
| UInt64 theAnswer = MultiplyByRatio(inHostTime, sToNanosNumerator, sToNanosDenominator); | |||||
| #if CoreAudio_Debug | |||||
| if(((sToNanosNumerator > sToNanosDenominator) && (theAnswer < inHostTime)) || ((sToNanosDenominator > sToNanosNumerator) && (theAnswer > inHostTime))) | |||||
| { | |||||
| DebugPrintf("CAHostTimeBase::ConvertToNanos: The conversion wrapped"); | |||||
| } | |||||
| #endif | |||||
| return theAnswer; | |||||
| } | |||||
| inline UInt64 CAHostTimeBase::ConvertFromNanos(UInt64 inNanos) | |||||
| { | |||||
| pthread_once(&sIsInited, Initialize); | |||||
| UInt64 theAnswer = MultiplyByRatio(inNanos, sToNanosDenominator, sToNanosNumerator); | |||||
| #if CoreAudio_Debug | |||||
| if(((sToNanosDenominator > sToNanosNumerator) && (theAnswer < inNanos)) || ((sToNanosNumerator > sToNanosDenominator) && (theAnswer > inNanos))) | |||||
| { | |||||
| DebugPrintf("CAHostTimeBase::ConvertFromNanos: The conversion wrapped"); | |||||
| } | |||||
| #endif | |||||
| return theAnswer; | |||||
| } | |||||
| inline UInt64 CAHostTimeBase::GetCurrentTimeInNanos() | |||||
| { | |||||
| return ConvertToNanos(GetTheCurrentTime()); | |||||
| } | |||||
| inline UInt64 CAHostTimeBase::AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime) | |||||
| { | |||||
| UInt64 theAnswer; | |||||
| if(inStartTime <= inEndTime) | |||||
| { | |||||
| theAnswer = inEndTime - inStartTime; | |||||
| } | |||||
| else | |||||
| { | |||||
| theAnswer = inStartTime - inEndTime; | |||||
| } | |||||
| return ConvertToNanos(theAnswer); | |||||
| } | |||||
| inline SInt64 CAHostTimeBase::HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime) | |||||
| { | |||||
| SInt64 theAnswer; | |||||
| SInt64 theSign = 1; | |||||
| if(inStartTime <= inEndTime) | |||||
| { | |||||
| theAnswer = static_cast<SInt64>(inEndTime - inStartTime); | |||||
| } | |||||
| else | |||||
| { | |||||
| theAnswer = static_cast<SInt64>(inStartTime - inEndTime); | |||||
| theSign = -1; | |||||
| } | |||||
| return theSign * static_cast<SInt64>(ConvertToNanos(static_cast<UInt64>(theAnswer))); | |||||
| } | |||||
| inline UInt64 CAHostTimeBase::MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator) | |||||
| { | |||||
| #if TARGET_OS_MAC && TARGET_RT_64_BIT | |||||
| __uint128_t theAnswer = inMuliplicand; | |||||
| #else | |||||
| long double theAnswer = inMuliplicand; | |||||
| #endif | |||||
| if(inNumerator != inDenominator) | |||||
| { | |||||
| theAnswer *= inNumerator; | |||||
| theAnswer /= inDenominator; | |||||
| } | |||||
| return static_cast<UInt64>(theAnswer); | |||||
| } | |||||
| #endif | |||||
| @@ -0,0 +1,68 @@ | |||||
| /* | |||||
| File: CAMath.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAMath_h__ | |||||
| #define __CAMath_h__ | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreAudio/CoreAudioTypes.h> | |||||
| #else | |||||
| #include <CoreAudioTypes.h> | |||||
| #endif | |||||
| inline bool fiszero(Float64 f) { return (f == 0.); } | |||||
| inline bool fiszero(Float32 f) { return (f == 0.f); } | |||||
| inline bool fnonzero(Float64 f) { return !fiszero(f); } | |||||
| inline bool fnonzero(Float32 f) { return !fiszero(f); } | |||||
| inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; } | |||||
| inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; } | |||||
| inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); } | |||||
| inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); } | |||||
| #endif // __CAMath_h__ | |||||
| @@ -0,0 +1,345 @@ | |||||
| /* | |||||
| File: CAMutex.cpp | |||||
| Abstract: CAMutex.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| //================================================================================================== | |||||
| // Includes | |||||
| //================================================================================================== | |||||
| // Self Include | |||||
| #include "CAMutex.h" | |||||
| #if TARGET_OS_MAC | |||||
| #include <errno.h> | |||||
| #endif | |||||
| // PublicUtility Includes | |||||
| #include "CADebugMacros.h" | |||||
| #include "CAException.h" | |||||
| #include "CAHostTimeBase.h" | |||||
| //================================================================================================== | |||||
| // Logging | |||||
| //================================================================================================== | |||||
| #if CoreAudio_Debug | |||||
| // #define Log_Ownership 1 | |||||
| // #define Log_Errors 1 | |||||
| // #define Log_LongLatencies 1 | |||||
| // #define LongLatencyThreshholdNS 1000000ULL // nanoseconds | |||||
| #endif | |||||
| //================================================================================================== | |||||
| // CAMutex | |||||
| //================================================================================================== | |||||
| CAMutex::CAMutex(const char* inName) | |||||
| : | |||||
| mName(inName), | |||||
| mOwner(0) | |||||
| { | |||||
| #if TARGET_OS_MAC | |||||
| OSStatus theError = pthread_mutex_init(&mMutex, NULL); | |||||
| ThrowIf(theError != 0, CAException(theError), "CAMutex::CAMutex: Could not init the mutex"); | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::CAMutex: creating %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner); | |||||
| #endif | |||||
| #elif TARGET_OS_WIN32 | |||||
| mMutex = CreateMutex(NULL, false, NULL); | |||||
| ThrowIfNULL(mMutex, CAException(GetLastError()), "CAMutex::CAMutex: could not create the mutex."); | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::CAMutex: creating %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner); | |||||
| #endif | |||||
| #endif | |||||
| } | |||||
| CAMutex::~CAMutex() | |||||
| { | |||||
| #if TARGET_OS_MAC | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::~CAMutex: destroying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner); | |||||
| #endif | |||||
| pthread_mutex_destroy(&mMutex); | |||||
| #elif TARGET_OS_WIN32 | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::~CAMutex: destroying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner); | |||||
| #endif | |||||
| if(mMutex != NULL) | |||||
| { | |||||
| CloseHandle(mMutex); | |||||
| } | |||||
| #endif | |||||
| } | |||||
| bool CAMutex::Lock() | |||||
| { | |||||
| bool theAnswer = false; | |||||
| #if TARGET_OS_MAC | |||||
| pthread_t theCurrentThread = pthread_self(); | |||||
| if(!pthread_equal(theCurrentThread, mOwner)) | |||||
| { | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p is locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner); | |||||
| #endif | |||||
| #if Log_LongLatencies | |||||
| UInt64 lockTryTime = CAHostTimeBase::GetCurrentTimeInNanos(); | |||||
| #endif | |||||
| OSStatus theError = pthread_mutex_lock(&mMutex); | |||||
| ThrowIf(theError != 0, CAException(theError), "CAMutex::Lock: Could not lock the mutex"); | |||||
| mOwner = theCurrentThread; | |||||
| theAnswer = true; | |||||
| #if Log_LongLatencies | |||||
| UInt64 lockAcquireTime = CAHostTimeBase::GetCurrentTimeInNanos(); | |||||
| if (lockAcquireTime - lockTryTime >= LongLatencyThresholdNS) | |||||
| DebugPrintfRtn(DebugPrintfFileComma "Thread %p took %.6fs to acquire the lock %s\n", theCurrentThread, (lockAcquireTime - lockTryTime) * 1.0e-9 /* nanos to seconds */, mName); | |||||
| #endif | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p has locked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner); | |||||
| #endif | |||||
| } | |||||
| #elif TARGET_OS_WIN32 | |||||
| if(mOwner != GetCurrentThreadId()) | |||||
| { | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu is locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); | |||||
| #endif | |||||
| OSStatus theError = WaitForSingleObject(mMutex, INFINITE); | |||||
| ThrowIfError(theError, CAException(theError), "CAMutex::Lock: could not lock the mutex"); | |||||
| mOwner = GetCurrentThreadId(); | |||||
| theAnswer = true; | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); | |||||
| #endif | |||||
| } | |||||
| #endif | |||||
| return theAnswer; | |||||
| } | |||||
| void CAMutex::Unlock() | |||||
| { | |||||
| #if TARGET_OS_MAC | |||||
| if(pthread_equal(pthread_self(), mOwner)) | |||||
| { | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p is unlocking %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner); | |||||
| #endif | |||||
| mOwner = 0; | |||||
| OSStatus theError = pthread_mutex_unlock(&mMutex); | |||||
| ThrowIf(theError != 0, CAException(theError), "CAMutex::Unlock: Could not unlock the mutex"); | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p has unlocked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner); | |||||
| #endif | |||||
| } | |||||
| else | |||||
| { | |||||
| DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own"); | |||||
| } | |||||
| #elif TARGET_OS_WIN32 | |||||
| if(mOwner == GetCurrentThreadId()) | |||||
| { | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu is unlocking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); | |||||
| #endif | |||||
| mOwner = 0; | |||||
| bool wasReleased = ReleaseMutex(mMutex); | |||||
| ThrowIf(!wasReleased, CAException(GetLastError()), "CAMutex::Unlock: Could not unlock the mutex"); | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu has unlocked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); | |||||
| #endif | |||||
| } | |||||
| else | |||||
| { | |||||
| DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own"); | |||||
| } | |||||
| #endif | |||||
| } | |||||
| bool CAMutex::Try(bool& outWasLocked) | |||||
| { | |||||
| bool theAnswer = false; | |||||
| outWasLocked = false; | |||||
| #if TARGET_OS_MAC | |||||
| pthread_t theCurrentThread = pthread_self(); | |||||
| if(!pthread_equal(theCurrentThread, mOwner)) | |||||
| { | |||||
| // this means the current thread doesn't already own the lock | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p is try-locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner); | |||||
| #endif | |||||
| // go ahead and call trylock to see if we can lock it. | |||||
| int theError = pthread_mutex_trylock(&mMutex); | |||||
| if(theError == 0) | |||||
| { | |||||
| // return value of 0 means we successfully locked the lock | |||||
| mOwner = theCurrentThread; | |||||
| theAnswer = true; | |||||
| outWasLocked = true; | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p has locked %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner); | |||||
| #endif | |||||
| } | |||||
| else if(theError == EBUSY) | |||||
| { | |||||
| // return value of EBUSY means that the lock was already locked by another thread | |||||
| theAnswer = false; | |||||
| outWasLocked = false; | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p failed to lock %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner); | |||||
| #endif | |||||
| } | |||||
| else | |||||
| { | |||||
| // any other return value means something really bad happenned | |||||
| ThrowIfError(theError, CAException(theError), "CAMutex::Try: call to pthread_mutex_trylock failed"); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| // this means the current thread already owns the lock | |||||
| theAnswer = true; | |||||
| outWasLocked = false; | |||||
| } | |||||
| #elif TARGET_OS_WIN32 | |||||
| if(mOwner != GetCurrentThreadId()) | |||||
| { | |||||
| // this means the current thread doesn't own the lock | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu is try-locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); | |||||
| #endif | |||||
| // try to acquire the mutex | |||||
| OSStatus theError = WaitForSingleObject(mMutex, 0); | |||||
| if(theError == WAIT_OBJECT_0) | |||||
| { | |||||
| // this means we successfully locked the lock | |||||
| mOwner = GetCurrentThreadId(); | |||||
| theAnswer = true; | |||||
| outWasLocked = true; | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); | |||||
| #endif | |||||
| } | |||||
| else if(theError == WAIT_TIMEOUT) | |||||
| { | |||||
| // this means that the lock was already locked by another thread | |||||
| theAnswer = false; | |||||
| outWasLocked = false; | |||||
| #if Log_Ownership | |||||
| DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu failed to lock %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner); | |||||
| #endif | |||||
| } | |||||
| else | |||||
| { | |||||
| // any other return value means something really bad happenned | |||||
| ThrowIfError(theError, CAException(GetLastError()), "CAMutex::Try: call to lock the mutex failed"); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| // this means the current thread already owns the lock | |||||
| theAnswer = true; | |||||
| outWasLocked = false; | |||||
| } | |||||
| #endif | |||||
| return theAnswer; | |||||
| } | |||||
| bool CAMutex::IsFree() const | |||||
| { | |||||
| return mOwner == 0; | |||||
| } | |||||
| bool CAMutex::IsOwnedByCurrentThread() const | |||||
| { | |||||
| bool theAnswer = true; | |||||
| #if TARGET_OS_MAC | |||||
| theAnswer = pthread_equal(pthread_self(), mOwner); | |||||
| #elif TARGET_OS_WIN32 | |||||
| theAnswer = (mOwner == GetCurrentThreadId()); | |||||
| #endif | |||||
| return theAnswer; | |||||
| } | |||||
| CAMutex::Unlocker::Unlocker(CAMutex& inMutex) | |||||
| : mMutex(inMutex), | |||||
| mNeedsLock(false) | |||||
| { | |||||
| Assert(mMutex.IsOwnedByCurrentThread(), "Major problem: Unlocker attempted to unlock a mutex not owned by the current thread!"); | |||||
| mMutex.Unlock(); | |||||
| mNeedsLock = true; | |||||
| } | |||||
| CAMutex::Unlocker::~Unlocker() | |||||
| { | |||||
| if(mNeedsLock) | |||||
| { | |||||
| mMutex.Lock(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,163 @@ | |||||
| /* | |||||
| File: CAMutex.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAMutex_h__ | |||||
| #define __CAMutex_h__ | |||||
| //================================================================================================== | |||||
| // Includes | |||||
| //================================================================================================== | |||||
| // System Includes | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreAudio/CoreAudioTypes.h> | |||||
| #else | |||||
| #include <CoreAudioTypes.h> | |||||
| #endif | |||||
| #if TARGET_OS_MAC | |||||
| #include <pthread.h> | |||||
| #elif TARGET_OS_WIN32 | |||||
| #include <windows.h> | |||||
| #else | |||||
| #error Unsupported operating system | |||||
| #endif | |||||
| //================================================================================================== | |||||
| // A recursive mutex. | |||||
| //================================================================================================== | |||||
| class CAMutex | |||||
| { | |||||
| // Construction/Destruction | |||||
| public: | |||||
| CAMutex(const char* inName); | |||||
| virtual ~CAMutex(); | |||||
| // Actions | |||||
| public: | |||||
| virtual bool Lock(); | |||||
| virtual void Unlock(); | |||||
| virtual bool Try(bool& outWasLocked); // returns true if lock is free, false if not | |||||
| virtual bool IsFree() const; | |||||
| virtual bool IsOwnedByCurrentThread() const; | |||||
| // Implementation | |||||
| protected: | |||||
| const char* mName; | |||||
| #if TARGET_OS_MAC | |||||
| pthread_t mOwner; | |||||
| pthread_mutex_t mMutex; | |||||
| #elif TARGET_OS_WIN32 | |||||
| UInt32 mOwner; | |||||
| HANDLE mMutex; | |||||
| #endif | |||||
| // Helper class to manage taking and releasing recursively | |||||
| public: | |||||
| class Locker | |||||
| { | |||||
| // Construction/Destruction | |||||
| public: | |||||
| Locker(CAMutex& inMutex) : mMutex(&inMutex), mNeedsRelease(false) { mNeedsRelease = mMutex->Lock(); } | |||||
| Locker(CAMutex* inMutex) : mMutex(inMutex), mNeedsRelease(false) { mNeedsRelease = (mMutex != NULL && mMutex->Lock()); } | |||||
| // in this case the mutex can be null | |||||
| ~Locker() { if(mNeedsRelease) { mMutex->Unlock(); } } | |||||
| private: | |||||
| Locker(const Locker&); | |||||
| Locker& operator=(const Locker&); | |||||
| // Implementation | |||||
| private: | |||||
| CAMutex* mMutex; | |||||
| bool mNeedsRelease; | |||||
| }; | |||||
| // Unlocker | |||||
| class Unlocker | |||||
| { | |||||
| public: | |||||
| Unlocker(CAMutex& inMutex); | |||||
| ~Unlocker(); | |||||
| private: | |||||
| CAMutex& mMutex; | |||||
| bool mNeedsLock; | |||||
| // Hidden definitions of copy ctor, assignment operator | |||||
| Unlocker(const Unlocker& copy); // Not implemented | |||||
| Unlocker& operator=(const Unlocker& copy); // Not implemented | |||||
| }; | |||||
| // you can use this with Try - if you take the lock in try, pass in the outWasLocked var | |||||
| class Tryer { | |||||
| // Construction/Destruction | |||||
| public: | |||||
| Tryer (CAMutex &mutex) : mMutex(mutex), mNeedsRelease(false), mHasLock(false) { mHasLock = mMutex.Try (mNeedsRelease); } | |||||
| ~Tryer () { if (mNeedsRelease) mMutex.Unlock(); } | |||||
| bool HasLock () const { return mHasLock; } | |||||
| private: | |||||
| Tryer(const Tryer&); | |||||
| Tryer& operator=(const Tryer&); | |||||
| // Implementation | |||||
| private: | |||||
| CAMutex & mMutex; | |||||
| bool mNeedsRelease; | |||||
| bool mHasLock; | |||||
| }; | |||||
| }; | |||||
| #endif // __CAMutex_h__ | |||||
| @@ -0,0 +1,97 @@ | |||||
| /* | |||||
| File: CAReferenceCounted.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAReferenceCounted_h__ | |||||
| #define __CAReferenceCounted_h__ | |||||
| #include "CAAtomic.h" | |||||
| // base class for reference-counted objects | |||||
| class CAReferenceCounted { | |||||
| public: | |||||
| CAReferenceCounted() : mRefCount(1) {} | |||||
| void retain() { CAAtomicIncrement32(&mRefCount); } | |||||
| void release() | |||||
| { | |||||
| SInt32 rc = CAAtomicDecrement32(&mRefCount); | |||||
| if (rc == 0) { | |||||
| releaseObject(); | |||||
| } | |||||
| } | |||||
| class Retainer { | |||||
| public: | |||||
| Retainer(CAReferenceCounted *obj) : mObject(obj) { mObject->retain(); } | |||||
| ~Retainer() { mObject->release(); } | |||||
| private: | |||||
| CAReferenceCounted * mObject; | |||||
| }; | |||||
| protected: | |||||
| virtual ~CAReferenceCounted() { } | |||||
| virtual void releaseObject () | |||||
| { | |||||
| delete this; | |||||
| } | |||||
| #if DEBUG | |||||
| public: | |||||
| #endif | |||||
| SInt32 GetReferenceCount() const { return mRefCount; } | |||||
| private: | |||||
| SInt32 mRefCount; | |||||
| CAReferenceCounted(const CAReferenceCounted &a); | |||||
| CAReferenceCounted &operator=(const CAReferenceCounted &a); | |||||
| }; | |||||
| #endif // __CAReferenceCounted_h__ | |||||
| @@ -0,0 +1,879 @@ | |||||
| /* | |||||
| File: CAStreamBasicDescription.cpp | |||||
| Abstract: CAStreamBasicDescription.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "CAStreamBasicDescription.h" | |||||
| #include "CAMath.h" | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreFoundation/CFByteOrder.h> | |||||
| #else | |||||
| #include <CFByteOrder.h> | |||||
| #endif | |||||
| #pragma mark This file needs to compile on earlier versions of the OS, so please keep that in mind when editing it | |||||
| char *CAStringForOSType (OSType t, char *writeLocation, size_t bufsize) | |||||
| { | |||||
| if (bufsize > 0) { | |||||
| char *p = writeLocation, *pend = writeLocation + bufsize; | |||||
| union { UInt32 i; unsigned char str[4]; } u; | |||||
| unsigned char *q = u.str; | |||||
| u.i = CFSwapInt32HostToBig(t); | |||||
| bool hasNonPrint = false; | |||||
| for (int i = 0; i < 4; ++i) { | |||||
| if (!(isprint(*q) && *q != '\\')) { | |||||
| hasNonPrint = true; | |||||
| break; | |||||
| } | |||||
| q++; | |||||
| } | |||||
| q = u.str; | |||||
| if (hasNonPrint) | |||||
| p += snprintf (p, pend - p, "0x"); | |||||
| else if (p < pend) | |||||
| *p++ = '\''; | |||||
| for (int i = 0; i < 4 && p < pend; ++i) { | |||||
| if (hasNonPrint) { | |||||
| p += snprintf(p, pend - p, "%02X", *q++); | |||||
| } else { | |||||
| *p++ = *q++; | |||||
| } | |||||
| } | |||||
| if (!hasNonPrint && p < pend) | |||||
| *p++ = '\''; | |||||
| if (p >= pend) p -= 1; | |||||
| *p = '\0'; | |||||
| } | |||||
| return writeLocation; | |||||
| } | |||||
| const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 }; | |||||
| CAStreamBasicDescription::CAStreamBasicDescription() | |||||
| { | |||||
| memset (this, 0, sizeof(AudioStreamBasicDescription)); | |||||
| } | |||||
| CAStreamBasicDescription::CAStreamBasicDescription(const AudioStreamBasicDescription &desc) | |||||
| { | |||||
| SetFrom(desc); | |||||
| } | |||||
| CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID, | |||||
| UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, | |||||
| UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, | |||||
| UInt32 inBitsPerChannel, UInt32 inFormatFlags) | |||||
| { | |||||
| mSampleRate = inSampleRate; | |||||
| mFormatID = inFormatID; | |||||
| mBytesPerPacket = inBytesPerPacket; | |||||
| mFramesPerPacket = inFramesPerPacket; | |||||
| mBytesPerFrame = inBytesPerFrame; | |||||
| mChannelsPerFrame = inChannelsPerFrame; | |||||
| mBitsPerChannel = inBitsPerChannel; | |||||
| mFormatFlags = inFormatFlags; | |||||
| mReserved = 0; | |||||
| } | |||||
| char *CAStreamBasicDescription::AsString(char *buf, size_t _bufsize, bool brief /*=false*/) const | |||||
| { | |||||
| int bufsize = (int)_bufsize; // must be signed to protect against overflow | |||||
| char *theBuffer = buf; | |||||
| int nc; | |||||
| char formatID[24]; | |||||
| CAStringForOSType(mFormatID, formatID, sizeof(formatID)); | |||||
| if (brief) { | |||||
| CommonPCMFormat com; | |||||
| bool interleaved; | |||||
| if (IdentifyCommonPCMFormat(com, &interleaved) && com != kPCMFormatOther) { | |||||
| const char *desc; | |||||
| switch (com) { | |||||
| case kPCMFormatInt16: | |||||
| desc = "Int16"; | |||||
| break; | |||||
| case kPCMFormatFixed824: | |||||
| desc = "Int8.24"; | |||||
| break; | |||||
| case kPCMFormatFloat32: | |||||
| desc = "Float32"; | |||||
| break; | |||||
| case kPCMFormatFloat64: | |||||
| desc = "Float64"; | |||||
| break; | |||||
| default: | |||||
| desc = NULL; | |||||
| break; | |||||
| } | |||||
| if (desc) { | |||||
| const char *inter =""; | |||||
| if (mChannelsPerFrame > 1) | |||||
| inter = !interleaved ? ", non-inter" : ", inter"; | |||||
| snprintf(buf, static_cast<size_t>(bufsize), "%2d ch, %6.0f Hz, %s%s", (int)mChannelsPerFrame, mSampleRate, desc, inter); | |||||
| return theBuffer; | |||||
| } | |||||
| } | |||||
| if (mChannelsPerFrame == 0 && mSampleRate == 0.0 && mFormatID == 0) { | |||||
| snprintf(buf, static_cast<size_t>(bufsize), "%2d ch, %6.0f Hz", (int)mChannelsPerFrame, mSampleRate); | |||||
| return theBuffer; | |||||
| } | |||||
| } | |||||
| nc = snprintf(buf, static_cast<size_t>(bufsize), "%2d ch, %6.0f Hz, %s (0x%08X) ", (int)NumberChannels(), mSampleRate, formatID, (int)mFormatFlags); | |||||
| buf += nc; if ((bufsize -= nc) <= 0) goto exit; | |||||
| if (mFormatID == kAudioFormatLinearPCM) { | |||||
| bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat); | |||||
| int wordSize = static_cast<int>(SampleWordSize()); | |||||
| const char *endian = (wordSize > 1) ? | |||||
| ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : ""; | |||||
| const char *sign = isInt ? | |||||
| ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : ""; | |||||
| const char *floatInt = isInt ? "integer" : "float"; | |||||
| char packed[32]; | |||||
| if (wordSize > 0 && PackednessIsSignificant()) { | |||||
| if (mFormatFlags & kLinearPCMFormatFlagIsPacked) | |||||
| snprintf(packed, sizeof(packed), "packed in %d bytes", wordSize); | |||||
| else | |||||
| snprintf(packed, sizeof(packed), "unpacked in %d bytes", wordSize); | |||||
| } else | |||||
| packed[0] = '\0'; | |||||
| const char *align = (wordSize > 0 && AlignmentIsSignificant()) ? | |||||
| ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : ""; | |||||
| const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : ""; | |||||
| const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : ""; | |||||
| char bitdepth[20]; | |||||
| int fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift; | |||||
| if (fracbits > 0) | |||||
| snprintf(bitdepth, sizeof(bitdepth), "%d.%d", (int)mBitsPerChannel - fracbits, fracbits); | |||||
| else | |||||
| snprintf(bitdepth, sizeof(bitdepth), "%d", (int)mBitsPerChannel); | |||||
| /*nc =*/ snprintf(buf, static_cast<size_t>(bufsize), "%s-bit%s%s %s%s%s%s%s", | |||||
| bitdepth, endian, sign, floatInt, | |||||
| commaSpace, packed, align, deinter); | |||||
| // buf += nc; if ((bufsize -= nc) <= 0) goto exit; | |||||
| } else if (mFormatID == kAudioFormatAppleLossless) { | |||||
| int sourceBits = 0; | |||||
| switch (mFormatFlags) | |||||
| { | |||||
| case 1: // kAppleLosslessFormatFlag_16BitSourceData | |||||
| sourceBits = 16; | |||||
| break; | |||||
| case 2: // kAppleLosslessFormatFlag_20BitSourceData | |||||
| sourceBits = 20; | |||||
| break; | |||||
| case 3: // kAppleLosslessFormatFlag_24BitSourceData | |||||
| sourceBits = 24; | |||||
| break; | |||||
| case 4: // kAppleLosslessFormatFlag_32BitSourceData | |||||
| sourceBits = 32; | |||||
| break; | |||||
| } | |||||
| if (sourceBits) | |||||
| nc = snprintf(buf, static_cast<size_t>(bufsize), "from %d-bit source, ", sourceBits); | |||||
| else | |||||
| nc = snprintf(buf, static_cast<size_t>(bufsize), "from UNKNOWN source bit depth, "); | |||||
| buf += nc; if ((bufsize -= nc) <= 0) goto exit; | |||||
| /*nc =*/ snprintf(buf, static_cast<size_t>(bufsize), "%d frames/packet", (int)mFramesPerPacket); | |||||
| // buf += nc; if ((bufsize -= nc) <= 0) goto exit; | |||||
| } | |||||
| else | |||||
| /*nc =*/ snprintf(buf, static_cast<size_t>(bufsize), "%d bits/channel, %d bytes/packet, %d frames/packet, %d bytes/frame", | |||||
| (int)mBitsPerChannel, (int)mBytesPerPacket, (int)mFramesPerPacket, (int)mBytesPerFrame); | |||||
| exit: | |||||
| return theBuffer; | |||||
| } | |||||
| void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription) | |||||
| { | |||||
| // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format | |||||
| if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0)) | |||||
| { | |||||
| // the canonical linear PCM format | |||||
| ioDescription.mFormatFlags = kAudioFormatFlagsCanonical; | |||||
| ioDescription.mBytesPerPacket = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame; | |||||
| ioDescription.mFramesPerPacket = 1; | |||||
| ioDescription.mBytesPerFrame = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame; | |||||
| ioDescription.mBitsPerChannel = 8 * SizeOf32(AudioSampleType); | |||||
| } | |||||
| } | |||||
| void CAStreamBasicDescription::NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription) | |||||
| { | |||||
| // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format | |||||
| if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0)) | |||||
| { | |||||
| // the canonical linear PCM format | |||||
| ioDescription.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked; | |||||
| if(inNativeEndian) | |||||
| { | |||||
| #if TARGET_RT_BIG_ENDIAN | |||||
| ioDescription.mFormatFlags |= kAudioFormatFlagIsBigEndian; | |||||
| #endif | |||||
| } | |||||
| else | |||||
| { | |||||
| #if TARGET_RT_LITTLE_ENDIAN | |||||
| ioDescription.mFormatFlags |= kAudioFormatFlagIsBigEndian; | |||||
| #endif | |||||
| } | |||||
| ioDescription.mBytesPerPacket = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame; | |||||
| ioDescription.mFramesPerPacket = 1; | |||||
| ioDescription.mBytesPerFrame = SizeOf32(AudioSampleType) * ioDescription.mChannelsPerFrame; | |||||
| ioDescription.mBitsPerChannel = 8 * SizeOf32(AudioSampleType); | |||||
| } | |||||
| } | |||||
| void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription) | |||||
| { | |||||
| ioDescription.mSampleRate = 0; | |||||
| ioDescription.mFormatID = 0; | |||||
| ioDescription.mBytesPerPacket = 0; | |||||
| ioDescription.mFramesPerPacket = 0; | |||||
| ioDescription.mBytesPerFrame = 0; | |||||
| ioDescription.mChannelsPerFrame = 0; | |||||
| ioDescription.mBitsPerChannel = 0; | |||||
| ioDescription.mFormatFlags = 0; | |||||
| } | |||||
| void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription) | |||||
| { | |||||
| if(fiszero(ioDescription.mSampleRate)) | |||||
| { | |||||
| ioDescription.mSampleRate = inTemplateDescription.mSampleRate; | |||||
| } | |||||
| if(ioDescription.mFormatID == 0) | |||||
| { | |||||
| ioDescription.mFormatID = inTemplateDescription.mFormatID; | |||||
| } | |||||
| if(ioDescription.mFormatFlags == 0) | |||||
| { | |||||
| ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags; | |||||
| } | |||||
| if(ioDescription.mBytesPerPacket == 0) | |||||
| { | |||||
| ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket; | |||||
| } | |||||
| if(ioDescription.mFramesPerPacket == 0) | |||||
| { | |||||
| ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket; | |||||
| } | |||||
| if(ioDescription.mBytesPerFrame == 0) | |||||
| { | |||||
| ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame; | |||||
| } | |||||
| if(ioDescription.mChannelsPerFrame == 0) | |||||
| { | |||||
| ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame; | |||||
| } | |||||
| if(ioDescription.mBitsPerChannel == 0) | |||||
| { | |||||
| ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel; | |||||
| } | |||||
| } | |||||
| void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate) | |||||
| { | |||||
| if(inIncludeSampleRate) | |||||
| { | |||||
| int theCharactersWritten = snprintf(outName, inMaxNameLength, "%.0f ", inDescription.mSampleRate); | |||||
| outName += theCharactersWritten; | |||||
| inMaxNameLength -= static_cast<UInt32>(theCharactersWritten); | |||||
| } | |||||
| switch(inDescription.mFormatID) | |||||
| { | |||||
| case kAudioFormatLinearPCM: | |||||
| { | |||||
| const char* theEndianString = NULL; | |||||
| if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) | |||||
| { | |||||
| #if TARGET_RT_LITTLE_ENDIAN | |||||
| theEndianString = "Big Endian"; | |||||
| #endif | |||||
| } | |||||
| else | |||||
| { | |||||
| #if TARGET_RT_BIG_ENDIAN | |||||
| theEndianString = "Little Endian"; | |||||
| #endif | |||||
| } | |||||
| const char* theKindString = NULL; | |||||
| if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0) | |||||
| { | |||||
| theKindString = (inAbbreviate ? "Float" : "Floating Point"); | |||||
| } | |||||
| else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) | |||||
| { | |||||
| theKindString = (inAbbreviate ? "SInt" : "Signed Integer"); | |||||
| } | |||||
| else | |||||
| { | |||||
| theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer"); | |||||
| } | |||||
| const char* thePackingString = NULL; | |||||
| if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0) | |||||
| { | |||||
| if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) | |||||
| { | |||||
| thePackingString = "High"; | |||||
| } | |||||
| else | |||||
| { | |||||
| thePackingString = "Low"; | |||||
| } | |||||
| } | |||||
| const char* theMixabilityString = NULL; | |||||
| if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0) | |||||
| { | |||||
| theMixabilityString = "Mixable"; | |||||
| } | |||||
| else | |||||
| { | |||||
| theMixabilityString = "Unmixable"; | |||||
| } | |||||
| if(inAbbreviate) | |||||
| { | |||||
| if(theEndianString != NULL) | |||||
| { | |||||
| if(thePackingString != NULL) | |||||
| { | |||||
| snprintf(outName, inMaxNameLength, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); | |||||
| } | |||||
| else | |||||
| { | |||||
| snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| if(thePackingString != NULL) | |||||
| { | |||||
| snprintf(outName, inMaxNameLength, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8)); | |||||
| } | |||||
| else | |||||
| { | |||||
| snprintf(outName, inMaxNameLength, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel); | |||||
| } | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| if(theEndianString != NULL) | |||||
| { | |||||
| if(thePackingString != NULL) | |||||
| { | |||||
| snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); | |||||
| } | |||||
| else | |||||
| { | |||||
| snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| if(thePackingString != NULL) | |||||
| { | |||||
| snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8); | |||||
| } | |||||
| else | |||||
| { | |||||
| snprintf(outName, inMaxNameLength, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| break; | |||||
| case kAudioFormatAC3: | |||||
| strlcpy(outName, "AC-3", sizeof(outName)); | |||||
| break; | |||||
| case kAudioFormat60958AC3: | |||||
| strlcpy(outName, "AC-3 for SPDIF", sizeof(outName)); | |||||
| break; | |||||
| default: | |||||
| CACopy4CCToCString(outName, inDescription.mFormatID); | |||||
| break; | |||||
| }; | |||||
| } | |||||
| #if CoreAudio_Debug | |||||
| #include "CALogMacros.h" | |||||
| void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc) | |||||
| { | |||||
| PrintFloat (" Sample Rate: ", inDesc.mSampleRate); | |||||
| Print4CharCode (" Format ID: ", inDesc.mFormatID); | |||||
| PrintHex (" Format Flags: ", inDesc.mFormatFlags); | |||||
| PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket); | |||||
| PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket); | |||||
| PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame); | |||||
| PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame); | |||||
| PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel); | |||||
| } | |||||
| #endif | |||||
| bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) | |||||
| { | |||||
| bool theAnswer = false; | |||||
| bool isDone = false; | |||||
| // note that if either side is 0, that field is skipped | |||||
| // format ID is the first order sort | |||||
| if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0))) | |||||
| { | |||||
| if(x.mFormatID != y.mFormatID) | |||||
| { | |||||
| // formats are sorted numerically except that linear | |||||
| // PCM is always first | |||||
| if(x.mFormatID == kAudioFormatLinearPCM) | |||||
| { | |||||
| theAnswer = true; | |||||
| } | |||||
| else if(y.mFormatID == kAudioFormatLinearPCM) | |||||
| { | |||||
| theAnswer = false; | |||||
| } | |||||
| else | |||||
| { | |||||
| theAnswer = x.mFormatID < y.mFormatID; | |||||
| } | |||||
| isDone = true; | |||||
| } | |||||
| } | |||||
| // mixable is always better than non-mixable for linear PCM and should be the second order sort item | |||||
| if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) | |||||
| { | |||||
| if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0)) | |||||
| { | |||||
| theAnswer = true; | |||||
| isDone = true; | |||||
| } | |||||
| else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0)) | |||||
| { | |||||
| theAnswer = false; | |||||
| isDone = true; | |||||
| } | |||||
| } | |||||
| // floating point vs integer for linear PCM only | |||||
| if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM))) | |||||
| { | |||||
| if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat)) | |||||
| { | |||||
| // floating point is better than integer | |||||
| theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat; | |||||
| isDone = true; | |||||
| } | |||||
| } | |||||
| // bit depth | |||||
| if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0))) | |||||
| { | |||||
| if(x.mBitsPerChannel != y.mBitsPerChannel) | |||||
| { | |||||
| // deeper bit depths are higher quality | |||||
| theAnswer = x.mBitsPerChannel < y.mBitsPerChannel; | |||||
| isDone = true; | |||||
| } | |||||
| } | |||||
| // sample rate | |||||
| if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate)) | |||||
| { | |||||
| if(fnotequal(x.mSampleRate, y.mSampleRate)) | |||||
| { | |||||
| // higher sample rates are higher quality | |||||
| theAnswer = x.mSampleRate < y.mSampleRate; | |||||
| isDone = true; | |||||
| } | |||||
| } | |||||
| // number of channels | |||||
| if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0))) | |||||
| { | |||||
| if(x.mChannelsPerFrame != y.mChannelsPerFrame) | |||||
| { | |||||
| // more channels is higher quality | |||||
| theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame; | |||||
| //isDone = true; | |||||
| } | |||||
| } | |||||
| return theAnswer; | |||||
| } | |||||
| void CAStreamBasicDescription::ModifyFormatFlagsForMatching(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y, UInt32& xFlags, UInt32& yFlags, bool converterOnly ) | |||||
| { | |||||
| // match wildcards | |||||
| if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0) | |||||
| { | |||||
| // Obliterate all flags. | |||||
| xFlags = yFlags = 0; | |||||
| return; | |||||
| } | |||||
| if (x.mFormatID == kAudioFormatLinearPCM) { | |||||
| // knock off the all clear flag | |||||
| xFlags = xFlags & ~kAudioFormatFlagsAreAllClear; | |||||
| yFlags = yFlags & ~kAudioFormatFlagsAreAllClear; | |||||
| // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit. | |||||
| if (xFlags & yFlags & kAudioFormatFlagIsPacked) { | |||||
| xFlags = xFlags & ~static_cast<UInt32>(kAudioFormatFlagIsAlignedHigh); | |||||
| yFlags = yFlags & ~static_cast<UInt32>(kAudioFormatFlagIsAlignedHigh); | |||||
| } | |||||
| // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit. | |||||
| if (xFlags & yFlags & kAudioFormatFlagIsFloat) { | |||||
| xFlags = xFlags & ~static_cast<UInt32>(kAudioFormatFlagIsSignedInteger); | |||||
| yFlags = yFlags & ~static_cast<UInt32>(kAudioFormatFlagIsSignedInteger); | |||||
| } | |||||
| // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness | |||||
| if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) | |||||
| { | |||||
| xFlags = xFlags & ~static_cast<UInt32>(kAudioFormatFlagIsBigEndian); | |||||
| } | |||||
| if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked)) | |||||
| { | |||||
| yFlags = yFlags & ~static_cast<UInt32>(kAudioFormatFlagIsBigEndian); | |||||
| } | |||||
| // if the number of channels is 1, we don't care about non-interleavedness | |||||
| if (x.mChannelsPerFrame == 1 && y.mChannelsPerFrame == 1) { | |||||
| xFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsNonInterleaved); | |||||
| yFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsNonInterleaved); | |||||
| } | |||||
| if (converterOnly) { | |||||
| CAStreamBasicDescription cas_x = CAStreamBasicDescription(x); | |||||
| CAStreamBasicDescription cas_y = CAStreamBasicDescription(y); | |||||
| if (!cas_x.PackednessIsSignificant() && !cas_y.PackednessIsSignificant()) { | |||||
| xFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsPacked); | |||||
| yFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsPacked); | |||||
| } | |||||
| if (!cas_x.AlignmentIsSignificant() && !cas_y.AlignmentIsSignificant()) { | |||||
| xFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsAlignedHigh); | |||||
| yFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsAlignedHigh); | |||||
| } | |||||
| // We don't care about whether the streams are mixable in this case | |||||
| xFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsNonMixable); | |||||
| yFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsNonMixable); | |||||
| } | |||||
| } | |||||
| } | |||||
| static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) | |||||
| { | |||||
| UInt32 xFlags = x.mFormatFlags; | |||||
| UInt32 yFlags = y.mFormatFlags; | |||||
| CAStreamBasicDescription::ModifyFormatFlagsForMatching(x, y, xFlags, yFlags, false); | |||||
| return xFlags == yFlags; | |||||
| } | |||||
| bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) | |||||
| { | |||||
| // the semantics for equality are: | |||||
| // 1) Values must match exactly -- except for PCM format flags, see above. | |||||
| // 2) wildcard's are ignored in the comparison | |||||
| #define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name)) | |||||
| return | |||||
| // check all but the format flags | |||||
| CAStreamBasicDescription::FlagIndependentEquivalence(x, y) | |||||
| // check the format flags | |||||
| && MatchFormatFlags(x, y); | |||||
| } | |||||
| bool CAStreamBasicDescription::FlagIndependentEquivalence(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y) | |||||
| { | |||||
| return | |||||
| // check the sample rate | |||||
| (fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate)) | |||||
| // check the format ids | |||||
| && MATCH(mFormatID) | |||||
| // check the bytes per packet | |||||
| && MATCH(mBytesPerPacket) | |||||
| // check the frames per packet | |||||
| && MATCH(mFramesPerPacket) | |||||
| // check the bytes per frame | |||||
| && MATCH(mBytesPerFrame) | |||||
| // check the channels per frame | |||||
| && MATCH(mChannelsPerFrame) | |||||
| // check the channels per frame | |||||
| && MATCH(mBitsPerChannel) ; | |||||
| } | |||||
| bool CAStreamBasicDescription::IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards) const | |||||
| { | |||||
| if (interpretingWildcards) | |||||
| return *this == other; | |||||
| return memcmp(this, &other, offsetof(AudioStreamBasicDescription, mReserved)) == 0; | |||||
| } | |||||
| bool CAStreamBasicDescription::IsFunctionallyEquivalent(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y) | |||||
| { | |||||
| UInt32 xFlags = x.mFormatFlags, yFlags = y.mFormatFlags; | |||||
| CAStreamBasicDescription::ModifyFormatFlagsForMatching(x, y, xFlags, yFlags, true); | |||||
| return | |||||
| // check all but the format flags | |||||
| CAStreamBasicDescription::FlagIndependentEquivalence(x, y) | |||||
| // check the format flags with converter focus | |||||
| && (xFlags == yFlags); | |||||
| } | |||||
| bool SanityCheck(const AudioStreamBasicDescription& x) | |||||
| { | |||||
| // This function returns false if there are sufficiently insane values in any field. | |||||
| // It is very conservative so even some very unlikely values will pass. | |||||
| // This is just meant to catch the case where the data from a file is corrupted. | |||||
| return | |||||
| (x.mSampleRate >= 0.) | |||||
| && (x.mSampleRate < 3e6) // SACD sample rate is 2.8224 MHz | |||||
| && (x.mBytesPerPacket < 1000000) | |||||
| && (x.mFramesPerPacket < 1000000) | |||||
| && (x.mBytesPerFrame < 1000000) | |||||
| && (x.mChannelsPerFrame <= 1024) | |||||
| && (x.mBitsPerChannel <= 1024) | |||||
| && (x.mFormatID != 0) | |||||
| && !(x.mFormatID == kAudioFormatLinearPCM && (x.mFramesPerPacket != 1 || x.mBytesPerPacket != x.mBytesPerFrame)); | |||||
| } | |||||
| bool CAStreamBasicDescription::FromText(const char *inTextDesc, AudioStreamBasicDescription &fmt) | |||||
| { | |||||
| const char *p = inTextDesc; | |||||
| memset(&fmt, 0, sizeof(fmt)); | |||||
| bool isPCM = true; // until proven otherwise | |||||
| UInt32 pcmFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; | |||||
| if (p[0] == '-') // previously we required a leading dash on PCM formats | |||||
| ++p; | |||||
| if (p[0] == 'B' && p[1] == 'E') { | |||||
| pcmFlags |= kLinearPCMFormatFlagIsBigEndian; | |||||
| p += 2; | |||||
| } else if (p[0] == 'L' && p[1] == 'E') { | |||||
| p += 2; | |||||
| } else { | |||||
| // default is native-endian | |||||
| #if TARGET_RT_BIG_ENDIAN | |||||
| pcmFlags |= kLinearPCMFormatFlagIsBigEndian; | |||||
| #endif | |||||
| } | |||||
| if (p[0] == 'F') { | |||||
| pcmFlags = (pcmFlags & ~static_cast<UInt32>(kAudioFormatFlagIsSignedInteger)) | kAudioFormatFlagIsFloat; | |||||
| ++p; | |||||
| } else { | |||||
| if (p[0] == 'U') { | |||||
| pcmFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsSignedInteger); | |||||
| ++p; | |||||
| } | |||||
| if (p[0] == 'I') | |||||
| ++p; | |||||
| else { | |||||
| // it's not PCM; presumably some other format (NOT VALIDATED; use AudioFormat for that) | |||||
| isPCM = false; | |||||
| p = inTextDesc; // go back to the beginning | |||||
| char buf[4] = { ' ',' ',' ',' ' }; | |||||
| for (int i = 0; i < 4; ++i) { | |||||
| if (*p != '\\') { | |||||
| if ((buf[i] = *p++) == '\0') { | |||||
| // special-case for 'aac' | |||||
| if (i != 3) return false; | |||||
| --p; // keep pointing at the terminating null | |||||
| buf[i] = ' '; | |||||
| break; | |||||
| } | |||||
| } else { | |||||
| // "\xNN" is a hex byte | |||||
| if (*++p != 'x') return false; | |||||
| int x; | |||||
| if (sscanf(++p, "%02X", &x) != 1) return false; | |||||
| buf[i] = static_cast<char>(x); | |||||
| p += 2; | |||||
| } | |||||
| } | |||||
| if (strchr("-@/#", buf[3])) { | |||||
| // further special-casing for 'aac' | |||||
| buf[3] = ' '; | |||||
| --p; | |||||
| } | |||||
| memcpy(&fmt.mFormatID, buf, 4); | |||||
| fmt.mFormatID = CFSwapInt32BigToHost(fmt.mFormatID); | |||||
| } | |||||
| } | |||||
| if (isPCM) { | |||||
| fmt.mFormatID = kAudioFormatLinearPCM; | |||||
| fmt.mFormatFlags = pcmFlags; | |||||
| fmt.mFramesPerPacket = 1; | |||||
| fmt.mChannelsPerFrame = 1; | |||||
| UInt32 bitdepth = 0, fracbits = 0; | |||||
| while (isdigit(*p)) | |||||
| bitdepth = 10 * bitdepth + static_cast<UInt32>(*p++ - '0'); | |||||
| if (*p == '.') { | |||||
| ++p; | |||||
| if (!isdigit(*p)) { | |||||
| fprintf(stderr, "Expected fractional bits following '.'\n"); | |||||
| goto Bail; | |||||
| } | |||||
| while (isdigit(*p)) | |||||
| fracbits = 10 * fracbits + static_cast<UInt32>(*p++ - '0'); | |||||
| bitdepth += fracbits; | |||||
| fmt.mFormatFlags |= (fracbits << kLinearPCMFormatFlagsSampleFractionShift); | |||||
| } | |||||
| fmt.mBitsPerChannel = bitdepth; | |||||
| fmt.mBytesPerPacket = fmt.mBytesPerFrame = (bitdepth + 7) / 8; | |||||
| if (bitdepth & 7) { | |||||
| // assume unpacked. (packed odd bit depths are describable but not supported in AudioConverter.) | |||||
| fmt.mFormatFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsPacked); | |||||
| // alignment matters; default to high-aligned. use ':L_' for low. | |||||
| fmt.mFormatFlags |= kLinearPCMFormatFlagIsAlignedHigh; | |||||
| } | |||||
| } | |||||
| if (*p == '@') { | |||||
| ++p; | |||||
| while (isdigit(*p)) | |||||
| fmt.mSampleRate = 10 * fmt.mSampleRate + (*p++ - '0'); | |||||
| } | |||||
| if (*p == '/') { | |||||
| UInt32 flags = 0; | |||||
| while (true) { | |||||
| char c = *++p; | |||||
| if (c >= '0' && c <= '9') | |||||
| flags = (flags << 4) | static_cast<UInt32>(c - '0'); | |||||
| else if (c >= 'A' && c <= 'F') | |||||
| flags = (flags << 4) | static_cast<UInt32>(c - 'A' + 10); | |||||
| else if (c >= 'a' && c <= 'f') | |||||
| flags = (flags << 4) | static_cast<UInt32>(c - 'a' + 10); | |||||
| else break; | |||||
| } | |||||
| fmt.mFormatFlags = flags; | |||||
| } | |||||
| if (*p == '#') { | |||||
| ++p; | |||||
| while (isdigit(*p)) | |||||
| fmt.mFramesPerPacket = 10 * fmt.mFramesPerPacket + static_cast<UInt32>(*p++ - '0'); | |||||
| } | |||||
| if (*p == ':') { | |||||
| ++p; | |||||
| fmt.mFormatFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsPacked); | |||||
| if (*p == 'L') | |||||
| fmt.mFormatFlags &= ~static_cast<UInt32>(kLinearPCMFormatFlagIsAlignedHigh); | |||||
| else if (*p == 'H') | |||||
| fmt.mFormatFlags |= kLinearPCMFormatFlagIsAlignedHigh; | |||||
| else | |||||
| goto Bail; | |||||
| ++p; | |||||
| UInt32 bytesPerFrame = 0; | |||||
| while (isdigit(*p)) | |||||
| bytesPerFrame = 10 * bytesPerFrame + static_cast<UInt32>(*p++ - '0'); | |||||
| fmt.mBytesPerFrame = fmt.mBytesPerPacket = bytesPerFrame; | |||||
| } | |||||
| if (*p == ',') { | |||||
| ++p; | |||||
| int ch = 0; | |||||
| while (isdigit(*p)) | |||||
| ch = 10 * ch + (*p++ - '0'); | |||||
| fmt.mChannelsPerFrame = static_cast<UInt32>(ch); | |||||
| if (*p == 'D') { | |||||
| ++p; | |||||
| if (fmt.mFormatID != kAudioFormatLinearPCM) { | |||||
| fprintf(stderr, "non-interleaved flag invalid for non-PCM formats\n"); | |||||
| goto Bail; | |||||
| } | |||||
| fmt.mFormatFlags |= kAudioFormatFlagIsNonInterleaved; | |||||
| } else { | |||||
| if (*p == 'I') ++p; // default | |||||
| if (fmt.mFormatID == kAudioFormatLinearPCM) | |||||
| fmt.mBytesPerPacket = fmt.mBytesPerFrame *= static_cast<UInt32>(ch); | |||||
| } | |||||
| } | |||||
| if (*p != '\0') { | |||||
| fprintf(stderr, "extra characters at end of format string: %s\n", p); | |||||
| goto Bail; | |||||
| } | |||||
| return true; | |||||
| Bail: | |||||
| fprintf(stderr, "Invalid format string: %s\n", inTextDesc); | |||||
| fprintf(stderr, "Syntax of format strings is: \n"); | |||||
| return false; | |||||
| } | |||||
| const char *CAStreamBasicDescription::sTextParsingUsageString = | |||||
| "format[@sample_rate_hz][/format_flags][#frames_per_packet][:LHbytesPerFrame][,channelsDI].\n" | |||||
| "Format for PCM is [-][BE|LE]{F|I|UI}{bitdepth}; else a 4-char format code (e.g. aac, alac).\n"; | |||||
| @@ -0,0 +1,424 @@ | |||||
| /* | |||||
| File: CAStreamBasicDescription.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAStreamBasicDescription_h__ | |||||
| #define __CAStreamBasicDescription_h__ | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreAudio/CoreAudioTypes.h> | |||||
| #include <CoreFoundation/CoreFoundation.h> | |||||
| #else | |||||
| #include "CoreAudioTypes.h" | |||||
| #include "CoreFoundation.h" | |||||
| #endif | |||||
| #include "CADebugMacros.h" | |||||
| #include <string.h> // for memset, memcpy | |||||
| #include <stdio.h> // for FILE * | |||||
| #pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it | |||||
| extern char *CAStringForOSType (OSType t, char *writeLocation, size_t bufsize); | |||||
| // define Leopard specific symbols for backward compatibility if applicable | |||||
| #if COREAUDIOTYPES_VERSION < 1050 | |||||
| typedef Float32 AudioSampleType; | |||||
| enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked }; | |||||
| #endif | |||||
| #if COREAUDIOTYPES_VERSION < 1051 | |||||
| typedef Float32 AudioUnitSampleType; | |||||
| enum { | |||||
| kLinearPCMFormatFlagsSampleFractionShift = 7, | |||||
| kLinearPCMFormatFlagsSampleFractionMask = (0x3F << kLinearPCMFormatFlagsSampleFractionShift), | |||||
| }; | |||||
| #endif | |||||
| // define the IsMixable format flag for all versions of the system | |||||
| #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) | |||||
| enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable }; | |||||
| #else | |||||
| enum { kIsNonMixableFlag = (1L << 6) }; | |||||
| #endif | |||||
| //============================================================================= | |||||
| // CAStreamBasicDescription | |||||
| // | |||||
| // This is a wrapper class for the AudioStreamBasicDescription struct. | |||||
| // It adds a number of convenience routines, but otherwise adds nothing | |||||
| // to the footprint of the original struct. | |||||
| //============================================================================= | |||||
| class CAStreamBasicDescription : | |||||
| public AudioStreamBasicDescription | |||||
| { | |||||
| // Constants | |||||
| public: | |||||
| static const AudioStreamBasicDescription sEmpty; | |||||
| enum CommonPCMFormat { | |||||
| kPCMFormatOther = 0, | |||||
| kPCMFormatFloat32 = 1, | |||||
| kPCMFormatInt16 = 2, | |||||
| kPCMFormatFixed824 = 3, | |||||
| kPCMFormatFloat64 = 4 | |||||
| }; | |||||
| // Construction/Destruction | |||||
| public: | |||||
| CAStreamBasicDescription(); | |||||
| CAStreamBasicDescription(const AudioStreamBasicDescription &desc); | |||||
| CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID, | |||||
| UInt32 inBytesPerPacket, UInt32 inFramesPerPacket, | |||||
| UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame, | |||||
| UInt32 inBitsPerChannel, UInt32 inFormatFlags); | |||||
| CAStreamBasicDescription( double inSampleRate, UInt32 inNumChannels, CommonPCMFormat pcmf, bool inIsInterleaved) { | |||||
| unsigned wordsize; | |||||
| mSampleRate = inSampleRate; | |||||
| mFormatID = kAudioFormatLinearPCM; | |||||
| mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked; | |||||
| mFramesPerPacket = 1; | |||||
| mChannelsPerFrame = inNumChannels; | |||||
| mBytesPerFrame = mBytesPerPacket = 0; | |||||
| mReserved = 0; | |||||
| switch (pcmf) { | |||||
| default: | |||||
| return; | |||||
| case kPCMFormatFloat32: | |||||
| wordsize = 4; | |||||
| mFormatFlags |= kAudioFormatFlagIsFloat; | |||||
| break; | |||||
| case kPCMFormatFloat64: | |||||
| wordsize = 8; | |||||
| mFormatFlags |= kAudioFormatFlagIsFloat; | |||||
| break; | |||||
| case kPCMFormatInt16: | |||||
| wordsize = 2; | |||||
| mFormatFlags |= kAudioFormatFlagIsSignedInteger; | |||||
| break; | |||||
| case kPCMFormatFixed824: | |||||
| wordsize = 4; | |||||
| mFormatFlags |= kAudioFormatFlagIsSignedInteger | (24 << kLinearPCMFormatFlagsSampleFractionShift); | |||||
| break; | |||||
| } | |||||
| mBitsPerChannel = wordsize * 8; | |||||
| if (inIsInterleaved) | |||||
| mBytesPerFrame = mBytesPerPacket = wordsize * inNumChannels; | |||||
| else { | |||||
| mFormatFlags |= kAudioFormatFlagIsNonInterleaved; | |||||
| mBytesPerFrame = mBytesPerPacket = wordsize; | |||||
| } | |||||
| } | |||||
| // Assignment | |||||
| CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; } | |||||
| void SetFrom(const AudioStreamBasicDescription &desc) | |||||
| { | |||||
| memcpy(this, &desc, sizeof(AudioStreamBasicDescription)); | |||||
| } | |||||
| bool FromText(const char *inTextDesc) { return FromText(inTextDesc, *this); } | |||||
| static bool FromText(const char *inTextDesc, AudioStreamBasicDescription &outDesc); | |||||
| // return true if parsing was successful | |||||
| static const char *sTextParsingUsageString; | |||||
| // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |||||
| // | |||||
| // interrogation | |||||
| bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; } | |||||
| bool PackednessIsSignificant() const | |||||
| { | |||||
| Assert(IsPCM(), "PackednessIsSignificant only applies for PCM"); | |||||
| return (SampleWordSize() << 3) != mBitsPerChannel; | |||||
| } | |||||
| bool AlignmentIsSignificant() const | |||||
| { | |||||
| return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0; | |||||
| } | |||||
| bool IsInterleaved() const | |||||
| { | |||||
| return !(mFormatFlags & kAudioFormatFlagIsNonInterleaved); | |||||
| } | |||||
| bool IsSignedInteger() const | |||||
| { | |||||
| return IsPCM() && (mFormatFlags & kAudioFormatFlagIsSignedInteger); | |||||
| } | |||||
| bool IsFloat() const | |||||
| { | |||||
| return IsPCM() && (mFormatFlags & kAudioFormatFlagIsFloat); | |||||
| } | |||||
| bool IsNativeEndian() const | |||||
| { | |||||
| return (mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian; | |||||
| } | |||||
| // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these: | |||||
| UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; } | |||||
| UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; } | |||||
| UInt32 NumberChannels() const { return mChannelsPerFrame; } | |||||
| UInt32 SampleWordSize() const { | |||||
| return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0; | |||||
| } | |||||
| UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; } | |||||
| UInt32 BytesToFrames(UInt32 nbytes) const { | |||||
| Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames"); | |||||
| return nbytes / mBytesPerFrame; | |||||
| } | |||||
| bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const | |||||
| { | |||||
| return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved(); | |||||
| } | |||||
| bool IdentifyCommonPCMFormat(CommonPCMFormat &outFormat, bool *outIsInterleaved=NULL) const | |||||
| { // return true if it's a valid PCM format. | |||||
| outFormat = kPCMFormatOther; | |||||
| // trap out patently invalid formats. | |||||
| if (mFormatID != kAudioFormatLinearPCM || mFramesPerPacket != 1 || mBytesPerFrame != mBytesPerPacket || mBitsPerChannel/8 > mBytesPerFrame || mChannelsPerFrame == 0) | |||||
| return false; | |||||
| bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; | |||||
| if (outIsInterleaved != NULL) *outIsInterleaved = interleaved; | |||||
| unsigned wordsize = mBytesPerFrame; | |||||
| if (interleaved) { | |||||
| if (wordsize % mChannelsPerFrame != 0) return false; | |||||
| wordsize /= mChannelsPerFrame; | |||||
| } | |||||
| if ((mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian | |||||
| && wordsize * 8 == mBitsPerChannel) { | |||||
| // packed and native endian, good | |||||
| if (mFormatFlags & kLinearPCMFormatFlagIsFloat) { | |||||
| // float: reject nonsense bits | |||||
| if (mFormatFlags & (kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagsSampleFractionMask)) | |||||
| return false; | |||||
| if (wordsize == 4) | |||||
| outFormat = kPCMFormatFloat32; | |||||
| if (wordsize == 8) | |||||
| outFormat = kPCMFormatFloat64; | |||||
| } else if (mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) { | |||||
| // signed int | |||||
| unsigned fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift; | |||||
| if (wordsize == 4 && fracbits == 24) | |||||
| outFormat = kPCMFormatFixed824; | |||||
| else if (wordsize == 2 && fracbits == 0) | |||||
| outFormat = kPCMFormatInt16; | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| bool IsCommonFloat32(bool *outIsInterleaved=NULL) const { | |||||
| CommonPCMFormat fmt; | |||||
| return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat32; | |||||
| } | |||||
| bool IsCommonFloat64(bool *outIsInterleaved=NULL) const { | |||||
| CommonPCMFormat fmt; | |||||
| return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat64; | |||||
| } | |||||
| bool IsCommonFixed824(bool *outIsInterleaved=NULL) const { | |||||
| CommonPCMFormat fmt; | |||||
| return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFixed824; | |||||
| } | |||||
| bool IsCommonInt16(bool *outIsInterleaved=NULL) const { | |||||
| CommonPCMFormat fmt; | |||||
| return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatInt16; | |||||
| } | |||||
| // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |||||
| // | |||||
| // manipulation | |||||
| void SetCanonical(UInt32 nChannels, bool interleaved) | |||||
| // note: leaves sample rate untouched | |||||
| { | |||||
| mFormatID = kAudioFormatLinearPCM; | |||||
| UInt32 sampleSize = SizeOf32(AudioSampleType); | |||||
| mFormatFlags = kAudioFormatFlagsCanonical; | |||||
| mBitsPerChannel = 8 * sampleSize; | |||||
| mChannelsPerFrame = nChannels; | |||||
| mFramesPerPacket = 1; | |||||
| if (interleaved) | |||||
| mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize; | |||||
| else { | |||||
| mBytesPerPacket = mBytesPerFrame = sampleSize; | |||||
| mFormatFlags |= kAudioFormatFlagIsNonInterleaved; | |||||
| } | |||||
| } | |||||
| bool IsCanonical() const | |||||
| { | |||||
| if (mFormatID != kAudioFormatLinearPCM) return false; | |||||
| UInt32 reqFormatFlags; | |||||
| UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagsSampleFractionMask); | |||||
| bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0; | |||||
| unsigned sampleSize = SizeOf32(AudioSampleType); | |||||
| reqFormatFlags = kAudioFormatFlagsCanonical; | |||||
| UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize; | |||||
| return ((mFormatFlags & flagsMask) == reqFormatFlags | |||||
| && mBitsPerChannel == 8 * sampleSize | |||||
| && mFramesPerPacket == 1 | |||||
| && mBytesPerFrame == reqFrameSize | |||||
| && mBytesPerPacket == reqFrameSize); | |||||
| } | |||||
| void SetAUCanonical(UInt32 nChannels, bool interleaved) | |||||
| { | |||||
| mFormatID = kAudioFormatLinearPCM; | |||||
| #if CA_PREFER_FIXED_POINT | |||||
| mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift); | |||||
| #else | |||||
| mFormatFlags = kAudioFormatFlagsCanonical; | |||||
| #endif | |||||
| mChannelsPerFrame = nChannels; | |||||
| mFramesPerPacket = 1; | |||||
| mBitsPerChannel = 8 * SizeOf32(AudioUnitSampleType); | |||||
| if (interleaved) | |||||
| mBytesPerPacket = mBytesPerFrame = nChannels * SizeOf32(AudioUnitSampleType); | |||||
| else { | |||||
| mBytesPerPacket = mBytesPerFrame = SizeOf32(AudioUnitSampleType); | |||||
| mFormatFlags |= kAudioFormatFlagIsNonInterleaved; | |||||
| } | |||||
| } | |||||
| void ChangeNumberChannels(UInt32 nChannels, bool interleaved) | |||||
| // alter an existing format | |||||
| { | |||||
| Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats"); | |||||
| UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING | |||||
| if (wordSize == 0) | |||||
| wordSize = (mBitsPerChannel + 7) / 8; | |||||
| mChannelsPerFrame = nChannels; | |||||
| mFramesPerPacket = 1; | |||||
| if (interleaved) { | |||||
| mBytesPerPacket = mBytesPerFrame = nChannels * wordSize; | |||||
| mFormatFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsNonInterleaved); | |||||
| } else { | |||||
| mBytesPerPacket = mBytesPerFrame = wordSize; | |||||
| mFormatFlags |= kAudioFormatFlagIsNonInterleaved; | |||||
| } | |||||
| } | |||||
| // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |||||
| // | |||||
| // other | |||||
| bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const; | |||||
| static bool FlagIndependentEquivalence(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y); | |||||
| static bool IsFunctionallyEquivalent(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y); | |||||
| void Print() const { | |||||
| Print (stdout); | |||||
| } | |||||
| void Print(FILE* file) const { | |||||
| PrintFormat (file, "", "AudioStreamBasicDescription:"); | |||||
| } | |||||
| void PrintFormat(FILE *f, const char *indent, const char *name) const { | |||||
| char buf[256]; | |||||
| fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf))); | |||||
| } | |||||
| void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline | |||||
| char buf[256]; | |||||
| fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf))); | |||||
| } | |||||
| char * AsString(char *buf, size_t bufsize, bool brief=false) const; | |||||
| static void Print (const AudioStreamBasicDescription &inDesc) | |||||
| { | |||||
| CAStreamBasicDescription desc(inDesc); | |||||
| desc.Print (); | |||||
| } | |||||
| OSStatus Save(CFPropertyListRef *outData) const; | |||||
| OSStatus Restore(CFPropertyListRef &inData); | |||||
| // Operations | |||||
| static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); } | |||||
| static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription); | |||||
| static void NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription); | |||||
| static void ResetFormat(AudioStreamBasicDescription& ioDescription); | |||||
| static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription); | |||||
| static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate = false); | |||||
| static void ModifyFormatFlagsForMatching(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y, UInt32& xFlags, UInt32& yFlags, bool converterOnly); | |||||
| #if CoreAudio_Debug | |||||
| static void PrintToLog(const AudioStreamBasicDescription& inDesc); | |||||
| #endif | |||||
| }; | |||||
| bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); | |||||
| bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y); | |||||
| #if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600)) | |||||
| inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); } | |||||
| inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); } | |||||
| inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); } | |||||
| inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); } | |||||
| #endif | |||||
| bool SanityCheck(const AudioStreamBasicDescription& x); | |||||
| #endif // __CAStreamBasicDescription_h__ | |||||
| @@ -0,0 +1,233 @@ | |||||
| /* | |||||
| File: CAThreadSafeList.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAThreadSafeList_h__ | |||||
| #define __CAThreadSafeList_h__ | |||||
| #include "CAAtomicStack.h" | |||||
| // linked list of T's | |||||
| // T must define operator == | |||||
| template <class T> | |||||
| class TThreadSafeList { | |||||
| private: | |||||
| enum EEventType { kAdd, kRemove, kClear }; | |||||
| class Node { | |||||
| public: | |||||
| Node * mNext; | |||||
| EEventType mEventType; | |||||
| T mObject; | |||||
| Node *& next() { return mNext; } | |||||
| }; | |||||
| public: | |||||
| class iterator { | |||||
| public: | |||||
| iterator() { } | |||||
| iterator(Node *n) : mNode(n) { } | |||||
| bool operator == (const iterator &other) const { return this->mNode == other.mNode; } | |||||
| bool operator != (const iterator &other) const { return this->mNode != other.mNode; } | |||||
| T & operator * () const { return mNode->mObject; } | |||||
| iterator & operator ++ () { mNode = mNode->next(); return *this; } // preincrement | |||||
| iterator operator ++ (int) { iterator tmp = *this; mNode = mNode->next(); return tmp; } // postincrement | |||||
| private: | |||||
| Node * mNode; | |||||
| }; | |||||
| TThreadSafeList() { } | |||||
| ~TThreadSafeList() | |||||
| { | |||||
| mActiveList.free_all(); | |||||
| mPendingList.free_all(); | |||||
| mFreeList.free_all(); | |||||
| } | |||||
| // These may be called on any thread | |||||
| void deferred_add(const T &obj) // can be called on any thread | |||||
| { | |||||
| Node *node = AllocNode(); | |||||
| node->mEventType = kAdd; | |||||
| node->mObject = obj; | |||||
| mPendingList.push_atomic(node); | |||||
| //mPendingList.dump("pending after add"); | |||||
| } | |||||
| void deferred_remove(const T &obj) // can be called on any thread | |||||
| { | |||||
| Node *node = AllocNode(); | |||||
| node->mEventType = kRemove; | |||||
| node->mObject = obj; | |||||
| mPendingList.push_atomic(node); | |||||
| //mPendingList.dump("pending after remove"); | |||||
| } | |||||
| void deferred_clear() // can be called on any thread | |||||
| { | |||||
| Node *node = AllocNode(); | |||||
| node->mEventType = kClear; | |||||
| mPendingList.push_atomic(node); | |||||
| } | |||||
| // These must be called from only one thread | |||||
| void update() // must only be called from one thread | |||||
| { | |||||
| NodeStack reversed; | |||||
| Node *event, *node, *next; | |||||
| bool workDone = false; | |||||
| // reverse the events so they are in order | |||||
| event = mPendingList.pop_all(); | |||||
| while (event != NULL) { | |||||
| next = event->mNext; | |||||
| reversed.push_NA(event); | |||||
| event = next; | |||||
| workDone = true; | |||||
| } | |||||
| if (workDone) { | |||||
| //reversed.dump("pending popped"); | |||||
| //mActiveList.dump("active before update"); | |||||
| // now process them | |||||
| while ((event = reversed.pop_NA()) != NULL) { | |||||
| switch (event->mEventType) { | |||||
| case kAdd: | |||||
| { | |||||
| Node **pnode; | |||||
| bool needToInsert = true; | |||||
| for (pnode = mActiveList.phead(); *pnode != NULL; pnode = &node->mNext) { | |||||
| node = *pnode; | |||||
| if (node->mObject == event->mObject) { | |||||
| //printf("already active!!!\n"); | |||||
| FreeNode(event); | |||||
| needToInsert = false; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (needToInsert) { | |||||
| // link the new event in at the end of the active list | |||||
| *pnode = event; | |||||
| event->mNext = NULL; | |||||
| } | |||||
| } | |||||
| break; | |||||
| case kRemove: | |||||
| // find matching node in the active list, remove it | |||||
| for (Node **pnode = mActiveList.phead(); *pnode != NULL; ) { | |||||
| node = *pnode; | |||||
| if (node->mObject == event->mObject) { | |||||
| *pnode = node->mNext; // remove from linked list | |||||
| FreeNode(node); | |||||
| break; | |||||
| } | |||||
| pnode = &node->mNext; | |||||
| } | |||||
| // dispose the request node | |||||
| FreeNode(event); | |||||
| break; | |||||
| case kClear: | |||||
| for (node = mActiveList.head(); node != NULL; ) { | |||||
| next = node->mNext; | |||||
| FreeNode(node); | |||||
| node = next; | |||||
| } | |||||
| FreeNode(event); | |||||
| break; | |||||
| default: | |||||
| //printf("invalid node type %d!\n", event->mEventType); | |||||
| break; | |||||
| } | |||||
| } | |||||
| //mActiveList.dump("active after update"); | |||||
| } | |||||
| } | |||||
| iterator begin() const { | |||||
| //mActiveList.dump("active at begin"); | |||||
| return iterator(mActiveList.head()); | |||||
| } | |||||
| iterator end() const { return iterator(NULL); } | |||||
| private: | |||||
| Node * AllocNode() | |||||
| { | |||||
| Node *node = mFreeList.pop_atomic(); | |||||
| if (node == NULL) | |||||
| node = (Node *)CA_malloc(sizeof(Node)); | |||||
| return node; | |||||
| } | |||||
| void FreeNode(Node *node) | |||||
| { | |||||
| mFreeList.push_atomic(node); | |||||
| } | |||||
| private: | |||||
| class NodeStack : public TAtomicStack<Node> { | |||||
| public: | |||||
| void free_all() { | |||||
| Node *node; | |||||
| while ((node = this->pop_NA()) != NULL) | |||||
| free(node); | |||||
| } | |||||
| Node ** phead() { return &this->mHead; } | |||||
| Node * head() const { return this->mHead; } | |||||
| }; | |||||
| NodeStack mActiveList; // what's actually in the container - only accessed on one thread | |||||
| NodeStack mPendingList; // add or remove requests - threadsafe | |||||
| NodeStack mFreeList; // free nodes for reuse - threadsafe | |||||
| }; | |||||
| #endif // __CAThreadSafeList_h__ | |||||
| @@ -0,0 +1,194 @@ | |||||
| /* | |||||
| File: CAVectorUnit.cpp | |||||
| Abstract: CAVectorUnit.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "CAVectorUnit.h" | |||||
| #if !TARGET_OS_WIN32 | |||||
| #include <sys/sysctl.h> | |||||
| #elif HAS_IPP | |||||
| #include "ippdefs.h" | |||||
| #include "ippcore.h" | |||||
| #endif | |||||
| int gCAVectorUnitType = kVecUninitialized; | |||||
| #if TARGET_OS_WIN32 | |||||
| // Use cpuid to check if SSE2 is available. | |||||
| // Before calling this function make sure cpuid is available | |||||
| static SInt32 IsSSE2Available() | |||||
| { | |||||
| int return_value; | |||||
| { | |||||
| int r_edx; | |||||
| _asm | |||||
| { | |||||
| mov eax, 0x01 | |||||
| cpuid | |||||
| mov r_edx, edx | |||||
| } | |||||
| return_value = (r_edx >> 26) & 0x1; | |||||
| } | |||||
| return return_value; | |||||
| } | |||||
| // Use cpuid to check if SSE3 is available. | |||||
| // Before calling this function make sure cpuid is available | |||||
| static SInt32 IsSSE3Available() | |||||
| { | |||||
| SInt32 return_value; | |||||
| { | |||||
| SInt32 r_ecx; | |||||
| _asm | |||||
| { | |||||
| mov eax, 0x01 | |||||
| cpuid | |||||
| mov r_ecx, ecx | |||||
| } | |||||
| return_value = r_ecx & 0x1; | |||||
| } | |||||
| return return_value; | |||||
| } | |||||
| // Return true if the cpuid instruction is available. | |||||
| // The cpuid instruction is available if bit 21 in the EFLAGS register can be changed | |||||
| // This function may not work on Intel CPUs prior to Pentium (didn't test) | |||||
| static bool IsCpuidAvailable() | |||||
| { | |||||
| SInt32 return_value = 0x0; | |||||
| _asm{ | |||||
| pushfd ; //push original EFLAGS | |||||
| pop eax ; //get original EFLAGS | |||||
| mov ecx, eax ; //save original EFLAGS | |||||
| xor eax, 200000h ; //flip ID bit in EFLAGS | |||||
| push eax ; //save new EFLAGS value on stack | |||||
| popfd ; //replace current EFLAGS value | |||||
| pushfd ; //get new EFLAGS | |||||
| pop eax ; //store new EFLAGS in EAX | |||||
| xor eax, ecx ; | |||||
| je end_cpuid_identify ; //can't toggle ID bit | |||||
| mov return_value, 0x1; | |||||
| end_cpuid_identify: | |||||
| nop; | |||||
| } | |||||
| return return_value; | |||||
| } | |||||
| #endif | |||||
| SInt32 CAVectorUnit_Examine() | |||||
| { | |||||
| int result = kVecNone; | |||||
| #if TARGET_OS_WIN32 | |||||
| #if HAS_IPP | |||||
| // Initialize the static IPP library! This needs to be done before | |||||
| // any IPP function calls, otherwise we may have a performance penalty | |||||
| int status = ippStaticInit(); | |||||
| if ( status == ippStsNonIntelCpu ) | |||||
| { | |||||
| IppCpuType cpuType = ippGetCpuType(); | |||||
| if ( cpuType >= ippCpuSSE || cpuType <= ippCpuSSE42 ) | |||||
| ippStaticInitCpu( cpuType ); | |||||
| } | |||||
| #endif | |||||
| { | |||||
| // On Windows we use cpuid to detect the vector unit because it works on Intel and AMD. | |||||
| // The IPP library does not detect SSE on AMD processors. | |||||
| if (IsCpuidAvailable()) | |||||
| { | |||||
| if(IsSSE3Available()) | |||||
| { | |||||
| result = kVecSSE3; | |||||
| } | |||||
| else if(IsSSE2Available()) | |||||
| { | |||||
| result = kVecSSE2; | |||||
| } | |||||
| } | |||||
| } | |||||
| #elif TARGET_OS_MAC | |||||
| #if DEBUG | |||||
| if (getenv("CA_NoVector")) { | |||||
| fprintf(stderr, "CA_NoVector set; Vector unit optimized routines will be bypassed\n"); | |||||
| return result; | |||||
| } | |||||
| else | |||||
| #endif | |||||
| { | |||||
| #if (TARGET_CPU_PPC || TARGET_CPU_PPC64) | |||||
| int sels[2] = { CTL_HW, HW_VECTORUNIT }; | |||||
| int vType = 0; //0 == scalar only | |||||
| size_t length = sizeof(vType); | |||||
| int error = sysctl(sels, 2, &vType, &length, NULL, 0); | |||||
| if (!error && vType > 0) | |||||
| result = kVecAltivec; | |||||
| #elif (TARGET_CPU_X86 || TARGET_CPU_X86_64) | |||||
| static const struct { const char* kName; const int kVectype; } kStringVectypes[] = { | |||||
| { "hw.optional.avx1_0", kVecAVX1 }, { "hw.optional.sse3", kVecSSE3 }, { "hw.optional.sse2", kVecSSE2 } | |||||
| }; | |||||
| static const size_t kNumStringVectypes = sizeof(kStringVectypes)/sizeof(kStringVectypes[0]); | |||||
| int i = 0, answer = 0; | |||||
| while(i != kNumStringVectypes) | |||||
| { | |||||
| size_t length = sizeof(answer); | |||||
| int error = sysctlbyname(kStringVectypes[i].kName, &answer, &length, NULL, 0); | |||||
| if (!error && answer) | |||||
| { | |||||
| result = kStringVectypes[i].kVectype; | |||||
| break; | |||||
| } | |||||
| ++i; | |||||
| }; | |||||
| #elif CA_ARM_NEON | |||||
| result = kVecNeon; | |||||
| #endif | |||||
| } | |||||
| #endif | |||||
| gCAVectorUnitType = result; | |||||
| return result; | |||||
| } | |||||
| @@ -0,0 +1,101 @@ | |||||
| /* | |||||
| File: CAVectorUnit.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAVectorUnit_h__ | |||||
| #define __CAVectorUnit_h__ | |||||
| #include <TargetConditionals.h> | |||||
| #include "CAVectorUnitTypes.h" | |||||
| #include <stdlib.h> | |||||
| #include <stdio.h> | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreFoundation/CFBase.h> | |||||
| #else | |||||
| #include "CFBase.h" | |||||
| #endif | |||||
| // Unify checks for vector units. | |||||
| // Allow setting an environment variable "CA_NoVector" to turn off vectorized code at runtime (very useful for performance testing). | |||||
| extern int gCAVectorUnitType; | |||||
| #ifdef __cplusplus | |||||
| extern "C" { | |||||
| #endif | |||||
| extern SInt32 CAVectorUnit_Examine(); // expensive. use GetType() for lazy initialization and caching. | |||||
| static inline SInt32 CAVectorUnit_GetType() | |||||
| { | |||||
| int x = gCAVectorUnitType; | |||||
| return (x != kVecUninitialized) ? x : CAVectorUnit_Examine(); | |||||
| } | |||||
| static inline Boolean CAVectorUnit_HasVectorUnit() | |||||
| { | |||||
| return CAVectorUnit_GetType() > kVecNone; | |||||
| } | |||||
| #ifdef __cplusplus | |||||
| } | |||||
| #endif | |||||
| #ifdef __cplusplus | |||||
| class CAVectorUnit { | |||||
| public: | |||||
| static SInt32 GetVectorUnitType() { return CAVectorUnit_GetType(); } | |||||
| static bool HasVectorUnit() { return GetVectorUnitType() > kVecNone; } | |||||
| static bool HasAltivec() { return GetVectorUnitType() == kVecAltivec; } | |||||
| static bool HasSSE2() { return GetVectorUnitType() >= kVecSSE2; } | |||||
| static bool HasSSE3() { return GetVectorUnitType() >= kVecSSE3; } | |||||
| static bool HasAVX1() { return GetVectorUnitType() >= kVecAVX1; } | |||||
| static bool HasNeon() { return GetVectorUnitType() == kVecNeon; } | |||||
| }; | |||||
| #endif | |||||
| #endif // __CAVectorUnit_h__ | |||||
| @@ -0,0 +1,60 @@ | |||||
| /* | |||||
| File: CAVectorUnitTypes.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAVectorUnitTypes_h__ | |||||
| #define __CAVectorUnitTypes_h__ | |||||
| enum { | |||||
| kVecUninitialized = -1, | |||||
| kVecNone = 0, | |||||
| kVecAltivec = 1, | |||||
| kVecSSE2 = 100, | |||||
| kVecSSE3 = 101, | |||||
| kVecAVX1 = 110, | |||||
| kVecNeon = 200 | |||||
| }; | |||||
| #endif | |||||
| @@ -0,0 +1,361 @@ | |||||
| /* | |||||
| File: CAXException.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CAXException_h__ | |||||
| #define __CAXException_h__ | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreFoundation/CoreFoundation.h> | |||||
| #else | |||||
| #include <ConditionalMacros.h> | |||||
| #include <CoreFoundation.h> | |||||
| #endif | |||||
| #include "CADebugMacros.h" | |||||
| #include <ctype.h> | |||||
| //#include <stdio.h> | |||||
| #include <string.h> | |||||
| class CAX4CCString { | |||||
| public: | |||||
| CAX4CCString(OSStatus error) { | |||||
| // see if it appears to be a 4-char-code | |||||
| UInt32 beErr = CFSwapInt32HostToBig(error); | |||||
| char *str = mStr; | |||||
| memcpy(str + 1, &beErr, 4); | |||||
| if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { | |||||
| str[0] = str[5] = '\''; | |||||
| str[6] = '\0'; | |||||
| } else if (error > -200000 && error < 200000) | |||||
| // no, format it as an integer | |||||
| snprintf(str, sizeof(mStr), "%d", (int)error); | |||||
| else | |||||
| snprintf(str, sizeof(mStr), "0x%x", (int)error); | |||||
| } | |||||
| const char *get() const { return mStr; } | |||||
| operator const char *() const { return mStr; } | |||||
| private: | |||||
| char mStr[16]; | |||||
| }; | |||||
| class CAX4CCStringNoQuote { | |||||
| public: | |||||
| CAX4CCStringNoQuote(OSStatus error) { | |||||
| // see if it appears to be a 4-char-code | |||||
| UInt32 beErr = CFSwapInt32HostToBig(error); | |||||
| char *str = mStr; | |||||
| memcpy(str, &beErr, 4); | |||||
| if (isprint(str[0]) && isprint(str[1]) && isprint(str[2]) && isprint(str[3])) { | |||||
| str[4] = '\0'; | |||||
| } else if (error > -200000 && error < 200000) | |||||
| // no, format it as an integer | |||||
| snprintf(str, sizeof(mStr), "%d", (int)error); | |||||
| else | |||||
| snprintf(str, sizeof(mStr), "0x%x", (int)error); | |||||
| } | |||||
| const char *get() const { return mStr; } | |||||
| operator const char *() const { return mStr; } | |||||
| private: | |||||
| char mStr[16]; | |||||
| }; | |||||
| // An extended exception class that includes the name of the failed operation | |||||
| class CAXException { | |||||
| public: | |||||
| CAXException(const char *operation, OSStatus err) : | |||||
| mError(err) | |||||
| { | |||||
| if (operation == NULL) | |||||
| mOperation[0] = '\0'; | |||||
| else if (strlen(operation) >= sizeof(mOperation)) { | |||||
| memcpy(mOperation, operation, sizeof(mOperation) - 1); | |||||
| mOperation[sizeof(mOperation) - 1] = '\0'; | |||||
| } else | |||||
| strlcpy(mOperation, operation, sizeof(mOperation)); | |||||
| } | |||||
| char *FormatError(char *str, size_t strsize) const | |||||
| { | |||||
| return FormatError(str, strsize, mError); | |||||
| } | |||||
| char mOperation[256]; | |||||
| const OSStatus mError; | |||||
| // ------------------------------------------------- | |||||
| typedef void (*WarningHandler)(const char *msg, OSStatus err); | |||||
| static char *FormatError(char *str, size_t strsize, OSStatus error) | |||||
| { | |||||
| strlcpy(str, CAX4CCString(error), strsize); | |||||
| return str; | |||||
| } | |||||
| static void Warning(const char *s, OSStatus error) | |||||
| { | |||||
| if (sWarningHandler) | |||||
| (*sWarningHandler)(s, error); | |||||
| } | |||||
| static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; } | |||||
| private: | |||||
| static WarningHandler sWarningHandler; | |||||
| }; | |||||
| #if DEBUG || CoreAudio_Debug | |||||
| #define XThrowIfError(error, operation) \ | |||||
| do { \ | |||||
| OSStatus __err = error; \ | |||||
| if (__err) { \ | |||||
| DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\ | |||||
| __THROW_STOP; \ | |||||
| throw CAXException(operation, __err); \ | |||||
| } \ | |||||
| } while (0) | |||||
| #define XThrowIf(condition, error, operation) \ | |||||
| do { \ | |||||
| if (condition) { \ | |||||
| OSStatus __err = error; \ | |||||
| DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\ | |||||
| __THROW_STOP; \ | |||||
| throw CAXException(operation, __err); \ | |||||
| } \ | |||||
| } while (0) | |||||
| #define XRequireNoError(error, label) \ | |||||
| do { \ | |||||
| OSStatus __err = error; \ | |||||
| if (__err) { \ | |||||
| DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\ | |||||
| STOP; \ | |||||
| goto label; \ | |||||
| } \ | |||||
| } while (0) | |||||
| #define XAssert(assertion) \ | |||||
| do { \ | |||||
| if (!(assertion)) { \ | |||||
| DebugMessageN3("%s:%d: error: failed assertion: %s", __FILE__, __LINE__, #assertion); \ | |||||
| __ASSERT_STOP; \ | |||||
| } \ | |||||
| } while (0) | |||||
| #define XAssertNoError(error) \ | |||||
| do { \ | |||||
| OSStatus __err = error; \ | |||||
| if (__err) { \ | |||||
| DebugMessageN4("%s:%d: error %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\ | |||||
| STOP; \ | |||||
| } \ | |||||
| } while (0) | |||||
| #define ca_require_noerr(errorCode, exceptionLabel) \ | |||||
| do \ | |||||
| { \ | |||||
| int evalOnceErrorCode = (errorCode); \ | |||||
| if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ | |||||
| { \ | |||||
| DebugMessageN5("ca_require_noerr: [%s, %d] (goto %s;) %s:%d", \ | |||||
| #errorCode, evalOnceErrorCode, \ | |||||
| #exceptionLabel, \ | |||||
| __FILE__, \ | |||||
| __LINE__); \ | |||||
| goto exceptionLabel; \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #define ca_verify_noerr(errorCode) \ | |||||
| do \ | |||||
| { \ | |||||
| int evalOnceErrorCode = (errorCode); \ | |||||
| if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \ | |||||
| { \ | |||||
| DebugMessageN4("ca_verify_noerr: [%s, %d] %s:%d", \ | |||||
| #errorCode, evalOnceErrorCode, \ | |||||
| __FILE__, \ | |||||
| __LINE__); \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #define ca_debug_string(message) \ | |||||
| do \ | |||||
| { \ | |||||
| DebugMessageN3("ca_debug_string: %s %s:%d", \ | |||||
| message, \ | |||||
| __FILE__, \ | |||||
| __LINE__); \ | |||||
| } while ( 0 ) | |||||
| #define ca_verify(assertion) \ | |||||
| do \ | |||||
| { \ | |||||
| if ( __builtin_expect(!(assertion), 0) ) \ | |||||
| { \ | |||||
| DebugMessageN3("ca_verify: %s %s:%d", \ | |||||
| #assertion, \ | |||||
| __FILE__, \ | |||||
| __LINE__); \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #define ca_require(assertion, exceptionLabel) \ | |||||
| do \ | |||||
| { \ | |||||
| if ( __builtin_expect(!(assertion), 0) ) \ | |||||
| { \ | |||||
| DebugMessageN4("ca_require: %s %s %s:%d", \ | |||||
| #assertion, \ | |||||
| #exceptionLabel, \ | |||||
| __FILE__, \ | |||||
| __LINE__); \ | |||||
| goto exceptionLabel; \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #define ca_check(assertion) \ | |||||
| do \ | |||||
| { \ | |||||
| if ( __builtin_expect(!(assertion), 0) ) \ | |||||
| { \ | |||||
| DebugMessageN3("ca_check: %s %s:%d", \ | |||||
| #assertion, \ | |||||
| __FILE__, \ | |||||
| __LINE__); \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #else | |||||
| #define XThrowIfError(error, operation) \ | |||||
| do { \ | |||||
| OSStatus __err = error; \ | |||||
| if (__err) { \ | |||||
| throw CAXException(operation, __err); \ | |||||
| } \ | |||||
| } while (0) | |||||
| #define XThrowIf(condition, error, operation) \ | |||||
| do { \ | |||||
| if (condition) { \ | |||||
| OSStatus __err = error; \ | |||||
| throw CAXException(operation, __err); \ | |||||
| } \ | |||||
| } while (0) | |||||
| #define XRequireNoError(error, label) \ | |||||
| do { \ | |||||
| OSStatus __err = error; \ | |||||
| if (__err) { \ | |||||
| goto label; \ | |||||
| } \ | |||||
| } while (0) | |||||
| #define XAssert(assertion) \ | |||||
| do { \ | |||||
| if (!(assertion)) { \ | |||||
| } \ | |||||
| } while (0) | |||||
| #define XAssertNoError(error) \ | |||||
| do { \ | |||||
| /*OSStatus __err =*/ error; \ | |||||
| } while (0) | |||||
| #define ca_require_noerr(errorCode, exceptionLabel) \ | |||||
| do \ | |||||
| { \ | |||||
| if ( __builtin_expect(0 != (errorCode), 0) ) \ | |||||
| { \ | |||||
| goto exceptionLabel; \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #define ca_verify_noerr(errorCode) \ | |||||
| do \ | |||||
| { \ | |||||
| if ( 0 != (errorCode) ) \ | |||||
| { \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #define ca_debug_string(message) | |||||
| #define ca_verify(assertion) \ | |||||
| do \ | |||||
| { \ | |||||
| if ( !(assertion) ) \ | |||||
| { \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #define ca_require(assertion, exceptionLabel) \ | |||||
| do \ | |||||
| { \ | |||||
| if ( __builtin_expect(!(assertion), 0) ) \ | |||||
| { \ | |||||
| goto exceptionLabel; \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #define ca_check(assertion) \ | |||||
| do \ | |||||
| { \ | |||||
| if ( !(assertion) ) \ | |||||
| { \ | |||||
| } \ | |||||
| } while ( 0 ) | |||||
| #endif | |||||
| #define XThrow(error, operation) XThrowIf(true, error, operation) | |||||
| #define XThrowIfErr(error) XThrowIfError(error, #error) | |||||
| #endif // __CAXException_h__ | |||||
| @@ -0,0 +1,90 @@ | |||||
| /* | |||||
| File: CarbonEventHandler.cpp | |||||
| Abstract: CarbonEventHandler.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "CarbonEventHandler.h" | |||||
| static pascal OSStatus TheEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) | |||||
| { | |||||
| CarbonEventHandler *handler = (CarbonEventHandler *)inUserData; | |||||
| if (handler->HandleEvent(inHandlerRef, inEvent)) | |||||
| return noErr; | |||||
| else return eventNotHandledErr; | |||||
| } | |||||
| CarbonEventHandler::CarbonEventHandler() : | |||||
| mHandlers(NULL) | |||||
| { | |||||
| } | |||||
| CarbonEventHandler::~CarbonEventHandler() | |||||
| { | |||||
| if (mHandlers != NULL) { | |||||
| int count = static_cast<int>(CFDictionaryGetCount(mHandlers)); | |||||
| EventHandlerRef *theHandlers = (EventHandlerRef*) malloc(count * sizeof(EventHandlerRef)); | |||||
| CFDictionaryGetKeysAndValues(mHandlers, NULL, (const void **)theHandlers); | |||||
| for (int i = 0; i < count; i++) | |||||
| RemoveEventHandler(theHandlers[i]); | |||||
| CFDictionaryRemoveAllValues(mHandlers); | |||||
| CFRelease (mHandlers); | |||||
| free(theHandlers); | |||||
| } | |||||
| } | |||||
| void CarbonEventHandler::WantEventTypes(EventTargetRef target, UInt32 inNumTypes, const EventTypeSpec *inList) | |||||
| { | |||||
| if (mHandlers == NULL) | |||||
| mHandlers = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); | |||||
| EventHandlerRef handler; | |||||
| if (CFDictionaryGetValueIfPresent (mHandlers, target, (const void **)&handler)) // if there is already a handler for the target, add the type | |||||
| verify_noerr(AddEventTypesToHandler(handler, inNumTypes, inList)); | |||||
| else { | |||||
| verify_noerr(InstallEventHandler(target, TheEventHandler, inNumTypes, inList, this, &handler)); | |||||
| CFDictionaryAddValue(mHandlers, target, handler); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,71 @@ | |||||
| /* | |||||
| File: CarbonEventHandler.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __CarbonEventHandler_h__ | |||||
| #define __CarbonEventHandler_h__ | |||||
| #include <Carbon/Carbon.h> | |||||
| /*! @class CarbonEventHandler */ | |||||
| class CarbonEventHandler { | |||||
| public: | |||||
| /*! @ctor CarbonEventHandler */ | |||||
| CarbonEventHandler(); | |||||
| /*! @dtor ~CarbonEventHandler */ | |||||
| virtual ~CarbonEventHandler(); | |||||
| /*! @method WantEventTypes */ | |||||
| virtual void WantEventTypes(EventTargetRef target, UInt32 inNumTypes, const EventTypeSpec *inList); | |||||
| /*! @method HandleEvent */ | |||||
| virtual bool HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event) = 0; | |||||
| protected: | |||||
| /*! @var mHandlers */ | |||||
| CFMutableDictionaryRef mHandlers; | |||||
| }; | |||||
| #endif // __CarbonEventHandler_h__ | |||||
| @@ -0,0 +1,369 @@ | |||||
| /* | |||||
| File: ComponentBase.cpp | |||||
| Abstract: ComponentBase.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "ComponentBase.h" | |||||
| #include "CAXException.h" | |||||
| #if TARGET_OS_MAC | |||||
| pthread_mutex_t ComponentInitLocker::sComponentOpenMutex = PTHREAD_MUTEX_INITIALIZER; | |||||
| pthread_once_t ComponentInitLocker::sOnce = PTHREAD_ONCE_INIT; | |||||
| void ComponentInitLocker::InitComponentInitLocker() | |||||
| { | |||||
| // have to do this because OS X lacks PTHREAD_MUTEX_RECURSIVE_INITIALIZER_NP | |||||
| pthread_mutexattr_t attr; | |||||
| pthread_mutexattr_init(&attr); | |||||
| pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | |||||
| pthread_mutex_init(&sComponentOpenMutex, &attr); | |||||
| pthread_mutexattr_destroy(&attr); | |||||
| } | |||||
| #elif TARGET_OS_WIN32 | |||||
| CAGuard ComponentInitLocker::sComponentOpenGuard("sComponentOpenGuard"); | |||||
| #endif | |||||
| ComponentBase::EInstanceType ComponentBase::sNewInstanceType; | |||||
| static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc); | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY && !TARGET_OS_WIN32 | |||||
| static OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc); | |||||
| #endif | |||||
| ComponentBase::ComponentBase(AudioComponentInstance inInstance) | |||||
| : mComponentInstance(inInstance), | |||||
| mInstanceType(sNewInstanceType) | |||||
| { | |||||
| GetComponentDescription(); | |||||
| } | |||||
| ComponentBase::~ComponentBase() | |||||
| { | |||||
| } | |||||
| void ComponentBase::PostConstructor() | |||||
| { | |||||
| } | |||||
| void ComponentBase::PreDestructor() | |||||
| { | |||||
| } | |||||
| #define ACPI ((AudioComponentPlugInInstance *)self) | |||||
| #define ACImp ((ComponentBase *)&ACPI->mInstanceStorage) | |||||
| OSStatus ComponentBase::AP_Open(void *self, AudioUnit compInstance) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| ComponentInitLocker lock; | |||||
| ComponentBase::sNewInstanceType = ComponentBase::kAudioComponentInstance; | |||||
| ComponentBase *cb = (ComponentBase *)(*ACPI->mConstruct)(&ACPI->mInstanceStorage, compInstance); | |||||
| cb->PostConstructor(); // allows base class to do additional initialization | |||||
| // once the derived class is fully constructed | |||||
| result = noErr; | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| if (result) | |||||
| delete ACPI; | |||||
| return result; | |||||
| } | |||||
| OSStatus ComponentBase::AP_Close(void *self) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| if (ACImp) { | |||||
| ACImp->PreDestructor(); | |||||
| (*ACPI->mDestruct)(&ACPI->mInstanceStorage); | |||||
| free(self); | |||||
| } | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| OSStatus ComponentBase::Version() | |||||
| { | |||||
| return 0x00000001; | |||||
| } | |||||
| OSStatus ComponentBase::ComponentEntryDispatch(ComponentParameters *p, ComponentBase *This) | |||||
| { | |||||
| if (This == NULL) return kAudio_ParamError; | |||||
| OSStatus result = noErr; | |||||
| switch (p->what) { | |||||
| case kComponentCloseSelect: | |||||
| This->PreDestructor(); | |||||
| delete This; | |||||
| break; | |||||
| case kComponentVersionSelect: | |||||
| result = This->Version(); | |||||
| break; | |||||
| case kComponentCanDoSelect: | |||||
| switch (GetSelectorForCanDo(p)) { | |||||
| case kComponentOpenSelect: | |||||
| case kComponentCloseSelect: | |||||
| case kComponentVersionSelect: | |||||
| case kComponentCanDoSelect: | |||||
| return 1; | |||||
| default: | |||||
| return 0; | |||||
| } | |||||
| default: | |||||
| result = badComponentSelector; | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| SInt16 ComponentBase::GetSelectorForCanDo(ComponentParameters *params) | |||||
| { | |||||
| if (params->what != kComponentCanDoSelect) return 0; | |||||
| #if TARGET_CPU_X86 | |||||
| SInt16 sel = params->params[0]; | |||||
| #elif TARGET_CPU_X86_64 | |||||
| SInt16 sel = params->params[1]; | |||||
| #elif TARGET_CPU_PPC | |||||
| SInt16 sel = (params->params[0] >> 16); | |||||
| #else | |||||
| SInt16 sel = params->params[0]; | |||||
| #endif | |||||
| return sel; | |||||
| /* | |||||
| printf ("flags:%d, paramSize: %d, what: %d\n\t", params->flags, params->paramSize, params->what); | |||||
| for (int i = 0; i < params->paramSize; ++i) { | |||||
| printf ("[%d]:%d(0x%x), ", i, params->params[i], params->params[i]); | |||||
| } | |||||
| printf("\n\tsel:%d\n", sel); | |||||
| */ | |||||
| } | |||||
| #endif | |||||
| #if CA_DO_NOT_USE_AUDIO_COMPONENT | |||||
| static OSStatus ComponentBase_GetComponentDescription (const AudioComponentInstance & inInstance, AudioComponentDescription &outDesc); | |||||
| #endif | |||||
| AudioComponentDescription ComponentBase::GetComponentDescription() const | |||||
| { | |||||
| AudioComponentDescription desc; | |||||
| OSStatus result = 1; | |||||
| if (IsPluginObject()) { | |||||
| ca_require_noerr(result = CB_GetComponentDescription (mComponentInstance, &desc), home); | |||||
| } | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| else { | |||||
| ca_require_noerr(result = CMgr_GetComponentDescription (mComponentInstance, &desc), home); | |||||
| } | |||||
| #endif | |||||
| home: | |||||
| if (result) | |||||
| memset (&desc, 0, sizeof(AudioComponentDescription)); | |||||
| return desc; | |||||
| } | |||||
| #if CA_USE_AUDIO_PLUGIN_ONLY | |||||
| // everything we need is there and we should be linking against it | |||||
| static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc) | |||||
| { | |||||
| AudioComponent comp = AudioComponentInstanceGetComponent(inInstance); | |||||
| if (comp) | |||||
| return AudioComponentGetDescription(comp, outDesc); | |||||
| return kAudio_ParamError; | |||||
| } | |||||
| #elif !TARGET_OS_WIN32 | |||||
| // these are the direct dependencies on ComponentMgr calls that an AU | |||||
| // that is a component mgr is dependent on | |||||
| // these are dynamically loaded so that these calls will work on Leopard | |||||
| #include <dlfcn.h> | |||||
| static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc) | |||||
| { | |||||
| typedef AudioComponent (*AudioComponentInstanceGetComponentProc) (AudioComponentInstance); | |||||
| static AudioComponentInstanceGetComponentProc aciGCProc = NULL; | |||||
| typedef OSStatus (*AudioComponentGetDescriptionProc)(AudioComponent, AudioComponentDescription *); | |||||
| static AudioComponentGetDescriptionProc acGDProc = NULL; | |||||
| static int doneInit = 0; | |||||
| if (doneInit == 0) { | |||||
| doneInit = 1; | |||||
| void* theImage = dlopen("/System/Library/Frameworks/AudioUnit.framework/AudioUnit", RTLD_LAZY); | |||||
| if (theImage != NULL) | |||||
| { | |||||
| aciGCProc = (AudioComponentInstanceGetComponentProc)dlsym (theImage, "AudioComponentInstanceGetComponent"); | |||||
| if (aciGCProc) { | |||||
| acGDProc = (AudioComponentGetDescriptionProc)dlsym (theImage, "AudioComponentGetDescription"); | |||||
| } | |||||
| } | |||||
| } | |||||
| OSStatus result = kAudio_UnimplementedError; | |||||
| if (acGDProc && aciGCProc) { | |||||
| AudioComponent comp = (*aciGCProc)(inInstance); | |||||
| if (comp) | |||||
| result = (*acGDProc)(comp, outDesc); | |||||
| } | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| else { | |||||
| result = CMgr_GetComponentDescription (inInstance, outDesc); | |||||
| } | |||||
| #endif | |||||
| return result; | |||||
| } | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| // these are the direct dependencies on ComponentMgr calls that an AU | |||||
| // that is a component mgr is dependent on | |||||
| // these are dynamically loaded | |||||
| #include <CoreServices/CoreServices.h> | |||||
| #include <AudioUnit/AudioUnit.h> | |||||
| #include "CAXException.h" | |||||
| #include "ComponentBase.h" | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| // Component Manager | |||||
| // Used for fast dispatch with audio units | |||||
| typedef Handle (*GetComponentInstanceStorageProc)(ComponentInstance aComponentInstance); | |||||
| static GetComponentInstanceStorageProc sGetComponentInstanceStorageProc = NULL; | |||||
| typedef OSErr (*GetComponentInfoProc)(Component, ComponentDescription *, void*, void*, void*); | |||||
| static GetComponentInfoProc sGetComponentInfoProc = NULL; | |||||
| typedef void (*SetComponentInstanceStorageProc)(ComponentInstance, Handle); | |||||
| static SetComponentInstanceStorageProc sSetComponentInstanceStorageProc = NULL; | |||||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||||
| static void CSInitOnce(void* /*unused*/) | |||||
| { | |||||
| void *theImage = dlopen("/System/Library/Frameworks/CoreServices.framework/CoreServices", RTLD_LAZY); | |||||
| if (!theImage) return; | |||||
| sGetComponentInstanceStorageProc = (GetComponentInstanceStorageProc) dlsym(theImage, "GetComponentInstanceStorage"); | |||||
| sGetComponentInfoProc = (GetComponentInfoProc)dlsym (theImage, "GetComponentInfo"); | |||||
| sSetComponentInstanceStorageProc = (SetComponentInstanceStorageProc) dlsym(theImage, "SetComponentInstanceStorage"); | |||||
| } | |||||
| #if TARGET_OS_MAC | |||||
| #include <dispatch/dispatch.h> | |||||
| static dispatch_once_t sCSInitOnce = 0; | |||||
| static void CSInit () | |||||
| { | |||||
| dispatch_once_f(&sCSInitOnce, NULL, CSInitOnce); | |||||
| } | |||||
| #else | |||||
| static void CSInit () | |||||
| { | |||||
| static int sDoCSLoad = 1; | |||||
| if (sDoCSLoad) { | |||||
| sDoCSLoad = 0; | |||||
| CSInitOnce(NULL); | |||||
| } | |||||
| } | |||||
| #endif | |||||
| OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc) | |||||
| { | |||||
| CSInit(); | |||||
| if (sGetComponentInfoProc) | |||||
| return (*sGetComponentInfoProc)((Component)inInstance, (ComponentDescription*)outDesc, NULL, NULL, NULL); | |||||
| return kAudio_UnimplementedError; | |||||
| } | |||||
| Handle CMgr_GetComponentInstanceStorage(ComponentInstance aComponentInstance) | |||||
| { | |||||
| CSInit(); | |||||
| if (sGetComponentInstanceStorageProc) | |||||
| return (*sGetComponentInstanceStorageProc)(aComponentInstance); | |||||
| return NULL; | |||||
| } | |||||
| void CMgr_SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage) | |||||
| { | |||||
| CSInit(); | |||||
| if (sSetComponentInstanceStorageProc) | |||||
| (*sSetComponentInstanceStorageProc)(aComponentInstance, theStorage); | |||||
| } | |||||
| #endif // !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| #else | |||||
| //#include "ComponentManagerDependenciesWin.h" | |||||
| // everything we need is there and we should be linking against it | |||||
| static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc) | |||||
| { | |||||
| AudioComponent comp = AudioComponentInstanceGetComponent(inInstance); | |||||
| if (comp) | |||||
| return AudioComponentGetDescription(comp, outDesc); | |||||
| return kAudio_ParamError; | |||||
| } | |||||
| #endif | |||||
| @@ -0,0 +1,353 @@ | |||||
| /* | |||||
| File: ComponentBase.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __ComponentBase_h__ | |||||
| #define __ComponentBase_h__ | |||||
| #include <new> | |||||
| #include "CADebugMacros.h" | |||||
| #include "CAXException.h" | |||||
| #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) | |||||
| #include <CoreAudio/CoreAudioTypes.h> | |||||
| #include <AudioUnit/AudioUnit.h> | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/Components.h> | |||||
| #if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5) | |||||
| #define AudioComponentInstance ComponentInstance | |||||
| #define AudioComponentDescription ComponentDescription | |||||
| #define AudioComponent Component | |||||
| #endif | |||||
| Handle CMgr_GetComponentInstanceStorage(ComponentInstance aComponentInstance); | |||||
| void CMgr_SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage); | |||||
| #endif | |||||
| #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 | |||||
| typedef Float32 AudioUnitParameterValue; | |||||
| #endif | |||||
| #if COREAUDIOTYPES_VERSION < 1051 | |||||
| typedef Float32 AudioUnitSampleType; | |||||
| #endif | |||||
| #if !TARGET_OS_WIN32 | |||||
| #include <pthread.h> | |||||
| #endif | |||||
| #if TARGET_OS_WIN32 | |||||
| #include "CAGuard.h" | |||||
| #endif | |||||
| #else | |||||
| #include "CoreAudioTypes.h" | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| #include "ComponentManagerDependenciesWin.h" | |||||
| #endif | |||||
| #include "AudioUnit.h" | |||||
| #include "CAGuard.h" | |||||
| #endif | |||||
| #ifndef COMPONENT_THROW | |||||
| #if VERBOSE_COMPONENT_THROW | |||||
| #define COMPONENT_THROW(throw_err) \ | |||||
| do { DebugMessage(#throw_err); throw static_cast<OSStatus>(throw_err); } while (0) | |||||
| #else | |||||
| #define COMPONENT_THROW(throw_err) \ | |||||
| throw static_cast<OSStatus>(throw_err) | |||||
| #endif | |||||
| #endif | |||||
| #define COMPONENT_CATCH \ | |||||
| catch (const CAXException &ex) { result = ex.mError; } \ | |||||
| catch (std::bad_alloc &) { result = kAudio_MemFullError; } \ | |||||
| catch (OSStatus catch_err) { result = catch_err; } \ | |||||
| catch (OSErr catch_err) { result = catch_err; } \ | |||||
| catch (...) { result = -1; } | |||||
| /*! @class ComponentBase */ | |||||
| class ComponentBase { | |||||
| public: | |||||
| // classic MacErrors | |||||
| enum { noErr = 0}; | |||||
| /*! @ctor ComponentBase */ | |||||
| ComponentBase(AudioComponentInstance inInstance); | |||||
| /*! @dtor ~ComponentBase */ | |||||
| virtual ~ComponentBase(); | |||||
| /*! @method PostConstructor */ | |||||
| virtual void PostConstructor(); | |||||
| /*! @method PreDestructor */ | |||||
| virtual void PreDestructor(); | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| /*! @method Version */ | |||||
| virtual OSStatus Version(); | |||||
| /*! @method ComponentEntryDispatch */ | |||||
| static OSStatus ComponentEntryDispatch(ComponentParameters *p, ComponentBase *This); | |||||
| /*! GetSelectorForCanDo */ | |||||
| static SInt16 GetSelectorForCanDo(ComponentParameters *params); | |||||
| #endif | |||||
| /*! @method GetComponentInstance */ | |||||
| AudioComponentInstance GetComponentInstance() const { return mComponentInstance; } | |||||
| /*! @method GetComponentDescription */ | |||||
| AudioComponentDescription GetComponentDescription() const; | |||||
| // This global variable is so that new instances know how they were instantiated: via the Component Manager, | |||||
| // or as AudioComponents. It's ugly, but preferable to altering the constructor of every class in the hierarchy. | |||||
| // It's safe because construction is protected by ComponentInitLocker. | |||||
| enum EInstanceType { kComponentMgrInstance, kAudioComponentInstance }; | |||||
| static EInstanceType sNewInstanceType; | |||||
| /*! @method IsPluginObject */ | |||||
| bool IsPluginObject () const { return mInstanceType == kAudioComponentInstance; } | |||||
| /*! @method IsCMgrObject */ | |||||
| bool IsCMgrObject () const { return mInstanceType == kComponentMgrInstance; } | |||||
| /*! @method AP_Open */ | |||||
| static OSStatus AP_Open(void *self, AudioUnit compInstance); | |||||
| /*! @method AP_Close */ | |||||
| static OSStatus AP_Close(void *self); | |||||
| protected: | |||||
| /*! @var mComponentInstance */ | |||||
| AudioComponentInstance mComponentInstance; | |||||
| EInstanceType mInstanceType; | |||||
| }; | |||||
| class ComponentInitLocker | |||||
| { | |||||
| #if TARGET_OS_MAC | |||||
| public: | |||||
| ComponentInitLocker() | |||||
| { | |||||
| pthread_once(&sOnce, InitComponentInitLocker); | |||||
| pthread_mutex_lock(&sComponentOpenMutex); | |||||
| mPreviousNewInstanceType = ComponentBase::sNewInstanceType; | |||||
| } | |||||
| ~ComponentInitLocker() | |||||
| { | |||||
| ComponentBase::sNewInstanceType = mPreviousNewInstanceType; | |||||
| pthread_mutex_unlock(&sComponentOpenMutex); | |||||
| } | |||||
| // There are situations (11844772) where we need to be able to release the lock early. | |||||
| class Unlocker { | |||||
| public: | |||||
| Unlocker() | |||||
| { | |||||
| pthread_mutex_unlock(&sComponentOpenMutex); | |||||
| } | |||||
| ~Unlocker() | |||||
| { | |||||
| pthread_mutex_lock(&sComponentOpenMutex); | |||||
| } | |||||
| }; | |||||
| private: | |||||
| static pthread_mutex_t sComponentOpenMutex; | |||||
| static pthread_once_t sOnce; | |||||
| static void InitComponentInitLocker(); | |||||
| #elif TARGET_OS_WIN32 | |||||
| public: | |||||
| bool sNeedsUnlocking; | |||||
| ComponentInitLocker() { sNeedsUnlocking = sComponentOpenGuard.Lock(); } | |||||
| ~ComponentInitLocker() { if(sNeedsUnlocking) { sComponentOpenGuard.Unlock(); } } | |||||
| private: | |||||
| static CAGuard sComponentOpenGuard; | |||||
| #endif | |||||
| private: | |||||
| ComponentBase::EInstanceType mPreviousNewInstanceType; | |||||
| }; | |||||
| /*! @class AudioComponentPlugInInstance */ | |||||
| struct AudioComponentPlugInInstance { | |||||
| AudioComponentPlugInInterface mPlugInInterface; | |||||
| void * (*mConstruct)(void *memory, AudioComponentInstance ci); | |||||
| void (*mDestruct)(void *memory); | |||||
| void * mPad[2]; // pad to a 16-byte boundary (in either 32 or 64 bit mode) | |||||
| UInt32 mInstanceStorage; // the ACI implementation object is constructed into this memory | |||||
| // this member is just a placeholder. it is aligned to a 16byte boundary | |||||
| }; | |||||
| /*! @class APFactory */ | |||||
| template <class APMethodLookup, class Implementor> | |||||
| class APFactory { | |||||
| public: | |||||
| static void *Construct(void *memory, AudioComponentInstance compInstance) | |||||
| { | |||||
| return new(memory) Implementor(compInstance); | |||||
| } | |||||
| static void Destruct(void *memory) | |||||
| { | |||||
| ((Implementor *)memory)->~Implementor(); | |||||
| } | |||||
| // This is the AudioComponentFactoryFunction. It returns an AudioComponentPlugInInstance. | |||||
| // The actual implementation object is not created until Open(). | |||||
| static AudioComponentPlugInInterface *Factory(const AudioComponentDescription * /* inDesc */) | |||||
| { | |||||
| AudioComponentPlugInInstance *acpi = | |||||
| (AudioComponentPlugInInstance *)malloc( offsetof(AudioComponentPlugInInstance, mInstanceStorage) + sizeof(Implementor) ); | |||||
| acpi->mPlugInInterface.Open = ComponentBase::AP_Open; | |||||
| acpi->mPlugInInterface.Close = ComponentBase::AP_Close; | |||||
| acpi->mPlugInInterface.Lookup = APMethodLookup::Lookup; | |||||
| acpi->mPlugInInterface.reserved = NULL; | |||||
| acpi->mConstruct = Construct; | |||||
| acpi->mDestruct = Destruct; | |||||
| acpi->mPad[0] = NULL; | |||||
| acpi->mPad[1] = NULL; | |||||
| return (AudioComponentPlugInInterface*)acpi; | |||||
| } | |||||
| // This is for runtime registration (not for plug-ins loaded from bundles). | |||||
| static AudioComponent Register(UInt32 type, UInt32 subtype, UInt32 manuf, CFStringRef name, UInt32 vers, UInt32 flags=0) | |||||
| { | |||||
| AudioComponentDescription desc = { type, subtype, manuf, flags, 0 }; | |||||
| return AudioComponentRegister(&desc, name, vers, Factory); | |||||
| } | |||||
| }; | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| /*! @class ComponentEntryPoint | |||||
| * @discussion This is only used for a component manager version | |||||
| */ | |||||
| template <class Class> | |||||
| class ComponentEntryPoint { | |||||
| public: | |||||
| /*! @method Dispatch */ | |||||
| static OSStatus Dispatch(ComponentParameters *params, Class *obj) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| if (params->what == kComponentOpenSelect) { | |||||
| // solve a host of initialization thread safety issues. | |||||
| ComponentInitLocker lock; | |||||
| ComponentBase::sNewInstanceType = ComponentBase::kComponentMgrInstance; | |||||
| ComponentInstance ci = (ComponentInstance)(params->params[0]); | |||||
| Class *This = new Class((AudioComponentInstance)ci); | |||||
| This->PostConstructor(); // allows base class to do additional initialization | |||||
| // once the derived class is fully constructed | |||||
| CMgr_SetComponentInstanceStorage(ci, (Handle)This); | |||||
| } else | |||||
| result = Class::ComponentEntryDispatch(params, obj); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| /*! @method Register */ | |||||
| static Component Register(OSType compType, OSType subType, OSType manufacturer) | |||||
| { | |||||
| ComponentDescription description = {compType, subType, manufacturer, 0, 0}; | |||||
| Component component = RegisterComponent(&description, (ComponentRoutineUPP) Dispatch, registerComponentGlobal, NULL, NULL, NULL); | |||||
| if (component != NULL) { | |||||
| SetDefaultComponent(component, defaultComponentAnyFlagsAnyManufacturerAnySubType); | |||||
| } | |||||
| return component; | |||||
| } | |||||
| }; | |||||
| // NOTE: Component Mgr is deprecated in ML. | |||||
| // this macro should not be used with new audio components | |||||
| // it is only for backwards compatibility with Lion and SL. | |||||
| // this macro registers both a plugin and a component mgr version. | |||||
| #define AUDIOCOMPONENT_ENTRY(FactoryType, Class) \ | |||||
| extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj); \ | |||||
| extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj) { \ | |||||
| return ComponentEntryPoint<Class>::Dispatch(params, obj); \ | |||||
| } \ | |||||
| extern "C" void * Class##Factory(const AudioComponentDescription *inDesc); \ | |||||
| extern "C" void * Class##Factory(const AudioComponentDescription *inDesc) { \ | |||||
| return FactoryType<Class>::Factory(inDesc); \ | |||||
| } | |||||
| // the only component we still support are the carbon based view components | |||||
| // you should be using this macro now to exclusively register those types | |||||
| #define VIEW_COMPONENT_ENTRY(Class) \ | |||||
| extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj); \ | |||||
| extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj) { \ | |||||
| return ComponentEntryPoint<Class>::Dispatch(params, obj); \ | |||||
| } | |||||
| /*! @class ComponentRegistrar */ | |||||
| template <class Class, OSType Type, OSType Subtype, OSType Manufacturer> | |||||
| class ComponentRegistrar { | |||||
| public: | |||||
| /*! @ctor ComponentRegistrar */ | |||||
| ComponentRegistrar() { ComponentEntryPoint<Class>::Register(Type, Subtype, Manufacturer); } | |||||
| }; | |||||
| #define COMPONENT_REGISTER(Class,Type,Subtype,Manufacturer) \ | |||||
| static ComponentRegistrar<Class, Type, Subtype, Manufacturer> gRegistrar##Class | |||||
| #else | |||||
| #define COMPONENT_ENTRY(Class) | |||||
| #define COMPONENT_REGISTER(Class) | |||||
| // this macro is used to generate the Entry Point for a given Audio Plugin | |||||
| // you should be using this macro now with audio components | |||||
| #define AUDIOCOMPONENT_ENTRY(FactoryType, Class) \ | |||||
| extern "C" void * Class##Factory(const AudioComponentDescription *inDesc); \ | |||||
| extern "C" void * Class##Factory(const AudioComponentDescription *inDesc) { \ | |||||
| return FactoryType<Class>::Factory(inDesc); \ | |||||
| } | |||||
| #endif // !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| #endif // __ComponentBase_h__ | |||||
| @@ -0,0 +1,354 @@ | |||||
| /* | |||||
| File: MusicDeviceBase.cpp | |||||
| Abstract: MusicDeviceBase.h | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #include "MusicDeviceBase.h" | |||||
| // compatibility with older OS SDK releases | |||||
| typedef OSStatus | |||||
| (*TEMP_MusicDeviceMIDIEventProc)( void * inComponentStorage, | |||||
| UInt32 inStatus, | |||||
| UInt32 inData1, | |||||
| UInt32 inData2, | |||||
| UInt32 inOffsetSampleFrame); | |||||
| typedef OSStatus | |||||
| (*TEMP_MusicDeviceStartNoteProc)( void * inComponentStorage, | |||||
| MusicDeviceInstrumentID inInstrument, | |||||
| MusicDeviceGroupID inGroupID, | |||||
| NoteInstanceID * outNoteInstanceID, | |||||
| UInt32 inOffsetSampleFrame, | |||||
| const MusicDeviceNoteParams * inParams); | |||||
| typedef OSStatus | |||||
| (*TEMP_MusicDeviceStopNoteProc)(void * inComponentStorage, | |||||
| MusicDeviceGroupID inGroupID, | |||||
| NoteInstanceID inNoteInstanceID, | |||||
| UInt32 inOffsetSampleFrame); | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| static OSStatus MusicDeviceBaseMIDIEvent(void * inComponentStorage, | |||||
| UInt32 inStatus, | |||||
| UInt32 inData1, | |||||
| UInt32 inData2, | |||||
| UInt32 inOffsetSampleFrame); | |||||
| static OSStatus MusicDeviceBaseStartNote( void * inComponentStorage, | |||||
| MusicDeviceInstrumentID inInstrument, | |||||
| MusicDeviceGroupID inGroupID, | |||||
| NoteInstanceID * outNoteInstanceID, | |||||
| UInt32 inOffsetSampleFrame, | |||||
| const MusicDeviceNoteParams * inParams); | |||||
| static OSStatus MusicDeviceBaseStopNote(void * inComponentStorage, | |||||
| MusicDeviceGroupID inGroupID, | |||||
| NoteInstanceID inNoteInstanceID, | |||||
| UInt32 inOffsetSampleFrame); | |||||
| #endif | |||||
| MusicDeviceBase::MusicDeviceBase(AudioComponentInstance inInstance, | |||||
| UInt32 numInputs, | |||||
| UInt32 numOutputs, | |||||
| UInt32 numGroups) | |||||
| : AUBase(inInstance, numInputs, numOutputs, numGroups), | |||||
| AUMIDIBase(this) | |||||
| { | |||||
| } | |||||
| OSStatus MusicDeviceBase::GetPropertyInfo(AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 & outDataSize, | |||||
| Boolean & outWritable) | |||||
| { | |||||
| OSStatus result; | |||||
| switch (inID) | |||||
| { | |||||
| #if !TARGET_OS_IPHONE | |||||
| case kMusicDeviceProperty_InstrumentCount: | |||||
| if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidScope; | |||||
| outDataSize = sizeof(UInt32); | |||||
| outWritable = false; | |||||
| result = noErr; | |||||
| break; | |||||
| #endif | |||||
| default: | |||||
| result = AUBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable); | |||||
| if (result == kAudioUnitErr_InvalidProperty) | |||||
| result = AUMIDIBase::DelegateGetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable); | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| OSStatus MusicDeviceBase::GetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| void * outData) | |||||
| { | |||||
| OSStatus result; | |||||
| switch (inID) | |||||
| { | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| case kAudioUnitProperty_FastDispatch: | |||||
| if (!IsCMgrObject()) return kAudioUnitErr_InvalidProperty; | |||||
| if (inElement == kMusicDeviceMIDIEventSelect) { | |||||
| *(TEMP_MusicDeviceMIDIEventProc *)outData = MusicDeviceBaseMIDIEvent; | |||||
| return noErr; | |||||
| } | |||||
| else if (inElement == kMusicDeviceStartNoteSelect) { | |||||
| *(TEMP_MusicDeviceStartNoteProc *)outData = MusicDeviceBaseStartNote; | |||||
| return noErr; | |||||
| } | |||||
| else if (inElement == kMusicDeviceStopNoteSelect) { | |||||
| *(TEMP_MusicDeviceStopNoteProc *)outData = MusicDeviceBaseStopNote; | |||||
| return noErr; | |||||
| } | |||||
| return kAudioUnitErr_InvalidElement; | |||||
| #endif | |||||
| #if !TARGET_OS_IPHONE | |||||
| case kMusicDeviceProperty_InstrumentCount: | |||||
| if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidScope; | |||||
| return GetInstrumentCount (*(UInt32*)outData); | |||||
| #endif | |||||
| default: | |||||
| result = AUBase::GetProperty (inID, inScope, inElement, outData); | |||||
| if (result == kAudioUnitErr_InvalidProperty) | |||||
| result = AUMIDIBase::DelegateGetProperty (inID, inScope, inElement, outData); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| OSStatus MusicDeviceBase::SetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const void * inData, | |||||
| UInt32 inDataSize) | |||||
| { | |||||
| OSStatus result = AUBase::SetProperty (inID, inScope, inElement, inData, inDataSize); | |||||
| if (result == kAudioUnitErr_InvalidProperty) | |||||
| result = AUMIDIBase::DelegateSetProperty (inID, inScope, inElement, inData, inDataSize); | |||||
| return result; | |||||
| } | |||||
| // For a MusicDevice that doesn't support separate instruments (ie. is mono-timbral) | |||||
| // then this call should return an instrument count of zero and noErr | |||||
| OSStatus MusicDeviceBase::GetInstrumentCount (UInt32 &outInstCount) const | |||||
| { | |||||
| outInstCount = 0; | |||||
| return noErr; | |||||
| } | |||||
| OSStatus MusicDeviceBase::HandleNoteOn( UInt8 inChannel, | |||||
| UInt8 inNoteNumber, | |||||
| UInt8 inVelocity, | |||||
| UInt32 inStartFrame) | |||||
| { | |||||
| MusicDeviceNoteParams params; | |||||
| params.argCount = 2; | |||||
| params.mPitch = inNoteNumber; | |||||
| params.mVelocity = inVelocity; | |||||
| return StartNote (kMusicNoteEvent_UseGroupInstrument, inChannel, NULL, inStartFrame, params); | |||||
| } | |||||
| OSStatus MusicDeviceBase::HandleNoteOff( UInt8 inChannel, | |||||
| UInt8 inNoteNumber, | |||||
| UInt8 inVelocity, | |||||
| UInt32 inStartFrame) | |||||
| { | |||||
| return StopNote (inChannel, inNoteNumber, inStartFrame); | |||||
| } | |||||
| OSStatus | |||||
| MusicDeviceBase::HandleStartNoteMessage (MusicDeviceInstrumentID inInstrument, | |||||
| MusicDeviceGroupID inGroupID, | |||||
| NoteInstanceID * outNoteInstanceID, | |||||
| UInt32 inOffsetSampleFrame, | |||||
| const MusicDeviceNoteParams * inParams) | |||||
| { | |||||
| if (inParams == NULL || outNoteInstanceID == NULL) return kAudio_ParamError; | |||||
| if (!IsInitialized()) return kAudioUnitErr_Uninitialized; | |||||
| return StartNote (inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams); | |||||
| } | |||||
| #if TARGET_OS_MAC | |||||
| #if __LP64__ | |||||
| // comp instance, parameters in forward order | |||||
| #define PARAM(_typ, _name, _index, _nparams) \ | |||||
| _typ _name = *(_typ *)¶ms->params[_index + 1]; | |||||
| #else | |||||
| // parameters in reverse order, then comp instance | |||||
| #define PARAM(_typ, _name, _index, _nparams) \ | |||||
| _typ _name = *(_typ *)¶ms->params[_nparams - 1 - _index]; | |||||
| #endif | |||||
| #elif TARGET_OS_WIN32 | |||||
| // (no comp instance), parameters in forward order | |||||
| #define PARAM(_typ, _name, _index, _nparams) \ | |||||
| _typ _name = *(_typ *)¶ms->params[_index]; | |||||
| #endif | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| OSStatus MusicDeviceBase::ComponentEntryDispatch( ComponentParameters * params, | |||||
| MusicDeviceBase * This) | |||||
| { | |||||
| if (This == NULL) return kAudio_ParamError; | |||||
| OSStatus result; | |||||
| switch (params->what) { | |||||
| case kMusicDeviceMIDIEventSelect: | |||||
| case kMusicDeviceSysExSelect: | |||||
| { | |||||
| result = AUMIDIBase::ComponentEntryDispatch (params, This); | |||||
| } | |||||
| break; | |||||
| case kMusicDevicePrepareInstrumentSelect: | |||||
| { | |||||
| PARAM(MusicDeviceInstrumentID, inInstrument, 0, 1); | |||||
| result = This->PrepareInstrument(inInstrument); | |||||
| } | |||||
| break; | |||||
| case kMusicDeviceReleaseInstrumentSelect: | |||||
| { | |||||
| PARAM(MusicDeviceInstrumentID, inInstrument, 0, 1); | |||||
| result = This->ReleaseInstrument(inInstrument); | |||||
| } | |||||
| break; | |||||
| case kMusicDeviceStartNoteSelect: | |||||
| { | |||||
| PARAM(MusicDeviceInstrumentID, pbinInstrument, 0, 5); | |||||
| PARAM(MusicDeviceGroupID, pbinGroupID, 1, 5); | |||||
| PARAM(NoteInstanceID *, pboutNoteInstanceID, 2, 5); | |||||
| PARAM(UInt32, pbinOffsetSampleFrame, 3, 5); | |||||
| PARAM(const MusicDeviceNoteParams *, pbinParams, 4, 5); | |||||
| result = This->HandleStartNoteMessage(pbinInstrument, pbinGroupID, pboutNoteInstanceID, pbinOffsetSampleFrame, pbinParams); | |||||
| } | |||||
| break; | |||||
| case kMusicDeviceStopNoteSelect: | |||||
| { | |||||
| PARAM(MusicDeviceGroupID, pbinGroupID, 0, 3); | |||||
| PARAM(NoteInstanceID, pbinNoteInstanceID, 1, 3); | |||||
| PARAM(UInt32, pbinOffsetSampleFrame, 2, 3); | |||||
| result = This->StopNote(pbinGroupID, pbinNoteInstanceID, pbinOffsetSampleFrame); | |||||
| } | |||||
| break; | |||||
| default: | |||||
| result = AUBase::ComponentEntryDispatch(params, This); | |||||
| break; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| #endif | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| // fast dispatch | |||||
| static OSStatus MusicDeviceBaseMIDIEvent(void * inComponentStorage, | |||||
| UInt32 inStatus, | |||||
| UInt32 inData1, | |||||
| UInt32 inData2, | |||||
| UInt32 inOffsetSampleFrame) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage); | |||||
| if (This == NULL) return kAudio_ParamError; | |||||
| result = This->MIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| OSStatus MusicDeviceBaseStartNote( void * inComponentStorage, | |||||
| MusicDeviceInstrumentID inInstrument, | |||||
| MusicDeviceGroupID inGroupID, | |||||
| NoteInstanceID * outNoteInstanceID, | |||||
| UInt32 inOffsetSampleFrame, | |||||
| const MusicDeviceNoteParams * inParams) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| if (inParams == NULL || outNoteInstanceID == NULL) return kAudio_ParamError; | |||||
| MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage); | |||||
| if (This == NULL) return kAudio_ParamError; | |||||
| result = This->StartNote(inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| OSStatus MusicDeviceBaseStopNote(void * inComponentStorage, | |||||
| MusicDeviceGroupID inGroupID, | |||||
| NoteInstanceID inNoteInstanceID, | |||||
| UInt32 inOffsetSampleFrame) | |||||
| { | |||||
| OSStatus result = noErr; | |||||
| try { | |||||
| MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage); | |||||
| if (This == NULL) return kAudio_ParamError; | |||||
| result = This->StopNote(inGroupID, inNoteInstanceID, inOffsetSampleFrame); | |||||
| } | |||||
| COMPONENT_CATCH | |||||
| return result; | |||||
| } | |||||
| #endif | |||||
| @@ -0,0 +1,126 @@ | |||||
| /* | |||||
| File: MusicDeviceBase.h | |||||
| Abstract: Part of CoreAudio Utility Classes | |||||
| Version: 1.1 | |||||
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple | |||||
| Inc. ("Apple") in consideration of your agreement to the following | |||||
| terms, and your use, installation, modification or redistribution of | |||||
| this Apple software constitutes acceptance of these terms. If you do | |||||
| not agree with these terms, please do not use, install, modify or | |||||
| redistribute this Apple software. | |||||
| In consideration of your agreement to abide by the following terms, and | |||||
| subject to these terms, Apple grants you a personal, non-exclusive | |||||
| license, under Apple's copyrights in this original Apple software (the | |||||
| "Apple Software"), to use, reproduce, modify and redistribute the Apple | |||||
| Software, with or without modifications, in source and/or binary forms; | |||||
| provided that if you redistribute the Apple Software in its entirety and | |||||
| without modifications, you must retain this notice and the following | |||||
| text and disclaimers in all such redistributions of the Apple Software. | |||||
| Neither the name, trademarks, service marks or logos of Apple Inc. may | |||||
| be used to endorse or promote products derived from the Apple Software | |||||
| without specific prior written permission from Apple. Except as | |||||
| expressly stated in this notice, no other rights or licenses, express or | |||||
| implied, are granted by Apple herein, including but not limited to any | |||||
| patent rights that may be infringed by your derivative works or by other | |||||
| works in which the Apple Software may be incorporated. | |||||
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE | |||||
| MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION | |||||
| THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS | |||||
| FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND | |||||
| OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. | |||||
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL | |||||
| OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
| INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, | |||||
| MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED | |||||
| AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), | |||||
| STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGE. | |||||
| Copyright (C) 2014 Apple Inc. All Rights Reserved. | |||||
| */ | |||||
| #ifndef __MusicDeviceBase_h__ | |||||
| #define __MusicDeviceBase_h__ | |||||
| #include "AUMIDIBase.h" | |||||
| // ________________________________________________________________________ | |||||
| // MusicDeviceBase | |||||
| // | |||||
| /*! @class MusicDeviceBase */ | |||||
| class MusicDeviceBase : public AUBase, public AUMIDIBase { | |||||
| public: | |||||
| /*! @ctor MusicDeviceBase */ | |||||
| MusicDeviceBase( AudioComponentInstance inInstance, | |||||
| UInt32 numInputs, | |||||
| UInt32 numOutputs, | |||||
| UInt32 numGroups = 0); | |||||
| virtual OSStatus MIDIEvent( UInt32 inStatus, | |||||
| UInt32 inData1, | |||||
| UInt32 inData2, | |||||
| UInt32 inOffsetSampleFrame) | |||||
| { | |||||
| return AUMIDIBase::MIDIEvent (inStatus, inData1, inData2, inOffsetSampleFrame); | |||||
| } | |||||
| /*! @method SysEx */ | |||||
| virtual OSStatus SysEx( const UInt8 * inData, | |||||
| UInt32 inLength) | |||||
| { | |||||
| return AUMIDIBase::SysEx (inData, inLength); | |||||
| } | |||||
| /*! @method GetPropertyInfo */ | |||||
| virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| UInt32 & outDataSize, | |||||
| Boolean & outWritable); | |||||
| /*! @method GetProperty */ | |||||
| virtual OSStatus GetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| void * outData); | |||||
| /*! @method SetProperty */ | |||||
| virtual OSStatus SetProperty( AudioUnitPropertyID inID, | |||||
| AudioUnitScope inScope, | |||||
| AudioUnitElement inElement, | |||||
| const void * inData, | |||||
| UInt32 inDataSize); | |||||
| /*! @method HandleNoteOn */ | |||||
| virtual OSStatus HandleNoteOn( UInt8 inChannel, | |||||
| UInt8 inNoteNumber, | |||||
| UInt8 inVelocity, | |||||
| UInt32 inStartFrame); | |||||
| /*! @method HandleNoteOff */ | |||||
| virtual OSStatus HandleNoteOff( UInt8 inChannel, | |||||
| UInt8 inNoteNumber, | |||||
| UInt8 inVelocity, | |||||
| UInt32 inStartFrame); | |||||
| /*! @method GetInstrumentCount */ | |||||
| virtual OSStatus GetInstrumentCount ( UInt32 &outInstCount) const; | |||||
| #if !CA_USE_AUDIO_PLUGIN_ONLY | |||||
| // component dispatcher | |||||
| /*! @method ComponentEntryDispatch */ | |||||
| static OSStatus ComponentEntryDispatch( ComponentParameters * params, | |||||
| MusicDeviceBase * This); | |||||
| #endif | |||||
| private: | |||||
| OSStatus HandleStartNoteMessage (MusicDeviceInstrumentID inInstrument, MusicDeviceGroupID inGroupID, NoteInstanceID *outNoteInstanceID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams *inParams); | |||||
| }; | |||||
| #endif // __MusicDeviceBase_h__ | |||||
| @@ -64,8 +64,8 @@ | |||||
| juce website for more info on how to get them: | juce website for more info on how to get them: | ||||
| http://www.juce.com/forum/topic/aus-xcode | http://www.juce.com/forum/topic/aus-xcode | ||||
| */ | */ | ||||
| #include "AUMIDIEffectBase.h" | |||||
| #include "MusicDeviceBase.h" | |||||
| #include "CoreAudioUtilityClasses/AUMIDIEffectBase.h" | |||||
| #include "CoreAudioUtilityClasses/MusicDeviceBase.h" | |||||
| #undef Point | #undef Point | ||||
| #undef Component | #undef Component | ||||
| @@ -84,7 +84,7 @@ | |||||
| #if BUILD_AU_CARBON_UI | #if BUILD_AU_CARBON_UI | ||||
| #undef Button | #undef Button | ||||
| #define Point CarbonDummyPointName | #define Point CarbonDummyPointName | ||||
| #include "AUCarbonViewBase.h" | |||||
| #include "CoreAudioUtilityClasses/AUCarbonViewBase.h" | |||||
| #undef Point | #undef Point | ||||
| #endif | #endif | ||||
| @@ -1647,7 +1647,7 @@ JUCE_FACTORY_ENTRY (JuceAU, JucePlugin_AUExportPrefix) | |||||
| #endif | #endif | ||||
| #if ! JUCE_DISABLE_AU_FACTORY_ENTRY | #if ! JUCE_DISABLE_AU_FACTORY_ENTRY | ||||
| #include "AUPlugInDispatch.cpp" | |||||
| #include "CoreAudioUtilityClasses/AUPlugInDispatch.cpp" | |||||
| #endif | #endif | ||||
| #endif | #endif | ||||
| @@ -26,6 +26,27 @@ | |||||
| { "file": "RTAS/juce_RTAS_Wrapper.cpp", "warnings": "disabled", "stdcall": "1", "target": "xcode, msvc" }, | { "file": "RTAS/juce_RTAS_Wrapper.cpp", "warnings": "disabled", "stdcall": "1", "target": "xcode, msvc" }, | ||||
| { "file": "AU/juce_AU_Resources.r", "target": "xcode", "AudioUnitOnly": "1" }, | { "file": "AU/juce_AU_Resources.r", "target": "xcode", "AudioUnitOnly": "1" }, | ||||
| { "file": "AU/juce_AU_Wrapper.mm", "target": "xcode" }, | { "file": "AU/juce_AU_Wrapper.mm", "target": "xcode" }, | ||||
| { "file": "AU/CoreAudioUtilityClasses/AUBase.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUBuffer.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUCarbonViewBase.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUCarbonViewControl.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUCarbonViewDispatch.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUDispatch.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUEffectBase.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUInputElement.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUMIDIBase.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUMIDIEffectBase.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUOutputBase.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUOutputElement.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/AUScopeElement.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/CAAUParameter.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/CAAudioChannelLayout.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/CAMutex.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/CAStreamBasicDescription.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/CAVectorUnit.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/CarbonEventHandler.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/ComponentBase.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AU/CoreAudioUtilityClasses/MusicDeviceBase.cpp", "warnings": "disabled", "target": "xcode", "AudioUnitOnly": "1" }, | |||||
| { "file": "AAX/juce_AAX_Wrapper.cpp", "target": "xcode, msvc" }, | { "file": "AAX/juce_AAX_Wrapper.cpp", "target": "xcode, msvc" }, | ||||
| { "file": "AAX/juce_AAX_Wrapper.mm", "target": "xcode" }, | { "file": "AAX/juce_AAX_Wrapper.mm", "target": "xcode" }, | ||||
| { "file": "utility/juce_PluginUtilities.cpp" } | { "file": "utility/juce_PluginUtilities.cpp" } | ||||