From 90c4985604884a94c9d7d34b77bb7f6fefe6c291 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 12 Jan 2016 07:45:46 -0500 Subject: remove wavesaudio backend --- .../waves_audiobackend.xcodeproj/project.pbxproj | 517 ---- libs/backends/wavesaudio/portmidi/pmutil.h | 127 - libs/backends/wavesaudio/portmidi/portmidi.h | 654 ---- libs/backends/wavesaudio/portmidi/porttime.h | 92 - .../wavesaudio/portmidi/src/pm_common/pminternal.h | 178 -- .../wavesaudio/portmidi/src/pm_common/pmutil.c | 284 -- .../wavesaudio/portmidi/src/pm_common/portmidi.c | 1137 ------- .../wavesaudio/portmidi/src/pm_mac/Makefile.osx | 129 - .../wavesaudio/portmidi/src/pm_mac/README_MAC.txt | 163 - .../wavesaudio/portmidi/src/pm_mac/finddefault.c | 57 - .../pm_mac.xcodeproj/project.pbxproj | 594 ---- .../project.xcworkspace/contents.xcworkspacedata | 7 - .../UserInterfaceState.xcuserstate | Bin 5803 -> 0 bytes .../xcschemes/Assemble Application.xcscheme | 86 - .../xcschemes/Compile Java.xcscheme | 59 - .../xcschemes/CopyJavaSources.xcscheme | 59 - .../xcschemes/JPortMidiHeaders.xcscheme | 59 - .../xcschemes/PmDefaults.xcscheme | 59 - .../xcschemes/xcschememanagement.plist | 62 - .../xcschemes/Assemble Application.xcscheme | 86 - .../xcschemes/Compile Java.xcscheme | 59 - .../xcschemes/CopyJavaSources.xcscheme | 59 - .../xcschemes/JPortMidiHeaders.xcscheme | 59 - .../xcschemes/PmDefaults.xcscheme | 59 - .../xcschemes/xcschememanagement.plist | 62 - .../src/pm_mac/pm_mac.xcodeproj/project.pbxproj | 594 ---- .../project.xcworkspace/contents.xcworkspacedata | 7 - .../UserInterfaceState.xcuserstate | Bin 5803 -> 0 bytes .../xcschemes/Assemble Application.xcscheme | 86 - .../xcschemes/Compile Java.xcscheme | 59 - .../xcschemes/CopyJavaSources.xcscheme | 59 - .../xcschemes/JPortMidiHeaders.xcscheme | 59 - .../xcschemes/PmDefaults.xcscheme | 59 - .../xcschemes/xcschememanagement.plist | 62 - .../xcschemes/Assemble Application.xcscheme | 86 - .../xcschemes/Compile Java.xcscheme | 59 - .../xcschemes/CopyJavaSources.xcscheme | 59 - .../xcschemes/JPortMidiHeaders.xcscheme | 59 - .../xcschemes/PmDefaults.xcscheme | 59 - .../xcschemes/xcschememanagement.plist | 62 - .../portmidi/src/pm_mac/pmdefaults/make/build.xml | 87 - .../src/pm_mac/pmdefaults/make/find-classrefs.sh | 31 - .../pmdefaults/resources/English.lproj/Credits.rtf | 14 - .../resources/English.lproj/InfoPlist.strings | 3 - .../src/pm_mac/pmdefaults/resources/Info.plist | 40 - .../src/pm_mac/pmdefaults/resources/Manifest | 1 - .../wavesaudio/portmidi/src/pm_mac/pmmac.c | 59 - .../wavesaudio/portmidi/src/pm_mac/pmmac.h | 4 - .../wavesaudio/portmidi/src/pm_mac/pmmacosxcm.c | 1021 ------- .../wavesaudio/portmidi/src/pm_mac/pmmacosxcm.h | 6 - .../portmidi/src/pm_mac/readbinaryplist.c | 1115 ------- .../portmidi/src/pm_mac/readbinaryplist.h | 88 - .../wavesaudio/portmidi/src/pm_win/pmwin.c | 142 - .../wavesaudio/portmidi/src/pm_win/pmwinmm.c | 1466 --------- .../wavesaudio/portmidi/src/pm_win/pmwinmm.h | 5 - .../portmidi/src/porttime/ptmacosx_mach.c | 131 - .../wavesaudio/portmidi/src/porttime/ptwinmm.c | 71 - libs/backends/wavesaudio/waves_audiobackend.cc | 1355 --------- libs/backends/wavesaudio/waves_audiobackend.h | 409 --- .../wavesaudio/waves_audiobackend.latency.cc | 90 - .../backends/wavesaudio/waves_audiobackend.midi.cc | 353 --- .../wavesaudio/waves_audiobackend.port_engine.cc | 661 ---- libs/backends/wavesaudio/waves_audioport.cc | 75 - libs/backends/wavesaudio/waves_audioport.h | 58 - libs/backends/wavesaudio/waves_dataport.cc | 150 - libs/backends/wavesaudio/waves_dataport.h | 116 - libs/backends/wavesaudio/waves_midi_buffer.cc | 49 - libs/backends/wavesaudio/waves_midi_buffer.h | 48 - libs/backends/wavesaudio/waves_midi_device.cc | 329 -- libs/backends/wavesaudio/waves_midi_device.h | 71 - .../wavesaudio/waves_midi_device_manager.cc | 245 -- .../wavesaudio/waves_midi_device_manager.h | 75 - libs/backends/wavesaudio/waves_midi_event.cc | 197 -- libs/backends/wavesaudio/waves_midi_event.h | 75 - libs/backends/wavesaudio/waves_midiport.cc | 67 - libs/backends/wavesaudio/waves_midiport.h | 64 - .../wavesaudio/wavesapi/BasicTypes/WCFourCC.h | 213 -- .../wavesaudio/wavesapi/BasicTypes/WTByteOrder.h | 223 -- .../wavesaudio/wavesapi/BasicTypes/WUComPtr.h | 118 - .../wavesaudio/wavesapi/BasicTypes/WUDefines.h | 176 -- .../wavesaudio/wavesapi/BasicTypes/WUMathConsts.h | 48 - .../wavesaudio/wavesapi/BasicTypes/WUTypes.h | 266 -- .../wavesapi/MiscUtils/MinMaxUtilities.h | 133 - .../wavesapi/MiscUtils/UMicroseconds.cpp | 77 - .../wavesaudio/wavesapi/MiscUtils/UMicroseconds.h | 124 - .../wavesaudio/wavesapi/MiscUtils/WCFixedString.h | 904 ------ .../wavesaudio/wavesapi/MiscUtils/WUErrors.h | 336 --- .../wavesaudio/wavesapi/MiscUtils/pthread_utils.h | 38 - .../wavesaudio/wavesapi/MiscUtils/safe_delete.h | 37 - .../wavesaudio/wavesapi/Threads/WCThreadSafe.cpp | 826 ----- .../wavesaudio/wavesapi/Threads/WCThreadSafe.h | 411 --- .../WavesPublicAPI/1.0/WavesPublicAPI_Defines.h | 60 - .../wavesaudio/wavesapi/WavesPublicAPI/WTErr.h | 46 - .../wavesaudio/wavesapi/WavesPublicAPI/wstdint.h | 367 --- .../wavesaudio/wavesapi/akupara/basics.hpp | 53 - .../wavesapi/akupara/compiletime_functions.hpp | 205 -- .../wavesapi/akupara/threading/atomic_ops.hpp | 388 --- .../akupara/threading/atomic_ops_gcc_x86.hpp | 201 -- .../wavesapi/devicemanager/IncludeWindows.h | 50 - .../devicemanager/WCMRAudioDeviceManager.cpp | 692 ----- .../devicemanager/WCMRAudioDeviceManager.h | 271 -- .../devicemanager/WCMRCoreAudioDeviceManager.cpp | 3140 -------------------- .../devicemanager/WCMRCoreAudioDeviceManager.h | 209 -- .../wavesapi/devicemanager/WCMRNativeAudio.cpp | 266 -- .../wavesapi/devicemanager/WCMRNativeAudio.h | 96 - .../devicemanager/WCMRPortAudioDeviceManager.cpp | 1782 ----------- .../devicemanager/WCMRPortAudioDeviceManager.h | 180 -- .../wavesapi/refmanager/WCRefManager.cpp | 26 - .../wavesaudio/wavesapi/refmanager/WCRefManager.h | 81 - libs/backends/wavesaudio/wscript | 104 - wscript | 12 +- 111 files changed, 1 insertion(+), 27005 deletions(-) delete mode 100644 libs/backends/wavesaudio/macosx/waves_audiobackend.xcodeproj/project.pbxproj delete mode 100644 libs/backends/wavesaudio/portmidi/pmutil.h delete mode 100644 libs/backends/wavesaudio/portmidi/portmidi.h delete mode 100644 libs/backends/wavesaudio/portmidi/porttime.h delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_common/pminternal.h delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_common/pmutil.c delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_common/portmidi.c delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/Makefile.osx delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/README_MAC.txt delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/finddefault.c delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.pbxproj delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.xcworkspace/xcuserdata/VKamyshniy.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Assemble Application.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Compile Java.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/CopyJavaSources.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/PmDefaults.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Assemble Application.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Compile Java.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/CopyJavaSources.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/PmDefaults.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.pbxproj delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.xcworkspace/xcuserdata/VKamyshniy.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Assemble Application.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Compile Java.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/CopyJavaSources.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/PmDefaults.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Assemble Application.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Compile Java.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/CopyJavaSources.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/PmDefaults.xcscheme delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/make/build.xml delete mode 100755 libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/make/find-classrefs.sh delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/English.lproj/Credits.rtf delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/English.lproj/InfoPlist.strings delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/Info.plist delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/Manifest delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pmmac.c delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pmmac.h delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pmmacosxcm.c delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/pmmacosxcm.h delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/readbinaryplist.c delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_mac/readbinaryplist.h delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_win/pmwin.c delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_win/pmwinmm.c delete mode 100644 libs/backends/wavesaudio/portmidi/src/pm_win/pmwinmm.h delete mode 100644 libs/backends/wavesaudio/portmidi/src/porttime/ptmacosx_mach.c delete mode 100644 libs/backends/wavesaudio/portmidi/src/porttime/ptwinmm.c delete mode 100644 libs/backends/wavesaudio/waves_audiobackend.cc delete mode 100644 libs/backends/wavesaudio/waves_audiobackend.h delete mode 100644 libs/backends/wavesaudio/waves_audiobackend.latency.cc delete mode 100644 libs/backends/wavesaudio/waves_audiobackend.midi.cc delete mode 100644 libs/backends/wavesaudio/waves_audiobackend.port_engine.cc delete mode 100644 libs/backends/wavesaudio/waves_audioport.cc delete mode 100644 libs/backends/wavesaudio/waves_audioport.h delete mode 100644 libs/backends/wavesaudio/waves_dataport.cc delete mode 100644 libs/backends/wavesaudio/waves_dataport.h delete mode 100644 libs/backends/wavesaudio/waves_midi_buffer.cc delete mode 100644 libs/backends/wavesaudio/waves_midi_buffer.h delete mode 100644 libs/backends/wavesaudio/waves_midi_device.cc delete mode 100644 libs/backends/wavesaudio/waves_midi_device.h delete mode 100644 libs/backends/wavesaudio/waves_midi_device_manager.cc delete mode 100644 libs/backends/wavesaudio/waves_midi_device_manager.h delete mode 100644 libs/backends/wavesaudio/waves_midi_event.cc delete mode 100644 libs/backends/wavesaudio/waves_midi_event.h delete mode 100644 libs/backends/wavesaudio/waves_midiport.cc delete mode 100644 libs/backends/wavesaudio/waves_midiport.h delete mode 100644 libs/backends/wavesaudio/wavesapi/BasicTypes/WCFourCC.h delete mode 100644 libs/backends/wavesaudio/wavesapi/BasicTypes/WTByteOrder.h delete mode 100644 libs/backends/wavesaudio/wavesapi/BasicTypes/WUComPtr.h delete mode 100644 libs/backends/wavesaudio/wavesapi/BasicTypes/WUDefines.h delete mode 100644 libs/backends/wavesaudio/wavesapi/BasicTypes/WUMathConsts.h delete mode 100644 libs/backends/wavesaudio/wavesapi/BasicTypes/WUTypes.h delete mode 100644 libs/backends/wavesaudio/wavesapi/MiscUtils/MinMaxUtilities.h delete mode 100644 libs/backends/wavesaudio/wavesapi/MiscUtils/UMicroseconds.cpp delete mode 100644 libs/backends/wavesaudio/wavesapi/MiscUtils/UMicroseconds.h delete mode 100644 libs/backends/wavesaudio/wavesapi/MiscUtils/WCFixedString.h delete mode 100644 libs/backends/wavesaudio/wavesapi/MiscUtils/WUErrors.h delete mode 100644 libs/backends/wavesaudio/wavesapi/MiscUtils/pthread_utils.h delete mode 100644 libs/backends/wavesaudio/wavesapi/MiscUtils/safe_delete.h delete mode 100644 libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.cpp delete mode 100644 libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.h delete mode 100644 libs/backends/wavesaudio/wavesapi/WavesPublicAPI/1.0/WavesPublicAPI_Defines.h delete mode 100644 libs/backends/wavesaudio/wavesapi/WavesPublicAPI/WTErr.h delete mode 100644 libs/backends/wavesaudio/wavesapi/WavesPublicAPI/wstdint.h delete mode 100644 libs/backends/wavesaudio/wavesapi/akupara/basics.hpp delete mode 100644 libs/backends/wavesaudio/wavesapi/akupara/compiletime_functions.hpp delete mode 100644 libs/backends/wavesaudio/wavesapi/akupara/threading/atomic_ops.hpp delete mode 100644 libs/backends/wavesaudio/wavesapi/akupara/threading/atomic_ops_gcc_x86.hpp delete mode 100644 libs/backends/wavesaudio/wavesapi/devicemanager/IncludeWindows.h delete mode 100644 libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp delete mode 100644 libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h delete mode 100644 libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp delete mode 100644 libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h delete mode 100644 libs/backends/wavesaudio/wavesapi/devicemanager/WCMRNativeAudio.cpp delete mode 100644 libs/backends/wavesaudio/wavesapi/devicemanager/WCMRNativeAudio.h delete mode 100644 libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp delete mode 100644 libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h delete mode 100644 libs/backends/wavesaudio/wavesapi/refmanager/WCRefManager.cpp delete mode 100644 libs/backends/wavesaudio/wavesapi/refmanager/WCRefManager.h delete mode 100644 libs/backends/wavesaudio/wscript diff --git a/libs/backends/wavesaudio/macosx/waves_audiobackend.xcodeproj/project.pbxproj b/libs/backends/wavesaudio/macosx/waves_audiobackend.xcodeproj/project.pbxproj deleted file mode 100644 index ac127735e8..0000000000 --- a/libs/backends/wavesaudio/macosx/waves_audiobackend.xcodeproj/project.pbxproj +++ /dev/null @@ -1,517 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 43278FF0194EFB30003C9FEA /* basics.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 43278FC8194EFB30003C9FEA /* basics.hpp */; }; - 43278FF1194EFB30003C9FEA /* compiletime_functions.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 43278FC9194EFB30003C9FEA /* compiletime_functions.hpp */; }; - 43278FF2194EFB30003C9FEA /* atomic_ops.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 43278FCB194EFB30003C9FEA /* atomic_ops.hpp */; }; - 43278FF3194EFB30003C9FEA /* atomic_ops_gcc_x86.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 43278FCC194EFB30003C9FEA /* atomic_ops_gcc_x86.hpp */; }; - 43278FF4194EFB30003C9FEA /* WCFourCC.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FCE194EFB30003C9FEA /* WCFourCC.h */; }; - 43278FF5194EFB30003C9FEA /* WTByteOrder.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FCF194EFB30003C9FEA /* WTByteOrder.h */; }; - 43278FF6194EFB30003C9FEA /* WUComPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FD0194EFB30003C9FEA /* WUComPtr.h */; }; - 43278FF7194EFB30003C9FEA /* WUDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FD1194EFB30003C9FEA /* WUDefines.h */; }; - 43278FF8194EFB30003C9FEA /* WUMathConsts.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FD2194EFB30003C9FEA /* WUMathConsts.h */; }; - 43278FF9194EFB30003C9FEA /* WUTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FD3194EFB30003C9FEA /* WUTypes.h */; }; - 43278FFA194EFB30003C9FEA /* IncludeWindows.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FD5194EFB30003C9FEA /* IncludeWindows.h */; }; - 43278FFB194EFB30003C9FEA /* WCMRAudioDeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43278FD6194EFB30003C9FEA /* WCMRAudioDeviceManager.cpp */; }; - 43278FFC194EFB30003C9FEA /* WCMRAudioDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FD7194EFB30003C9FEA /* WCMRAudioDeviceManager.h */; }; - 43278FFD194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43278FD8194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.cpp */; }; - 43278FFE194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FD9194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.h */; }; - 43278FFF194EFB30003C9FEA /* WCMRNativeAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43278FDA194EFB30003C9FEA /* WCMRNativeAudio.cpp */; }; - 43279000194EFB30003C9FEA /* WCMRNativeAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FDB194EFB30003C9FEA /* WCMRNativeAudio.h */; }; - 43279001194EFB30003C9FEA /* WCMRPortAudioDeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43278FDC194EFB30003C9FEA /* WCMRPortAudioDeviceManager.cpp */; }; - 43279002194EFB30003C9FEA /* WCMRPortAudioDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FDD194EFB30003C9FEA /* WCMRPortAudioDeviceManager.h */; }; - 43279003194EFB30003C9FEA /* MinMaxUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FDF194EFB30003C9FEA /* MinMaxUtilities.h */; }; - 43279004194EFB30003C9FEA /* safe_delete.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FE0194EFB30003C9FEA /* safe_delete.h */; }; - 43279005194EFB30003C9FEA /* UMicroseconds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43278FE1194EFB30003C9FEA /* UMicroseconds.cpp */; }; - 43279006194EFB30003C9FEA /* UMicroseconds.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FE2194EFB30003C9FEA /* UMicroseconds.h */; }; - 43279007194EFB30003C9FEA /* WCFixedString.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FE3194EFB30003C9FEA /* WCFixedString.h */; }; - 43279008194EFB30003C9FEA /* WUErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FE4194EFB30003C9FEA /* WUErrors.h */; }; - 43279009194EFB30003C9FEA /* WCRefManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43278FE6194EFB30003C9FEA /* WCRefManager.cpp */; }; - 4327900A194EFB30003C9FEA /* WCRefManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FE7194EFB30003C9FEA /* WCRefManager.h */; }; - 4327900B194EFB30003C9FEA /* WCThreadSafe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43278FE9194EFB30003C9FEA /* WCThreadSafe.cpp */; }; - 4327900C194EFB30003C9FEA /* WCThreadSafe.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FEA194EFB30003C9FEA /* WCThreadSafe.h */; }; - 4327900D194EFB30003C9FEA /* WavesPublicAPI_Defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FED194EFB30003C9FEA /* WavesPublicAPI_Defines.h */; }; - 4327900E194EFB30003C9FEA /* wstdint.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FEE194EFB30003C9FEA /* wstdint.h */; }; - 4327900F194EFB30003C9FEA /* WTErr.h in Headers */ = {isa = PBXBuildFile; fileRef = 43278FEF194EFB30003C9FEA /* WTErr.h */; }; - 43AA86F0194EED8900A67B56 /* waves_audiobackend.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86E5194EED8900A67B56 /* waves_audiobackend.cc */; }; - 43AA86F1194EED8900A67B56 /* waves_audiobackend.latency.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86E6194EED8900A67B56 /* waves_audiobackend.latency.cc */; }; - 43AA86F2194EED8900A67B56 /* waves_audiobackend.midi.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86E7194EED8900A67B56 /* waves_audiobackend.midi.cc */; }; - 43AA86F3194EED8900A67B56 /* waves_audiobackend.port_engine.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86E8194EED8900A67B56 /* waves_audiobackend.port_engine.cc */; }; - 43AA86F4194EED8900A67B56 /* waves_audioport.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86E9194EED8900A67B56 /* waves_audioport.cc */; }; - 43AA86F5194EED8900A67B56 /* waves_dataport.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86EA194EED8900A67B56 /* waves_dataport.cc */; }; - 43AA86F6194EED8900A67B56 /* waves_midi_buffer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86EB194EED8900A67B56 /* waves_midi_buffer.cc */; }; - 43AA86F7194EED8900A67B56 /* waves_midi_device_manager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86EC194EED8900A67B56 /* waves_midi_device_manager.cc */; }; - 43AA86F8194EED8900A67B56 /* waves_midi_device.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86ED194EED8900A67B56 /* waves_midi_device.cc */; }; - 43AA86F9194EED8900A67B56 /* waves_midi_event.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86EE194EED8900A67B56 /* waves_midi_event.cc */; }; - 43AA86FA194EED8900A67B56 /* waves_midiport.cc in Sources */ = {isa = PBXBuildFile; fileRef = 43AA86EF194EED8900A67B56 /* waves_midiport.cc */; }; - 43AA8703194EEDAC00A67B56 /* waves_audiobackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AA86FB194EEDAC00A67B56 /* waves_audiobackend.h */; }; - 43AA8704194EEDAC00A67B56 /* waves_audioport.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AA86FC194EEDAC00A67B56 /* waves_audioport.h */; }; - 43AA8705194EEDAC00A67B56 /* waves_dataport.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AA86FD194EEDAC00A67B56 /* waves_dataport.h */; }; - 43AA8706194EEDAC00A67B56 /* waves_midi_buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AA86FE194EEDAC00A67B56 /* waves_midi_buffer.h */; }; - 43AA8707194EEDAC00A67B56 /* waves_midi_device_manager.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AA86FF194EEDAC00A67B56 /* waves_midi_device_manager.h */; }; - 43AA8708194EEDAC00A67B56 /* waves_midi_device.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AA8700194EEDAC00A67B56 /* waves_midi_device.h */; }; - 43AA8709194EEDAC00A67B56 /* waves_midi_event.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AA8701194EEDAC00A67B56 /* waves_midi_event.h */; }; - 43AA870A194EEDAC00A67B56 /* waves_midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AA8702194EEDAC00A67B56 /* waves_midiport.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 43278FC8194EFB30003C9FEA /* basics.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = basics.hpp; path = ../wavesapi/akupara/basics.hpp; sourceTree = SOURCE_ROOT; }; - 43278FC9194EFB30003C9FEA /* compiletime_functions.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = compiletime_functions.hpp; path = ../wavesapi/akupara/compiletime_functions.hpp; sourceTree = SOURCE_ROOT; }; - 43278FCB194EFB30003C9FEA /* atomic_ops.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = atomic_ops.hpp; path = ../wavesapi/akupara/threading/atomic_ops.hpp; sourceTree = SOURCE_ROOT; }; - 43278FCC194EFB30003C9FEA /* atomic_ops_gcc_x86.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = atomic_ops_gcc_x86.hpp; path = ../wavesapi/akupara/threading/atomic_ops_gcc_x86.hpp; sourceTree = SOURCE_ROOT; }; - 43278FCE194EFB30003C9FEA /* WCFourCC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCFourCC.h; path = ../wavesapi/BasicTypes/WCFourCC.h; sourceTree = SOURCE_ROOT; }; - 43278FCF194EFB30003C9FEA /* WTByteOrder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WTByteOrder.h; path = ../wavesapi/BasicTypes/WTByteOrder.h; sourceTree = SOURCE_ROOT; }; - 43278FD0194EFB30003C9FEA /* WUComPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WUComPtr.h; path = ../wavesapi/BasicTypes/WUComPtr.h; sourceTree = SOURCE_ROOT; }; - 43278FD1194EFB30003C9FEA /* WUDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WUDefines.h; path = ../wavesapi/BasicTypes/WUDefines.h; sourceTree = SOURCE_ROOT; }; - 43278FD2194EFB30003C9FEA /* WUMathConsts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WUMathConsts.h; path = ../wavesapi/BasicTypes/WUMathConsts.h; sourceTree = SOURCE_ROOT; }; - 43278FD3194EFB30003C9FEA /* WUTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WUTypes.h; path = ../wavesapi/BasicTypes/WUTypes.h; sourceTree = SOURCE_ROOT; }; - 43278FD5194EFB30003C9FEA /* IncludeWindows.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IncludeWindows.h; path = ../wavesapi/devicemanager/IncludeWindows.h; sourceTree = SOURCE_ROOT; }; - 43278FD6194EFB30003C9FEA /* WCMRAudioDeviceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WCMRAudioDeviceManager.cpp; path = ../wavesapi/devicemanager/WCMRAudioDeviceManager.cpp; sourceTree = SOURCE_ROOT; }; - 43278FD7194EFB30003C9FEA /* WCMRAudioDeviceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCMRAudioDeviceManager.h; path = ../wavesapi/devicemanager/WCMRAudioDeviceManager.h; sourceTree = SOURCE_ROOT; }; - 43278FD8194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WCMRCoreAudioDeviceManager.cpp; path = ../wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp; sourceTree = SOURCE_ROOT; }; - 43278FD9194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCMRCoreAudioDeviceManager.h; path = ../wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h; sourceTree = SOURCE_ROOT; }; - 43278FDA194EFB30003C9FEA /* WCMRNativeAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WCMRNativeAudio.cpp; path = ../wavesapi/devicemanager/WCMRNativeAudio.cpp; sourceTree = SOURCE_ROOT; }; - 43278FDB194EFB30003C9FEA /* WCMRNativeAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCMRNativeAudio.h; path = ../wavesapi/devicemanager/WCMRNativeAudio.h; sourceTree = SOURCE_ROOT; }; - 43278FDC194EFB30003C9FEA /* WCMRPortAudioDeviceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WCMRPortAudioDeviceManager.cpp; path = ../wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp; sourceTree = SOURCE_ROOT; }; - 43278FDD194EFB30003C9FEA /* WCMRPortAudioDeviceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCMRPortAudioDeviceManager.h; path = ../wavesapi/devicemanager/WCMRPortAudioDeviceManager.h; sourceTree = SOURCE_ROOT; }; - 43278FDF194EFB30003C9FEA /* MinMaxUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MinMaxUtilities.h; path = ../wavesapi/miscutils/MinMaxUtilities.h; sourceTree = SOURCE_ROOT; }; - 43278FE0194EFB30003C9FEA /* safe_delete.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = safe_delete.h; path = ../wavesapi/miscutils/safe_delete.h; sourceTree = SOURCE_ROOT; }; - 43278FE1194EFB30003C9FEA /* UMicroseconds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UMicroseconds.cpp; path = ../wavesapi/miscutils/UMicroseconds.cpp; sourceTree = SOURCE_ROOT; }; - 43278FE2194EFB30003C9FEA /* UMicroseconds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UMicroseconds.h; path = ../wavesapi/miscutils/UMicroseconds.h; sourceTree = SOURCE_ROOT; }; - 43278FE3194EFB30003C9FEA /* WCFixedString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCFixedString.h; path = ../wavesapi/miscutils/WCFixedString.h; sourceTree = SOURCE_ROOT; }; - 43278FE4194EFB30003C9FEA /* WUErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WUErrors.h; path = ../wavesapi/miscutils/WUErrors.h; sourceTree = SOURCE_ROOT; }; - 43278FE6194EFB30003C9FEA /* WCRefManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WCRefManager.cpp; path = ../wavesapi/refmanager/WCRefManager.cpp; sourceTree = SOURCE_ROOT; }; - 43278FE7194EFB30003C9FEA /* WCRefManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCRefManager.h; path = ../wavesapi/refmanager/WCRefManager.h; sourceTree = SOURCE_ROOT; }; - 43278FE9194EFB30003C9FEA /* WCThreadSafe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WCThreadSafe.cpp; path = ../wavesapi/threads/WCThreadSafe.cpp; sourceTree = SOURCE_ROOT; }; - 43278FEA194EFB30003C9FEA /* WCThreadSafe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WCThreadSafe.h; path = ../wavesapi/threads/WCThreadSafe.h; sourceTree = SOURCE_ROOT; }; - 43278FED194EFB30003C9FEA /* WavesPublicAPI_Defines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WavesPublicAPI_Defines.h; path = ../wavesapi/wavespublicapi/1.0/WavesPublicAPI_Defines.h; sourceTree = SOURCE_ROOT; }; - 43278FEE194EFB30003C9FEA /* wstdint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wstdint.h; path = ../wavesapi/wavespublicapi/wstdint.h; sourceTree = SOURCE_ROOT; }; - 43278FEF194EFB30003C9FEA /* WTErr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WTErr.h; path = ../wavesapi/wavespublicapi/WTErr.h; sourceTree = SOURCE_ROOT; }; - 43AA86DC194EECE000A67B56 /* libwaves_audiobackend.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libwaves_audiobackend.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; - 43AA86E5194EED8900A67B56 /* waves_audiobackend.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_audiobackend.cc; path = ../waves_audiobackend.cc; sourceTree = SOURCE_ROOT; }; - 43AA86E6194EED8900A67B56 /* waves_audiobackend.latency.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_audiobackend.latency.cc; path = ../waves_audiobackend.latency.cc; sourceTree = SOURCE_ROOT; }; - 43AA86E7194EED8900A67B56 /* waves_audiobackend.midi.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_audiobackend.midi.cc; path = ../waves_audiobackend.midi.cc; sourceTree = SOURCE_ROOT; }; - 43AA86E8194EED8900A67B56 /* waves_audiobackend.port_engine.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_audiobackend.port_engine.cc; path = ../waves_audiobackend.port_engine.cc; sourceTree = SOURCE_ROOT; }; - 43AA86E9194EED8900A67B56 /* waves_audioport.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_audioport.cc; path = ../waves_audioport.cc; sourceTree = SOURCE_ROOT; }; - 43AA86EA194EED8900A67B56 /* waves_dataport.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_dataport.cc; path = ../waves_dataport.cc; sourceTree = SOURCE_ROOT; }; - 43AA86EB194EED8900A67B56 /* waves_midi_buffer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_midi_buffer.cc; path = ../waves_midi_buffer.cc; sourceTree = SOURCE_ROOT; }; - 43AA86EC194EED8900A67B56 /* waves_midi_device_manager.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_midi_device_manager.cc; path = ../waves_midi_device_manager.cc; sourceTree = SOURCE_ROOT; }; - 43AA86ED194EED8900A67B56 /* waves_midi_device.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_midi_device.cc; path = ../waves_midi_device.cc; sourceTree = SOURCE_ROOT; }; - 43AA86EE194EED8900A67B56 /* waves_midi_event.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_midi_event.cc; path = ../waves_midi_event.cc; sourceTree = SOURCE_ROOT; }; - 43AA86EF194EED8900A67B56 /* waves_midiport.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = waves_midiport.cc; path = ../waves_midiport.cc; sourceTree = SOURCE_ROOT; }; - 43AA86FB194EEDAC00A67B56 /* waves_audiobackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = waves_audiobackend.h; path = ../waves_audiobackend.h; sourceTree = SOURCE_ROOT; }; - 43AA86FC194EEDAC00A67B56 /* waves_audioport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = waves_audioport.h; path = ../waves_audioport.h; sourceTree = SOURCE_ROOT; }; - 43AA86FD194EEDAC00A67B56 /* waves_dataport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = waves_dataport.h; path = ../waves_dataport.h; sourceTree = SOURCE_ROOT; }; - 43AA86FE194EEDAC00A67B56 /* waves_midi_buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = waves_midi_buffer.h; path = ../waves_midi_buffer.h; sourceTree = SOURCE_ROOT; }; - 43AA86FF194EEDAC00A67B56 /* waves_midi_device_manager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = waves_midi_device_manager.h; path = ../waves_midi_device_manager.h; sourceTree = SOURCE_ROOT; }; - 43AA8700194EEDAC00A67B56 /* waves_midi_device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = waves_midi_device.h; path = ../waves_midi_device.h; sourceTree = SOURCE_ROOT; }; - 43AA8701194EEDAC00A67B56 /* waves_midi_event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = waves_midi_event.h; path = ../waves_midi_event.h; sourceTree = SOURCE_ROOT; }; - 43AA8702194EEDAC00A67B56 /* waves_midiport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = waves_midiport.h; path = ../waves_midiport.h; sourceTree = SOURCE_ROOT; }; - 43AA870B194EEDC600A67B56 /* wscript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = wscript; path = ../wscript; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 43AA86D9194EECE000A67B56 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 43278FC6194EFB30003C9FEA /* wavesapi */ = { - isa = PBXGroup; - children = ( - 43278FC7194EFB30003C9FEA /* akupara */, - 43278FCD194EFB30003C9FEA /* BasicTypes */, - 43278FD4194EFB30003C9FEA /* devicemanager */, - 43278FDE194EFB30003C9FEA /* miscutils */, - 43278FE5194EFB30003C9FEA /* refmanager */, - 43278FE8194EFB30003C9FEA /* threads */, - 43278FEB194EFB30003C9FEA /* wavespublicapi */, - ); - name = wavesapi; - path = ../wavesapi; - sourceTree = SOURCE_ROOT; - }; - 43278FC7194EFB30003C9FEA /* akupara */ = { - isa = PBXGroup; - children = ( - 43278FC8194EFB30003C9FEA /* basics.hpp */, - 43278FC9194EFB30003C9FEA /* compiletime_functions.hpp */, - 43278FCA194EFB30003C9FEA /* threading */, - ); - path = akupara; - sourceTree = ""; - }; - 43278FCA194EFB30003C9FEA /* threading */ = { - isa = PBXGroup; - children = ( - 43278FCB194EFB30003C9FEA /* atomic_ops.hpp */, - 43278FCC194EFB30003C9FEA /* atomic_ops_gcc_x86.hpp */, - ); - path = threading; - sourceTree = ""; - }; - 43278FCD194EFB30003C9FEA /* BasicTypes */ = { - isa = PBXGroup; - children = ( - 43278FCE194EFB30003C9FEA /* WCFourCC.h */, - 43278FCF194EFB30003C9FEA /* WTByteOrder.h */, - 43278FD0194EFB30003C9FEA /* WUComPtr.h */, - 43278FD1194EFB30003C9FEA /* WUDefines.h */, - 43278FD2194EFB30003C9FEA /* WUMathConsts.h */, - 43278FD3194EFB30003C9FEA /* WUTypes.h */, - ); - path = BasicTypes; - sourceTree = ""; - }; - 43278FD4194EFB30003C9FEA /* devicemanager */ = { - isa = PBXGroup; - children = ( - 43278FD5194EFB30003C9FEA /* IncludeWindows.h */, - 43278FD6194EFB30003C9FEA /* WCMRAudioDeviceManager.cpp */, - 43278FD7194EFB30003C9FEA /* WCMRAudioDeviceManager.h */, - 43278FD8194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.cpp */, - 43278FD9194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.h */, - 43278FDA194EFB30003C9FEA /* WCMRNativeAudio.cpp */, - 43278FDB194EFB30003C9FEA /* WCMRNativeAudio.h */, - 43278FDC194EFB30003C9FEA /* WCMRPortAudioDeviceManager.cpp */, - 43278FDD194EFB30003C9FEA /* WCMRPortAudioDeviceManager.h */, - ); - path = devicemanager; - sourceTree = ""; - }; - 43278FDE194EFB30003C9FEA /* miscutils */ = { - isa = PBXGroup; - children = ( - 43278FDF194EFB30003C9FEA /* MinMaxUtilities.h */, - 43278FE0194EFB30003C9FEA /* safe_delete.h */, - 43278FE1194EFB30003C9FEA /* UMicroseconds.cpp */, - 43278FE2194EFB30003C9FEA /* UMicroseconds.h */, - 43278FE3194EFB30003C9FEA /* WCFixedString.h */, - 43278FE4194EFB30003C9FEA /* WUErrors.h */, - ); - path = miscutils; - sourceTree = ""; - }; - 43278FE5194EFB30003C9FEA /* refmanager */ = { - isa = PBXGroup; - children = ( - 43278FE6194EFB30003C9FEA /* WCRefManager.cpp */, - 43278FE7194EFB30003C9FEA /* WCRefManager.h */, - ); - path = refmanager; - sourceTree = ""; - }; - 43278FE8194EFB30003C9FEA /* threads */ = { - isa = PBXGroup; - children = ( - 43278FE9194EFB30003C9FEA /* WCThreadSafe.cpp */, - 43278FEA194EFB30003C9FEA /* WCThreadSafe.h */, - ); - path = threads; - sourceTree = ""; - }; - 43278FEB194EFB30003C9FEA /* wavespublicapi */ = { - isa = PBXGroup; - children = ( - 43278FEC194EFB30003C9FEA /* 1.0 */, - 43278FEE194EFB30003C9FEA /* wstdint.h */, - 43278FEF194EFB30003C9FEA /* WTErr.h */, - ); - path = wavespublicapi; - sourceTree = ""; - }; - 43278FEC194EFB30003C9FEA /* 1.0 */ = { - isa = PBXGroup; - children = ( - 43278FED194EFB30003C9FEA /* WavesPublicAPI_Defines.h */, - ); - path = 1.0; - sourceTree = ""; - }; - 43AA86D3194EECE000A67B56 = { - isa = PBXGroup; - children = ( - 43278FC6194EFB30003C9FEA /* wavesapi */, - 43AA870C194EEDCA00A67B56 /* scripts */, - 43AA86E4194EECF300A67B56 /* headers */, - 43AA86E3194EECEB00A67B56 /* source */, - 43AA86DD194EECE000A67B56 /* Products */, - ); - sourceTree = ""; - }; - 43AA86DD194EECE000A67B56 /* Products */ = { - isa = PBXGroup; - children = ( - 43AA86DC194EECE000A67B56 /* libwaves_audiobackend.dylib */, - ); - name = Products; - sourceTree = SOURCE_ROOT; - }; - 43AA86E3194EECEB00A67B56 /* source */ = { - isa = PBXGroup; - children = ( - 43AA86E5194EED8900A67B56 /* waves_audiobackend.cc */, - 43AA86E6194EED8900A67B56 /* waves_audiobackend.latency.cc */, - 43AA86E7194EED8900A67B56 /* waves_audiobackend.midi.cc */, - 43AA86E8194EED8900A67B56 /* waves_audiobackend.port_engine.cc */, - 43AA86E9194EED8900A67B56 /* waves_audioport.cc */, - 43AA86EA194EED8900A67B56 /* waves_dataport.cc */, - 43AA86EB194EED8900A67B56 /* waves_midi_buffer.cc */, - 43AA86EC194EED8900A67B56 /* waves_midi_device_manager.cc */, - 43AA86ED194EED8900A67B56 /* waves_midi_device.cc */, - 43AA86EE194EED8900A67B56 /* waves_midi_event.cc */, - 43AA86EF194EED8900A67B56 /* waves_midiport.cc */, - ); - name = source; - sourceTree = SOURCE_ROOT; - }; - 43AA86E4194EECF300A67B56 /* headers */ = { - isa = PBXGroup; - children = ( - 43AA86FB194EEDAC00A67B56 /* waves_audiobackend.h */, - 43AA86FC194EEDAC00A67B56 /* waves_audioport.h */, - 43AA86FD194EEDAC00A67B56 /* waves_dataport.h */, - 43AA86FE194EEDAC00A67B56 /* waves_midi_buffer.h */, - 43AA86FF194EEDAC00A67B56 /* waves_midi_device_manager.h */, - 43AA8700194EEDAC00A67B56 /* waves_midi_device.h */, - 43AA8701194EEDAC00A67B56 /* waves_midi_event.h */, - 43AA8702194EEDAC00A67B56 /* waves_midiport.h */, - ); - name = headers; - sourceTree = SOURCE_ROOT; - }; - 43AA870C194EEDCA00A67B56 /* scripts */ = { - isa = PBXGroup; - children = ( - 43AA870B194EEDC600A67B56 /* wscript */, - ); - name = scripts; - sourceTree = SOURCE_ROOT; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 43AA86DA194EECE000A67B56 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 43AA8703194EEDAC00A67B56 /* waves_audiobackend.h in Headers */, - 43AA8704194EEDAC00A67B56 /* waves_audioport.h in Headers */, - 43AA8705194EEDAC00A67B56 /* waves_dataport.h in Headers */, - 43AA8706194EEDAC00A67B56 /* waves_midi_buffer.h in Headers */, - 43AA8707194EEDAC00A67B56 /* waves_midi_device_manager.h in Headers */, - 43AA8708194EEDAC00A67B56 /* waves_midi_device.h in Headers */, - 43AA8709194EEDAC00A67B56 /* waves_midi_event.h in Headers */, - 43AA870A194EEDAC00A67B56 /* waves_midiport.h in Headers */, - 43278FF0194EFB30003C9FEA /* basics.hpp in Headers */, - 43278FF1194EFB30003C9FEA /* compiletime_functions.hpp in Headers */, - 43278FF2194EFB30003C9FEA /* atomic_ops.hpp in Headers */, - 43278FF3194EFB30003C9FEA /* atomic_ops_gcc_x86.hpp in Headers */, - 43278FF4194EFB30003C9FEA /* WCFourCC.h in Headers */, - 43278FF5194EFB30003C9FEA /* WTByteOrder.h in Headers */, - 43278FF6194EFB30003C9FEA /* WUComPtr.h in Headers */, - 43278FF7194EFB30003C9FEA /* WUDefines.h in Headers */, - 43278FF8194EFB30003C9FEA /* WUMathConsts.h in Headers */, - 43278FF9194EFB30003C9FEA /* WUTypes.h in Headers */, - 43278FFA194EFB30003C9FEA /* IncludeWindows.h in Headers */, - 43278FFC194EFB30003C9FEA /* WCMRAudioDeviceManager.h in Headers */, - 43278FFE194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.h in Headers */, - 43279000194EFB30003C9FEA /* WCMRNativeAudio.h in Headers */, - 43279002194EFB30003C9FEA /* WCMRPortAudioDeviceManager.h in Headers */, - 43279003194EFB30003C9FEA /* MinMaxUtilities.h in Headers */, - 43279004194EFB30003C9FEA /* safe_delete.h in Headers */, - 43279006194EFB30003C9FEA /* UMicroseconds.h in Headers */, - 43279007194EFB30003C9FEA /* WCFixedString.h in Headers */, - 43279008194EFB30003C9FEA /* WUErrors.h in Headers */, - 4327900A194EFB30003C9FEA /* WCRefManager.h in Headers */, - 4327900C194EFB30003C9FEA /* WCThreadSafe.h in Headers */, - 4327900D194EFB30003C9FEA /* WavesPublicAPI_Defines.h in Headers */, - 4327900E194EFB30003C9FEA /* wstdint.h in Headers */, - 4327900F194EFB30003C9FEA /* WTErr.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 43AA86DB194EECE000A67B56 /* waves_audiobackend */ = { - isa = PBXNativeTarget; - buildConfigurationList = 43AA86E0194EECE000A67B56 /* Build configuration list for PBXNativeTarget "waves_audiobackend" */; - buildPhases = ( - 43AA86D8194EECE000A67B56 /* Sources */, - 43AA86D9194EECE000A67B56 /* Frameworks */, - 43AA86DA194EECE000A67B56 /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = waves_audiobackend; - productName = waves_audiobackend; - productReference = 43AA86DC194EECE000A67B56 /* libwaves_audiobackend.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 43AA86D4194EECE000A67B56 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0460; - ORGANIZATIONNAME = Waves; - }; - buildConfigurationList = 43AA86D7194EECE000A67B56 /* Build configuration list for PBXProject "waves_audiobackend" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 43AA86D3194EECE000A67B56; - productRefGroup = 43AA86DD194EECE000A67B56 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 43AA86DB194EECE000A67B56 /* waves_audiobackend */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 43AA86D8194EECE000A67B56 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 43AA86F0194EED8900A67B56 /* waves_audiobackend.cc in Sources */, - 43AA86F1194EED8900A67B56 /* waves_audiobackend.latency.cc in Sources */, - 43AA86F2194EED8900A67B56 /* waves_audiobackend.midi.cc in Sources */, - 43AA86F3194EED8900A67B56 /* waves_audiobackend.port_engine.cc in Sources */, - 43AA86F4194EED8900A67B56 /* waves_audioport.cc in Sources */, - 43AA86F5194EED8900A67B56 /* waves_dataport.cc in Sources */, - 43AA86F6194EED8900A67B56 /* waves_midi_buffer.cc in Sources */, - 43AA86F7194EED8900A67B56 /* waves_midi_device_manager.cc in Sources */, - 43AA86F8194EED8900A67B56 /* waves_midi_device.cc in Sources */, - 43AA86F9194EED8900A67B56 /* waves_midi_event.cc in Sources */, - 43AA86FA194EED8900A67B56 /* waves_midiport.cc in Sources */, - 43278FFB194EFB30003C9FEA /* WCMRAudioDeviceManager.cpp in Sources */, - 43278FFD194EFB30003C9FEA /* WCMRCoreAudioDeviceManager.cpp in Sources */, - 43278FFF194EFB30003C9FEA /* WCMRNativeAudio.cpp in Sources */, - 43279001194EFB30003C9FEA /* WCMRPortAudioDeviceManager.cpp in Sources */, - 43279005194EFB30003C9FEA /* UMicroseconds.cpp in Sources */, - 43279009194EFB30003C9FEA /* WCRefManager.cpp in Sources */, - 4327900B194EFB30003C9FEA /* WCThreadSafe.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 43AA86DE194EECE000A67B56 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - }; - name = Debug; - }; - 43AA86DF194EECE000A67B56 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - SDKROOT = macosx; - }; - name = Release; - }; - 43AA86E1194EECE000A67B56 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - EXECUTABLE_PREFIX = lib; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 43AA86E2194EECE000A67B56 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - EXECUTABLE_PREFIX = lib; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 43AA86D7194EECE000A67B56 /* Build configuration list for PBXProject "waves_audiobackend" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 43AA86DE194EECE000A67B56 /* Debug */, - 43AA86DF194EECE000A67B56 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 43AA86E0194EECE000A67B56 /* Build configuration list for PBXNativeTarget "waves_audiobackend" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 43AA86E1194EECE000A67B56 /* Debug */, - 43AA86E2194EECE000A67B56 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 43AA86D4194EECE000A67B56 /* Project object */; -} diff --git a/libs/backends/wavesaudio/portmidi/pmutil.h b/libs/backends/wavesaudio/portmidi/pmutil.h deleted file mode 100644 index 88ebf145ed..0000000000 --- a/libs/backends/wavesaudio/portmidi/pmutil.h +++ /dev/null @@ -1,127 +0,0 @@ -/* pmutil.h -- some helpful utilities for building midi - applications that use PortMidi - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef void PmQueue; - -/* - A single-reader, single-writer queue is created by - Pm_QueueCreate(), which takes the number of messages and - the message size as parameters. The queue only accepts - fixed sized messages. Returns NULL if memory cannot be allocated. - - This queue implementation uses the "light pipe" algorithm which - operates correctly even with multi-processors and out-of-order - memory writes. (see Alexander Dokumentov, "Lock-free Interprocess - Communication," Dr. Dobbs Portal, http://www.ddj.com/, - articleID=189401457, June 15, 2006. This algorithm requires - that messages be translated to a form where no words contain - zeros. Each word becomes its own "data valid" tag. Because of - this translation, we cannot return a pointer to data still in - the queue when the "peek" method is called. Instead, a buffer - is preallocated so that data can be copied there. Pm_QueuePeek() - dequeues a message into this buffer and returns a pointer to - it. A subsequent Pm_Dequeue() will copy from this buffer. - - This implementation does not try to keep reader/writer data in - separate cache lines or prevent thrashing on cache lines. - However, this algorithm differs by doing inserts/removals in - units of messages rather than units of machine words. Some - performance improvement might be obtained by not clearing data - immediately after a read, but instead by waiting for the end - of the cache line, especially if messages are smaller than - cache lines. See the Dokumentov article for explanation. - - The algorithm is extended to handle "overflow" reporting. To report - an overflow, the sender writes the current tail position to a field. - The receiver must acknowlege receipt by zeroing the field. The sender - will not send more until the field is zeroed. - - Pm_QueueDestroy() destroys the queue and frees its storage. - */ - -PMEXPORT PmQueue *Pm_QueueCreate(long num_msgs, int32_t bytes_per_msg); -PMEXPORT PmError Pm_QueueDestroy(PmQueue *queue); - -/* - Pm_Dequeue() removes one item from the queue, copying it into msg. - Returns 1 if successful, and 0 if the queue is empty. - Returns pmBufferOverflow if what would have been the next thing - in the queue was dropped due to overflow. (So when overflow occurs, - the receiver can receive a queue full of messages before getting the - overflow report. This protocol ensures that the reader will be - notified when data is lost due to overflow. - */ -PMEXPORT PmError Pm_Dequeue(PmQueue *queue, void *msg); - - -/* - Pm_Enqueue() inserts one item into the queue, copying it from msg. - Returns pmNoError if successful and pmBufferOverflow if the queue was - already full. If pmBufferOverflow is returned, the overflow flag is set. - */ -PMEXPORT PmError Pm_Enqueue(PmQueue *queue, void *msg); - - -/* - Pm_QueueFull() returns non-zero if the queue is full - Pm_QueueEmpty() returns non-zero if the queue is empty - - Either condition may change immediately because a parallel - enqueue or dequeue operation could be in progress. Furthermore, - Pm_QueueEmpty() is optimistic: it may say false, when due to - out-of-order writes, the full message has not arrived. Therefore, - Pm_Dequeue() could still return 0 after Pm_QueueEmpty() returns - false. On the other hand, Pm_QueueFull() is pessimistic: if it - returns false, then Pm_Enqueue() is guaranteed to succeed. - - Error conditions: Pm_QueueFull() returns pmBadPtr if queue is NULL. - Pm_QueueEmpty() returns FALSE if queue is NULL. - */ -PMEXPORT int Pm_QueueFull(PmQueue *queue); -PMEXPORT int Pm_QueueEmpty(PmQueue *queue); - - -/* - Pm_QueuePeek() returns a pointer to the item at the head of the queue, - or NULL if the queue is empty. The item is not removed from the queue. - Pm_QueuePeek() will not indicate when an overflow occurs. If you want - to get and check pmBufferOverflow messages, use the return value of - Pm_QueuePeek() *only* as an indication that you should call - Pm_Dequeue(). At the point where a direct call to Pm_Dequeue() would - return pmBufferOverflow, Pm_QueuePeek() will return NULL but internally - clear the pmBufferOverflow flag, enabling Pm_Enqueue() to resume - enqueuing messages. A subsequent call to Pm_QueuePeek() - will return a pointer to the first message *after* the overflow. - Using this as an indication to call Pm_Dequeue(), the first call - to Pm_Dequeue() will return pmBufferOverflow. The second call will - return success, copying the same message pointed to by the previous - Pm_QueuePeek(). - - When to use Pm_QueuePeek(): (1) when you need to look at the message - data to decide who should be called to receive it. (2) when you need - to know a message is ready but cannot accept the message. - - Note that Pm_QueuePeek() is not a fast check, so if possible, you - might as well just call Pm_Dequeue() and accept the data if it is there. - */ -PMEXPORT void *Pm_QueuePeek(PmQueue *queue); - -/* - Pm_SetOverflow() allows the writer (enqueuer) to signal an overflow - condition to the reader (dequeuer). E.g. when transfering data from - the OS to an application, if the OS indicates a buffer overrun, - Pm_SetOverflow() can be used to insure that the reader receives a - pmBufferOverflow result from Pm_Dequeue(). Returns pmBadPtr if queue - is NULL, returns pmBufferOverflow if buffer is already in an overflow - state, returns pmNoError if successfully set overflow state. - */ -PMEXPORT PmError Pm_SetOverflow(PmQueue *queue); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ diff --git a/libs/backends/wavesaudio/portmidi/portmidi.h b/libs/backends/wavesaudio/portmidi/portmidi.h deleted file mode 100644 index 50f74adcb0..0000000000 --- a/libs/backends/wavesaudio/portmidi/portmidi.h +++ /dev/null @@ -1,654 +0,0 @@ -#ifndef PORT_MIDI_H -#define PORT_MIDI_H -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * PortMidi Portable Real-Time MIDI Library - * PortMidi API Header File - * Latest version available at: http://sourceforge.net/projects/portmedia - * - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * Copyright (c) 2001-2006 Roger B. Dannenberg - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortMidi license; however, - * the PortMusic community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/* CHANGELOG FOR PORTMIDI - * (see ../CHANGELOG.txt) - * - * NOTES ON HOST ERROR REPORTING: - * - * PortMidi errors (of type PmError) are generic, system-independent errors. - * When an error does not map to one of the more specific PmErrors, the - * catch-all code pmHostError is returned. This means that PortMidi has - * retained a more specific system-dependent error code. The caller can - * get more information by calling Pm_HasHostError() to test if there is - * a pending host error, and Pm_GetHostErrorText() to get a text string - * describing the error. Host errors are reported on a per-device basis - * because only after you open a device does PortMidi have a place to - * record the host error code. I.e. only - * those routines that receive a (PortMidiStream *) argument check and - * report errors. One exception to this is that Pm_OpenInput() and - * Pm_OpenOutput() can report errors even though when an error occurs, - * there is no PortMidiStream* to hold the error. Fortunately, both - * of these functions return any error immediately, so we do not really - * need per-device error memory. Instead, any host error code is stored - * in a global, pmHostError is returned, and the user can call - * Pm_GetHostErrorText() to get the error message (and the invalid stream - * parameter will be ignored.) The functions - * pm_init and pm_term do not fail or raise - * errors. The job of pm_init is to locate all available devices so that - * the caller can get information via PmDeviceInfo(). If an error occurs, - * the device is simply not listed as available. - * - * Host errors come in two flavors: - * a) host error - * b) host error during callback - * These can occur w/midi input or output devices. (b) can only happen - * asynchronously (during callback routines), whereas (a) only occurs while - * synchronously running PortMidi and any resulting system dependent calls. - * Both (a) and (b) are reported by the next read or write call. You can - * also query for asynchronous errors (b) at any time by calling - * Pm_HasHostError(). - * - * NOTES ON COMPILE-TIME SWITCHES - * - * DEBUG assumes stdio and a console. Use this if you want automatic, simple - * error reporting, e.g. for prototyping. If you are using MFC or some - * other graphical interface with no console, DEBUG probably should be - * undefined. - * PM_CHECK_ERRORS more-or-less takes over error checking for return values, - * stopping your program and printing error messages when an error - * occurs. This also uses stdio for console text I/O. - */ - -#ifndef WIN32 -// Linux and OS X have stdint.h -#include -#else -#ifndef INT32_DEFINED -// rather than having users install a special .h file for windows, -// just put the required definitions inline here. porttime.h uses -// these too, so the definitions are (unfortunately) duplicated there -typedef int int32_t; -typedef unsigned int uint32_t; -#define INT32_DEFINED -#endif -#endif - -#ifdef _WINDLL -#define PMEXPORT __declspec(dllexport) -#else -#define PMEXPORT -#endif - -#ifndef FALSE - #define FALSE 0 -#endif -#ifndef TRUE - #define TRUE 1 -#endif - -/* default size of buffers for sysex transmission: */ -#define PM_DEFAULT_SYSEX_BUFFER_SIZE 1024 - -/** List of portmidi errors.*/ -typedef enum { - pmNoError = 0, - pmNoData = 0, /**< A "no error" return that also indicates no data avail. */ - pmGotData = 1, /**< A "no error" return that also indicates data available */ - pmHostError = -10000, - pmInvalidDeviceId, /** out of range or - * output device when input is requested or - * input device when output is requested or - * device is already opened - */ - pmInsufficientMemory, - pmBufferTooSmall, - pmBufferOverflow, - pmBadPtr, /* PortMidiStream parameter is NULL or - * stream is not opened or - * stream is output when input is required or - * stream is input when output is required */ - pmBadData, /** illegal midi data, e.g. missing EOX */ - pmInternalError, - pmBufferMaxSize /** buffer is already as large as it can be */ - /* NOTE: If you add a new error type, be sure to update Pm_GetErrorText() */ -} PmError; - -/** - Pm_Initialize() is the library initialisation function - call this before - using the library. -*/ -PMEXPORT PmError Pm_Initialize( void ); - -/** - Pm_Terminate() is the library termination function - call this after - using the library. -*/ -PMEXPORT PmError Pm_Terminate( void ); - -/** A single PortMidiStream is a descriptor for an open MIDI device. -*/ -typedef void PortMidiStream; -#define PmStream PortMidiStream - -/** - Test whether stream has a pending host error. Normally, the client finds - out about errors through returned error codes, but some errors can occur - asynchronously where the client does not - explicitly call a function, and therefore cannot receive an error code. - The client can test for a pending error using Pm_HasHostError(). If true, - the error can be accessed and cleared by calling Pm_GetErrorText(). - Errors are also cleared by calling other functions that can return - errors, e.g. Pm_OpenInput(), Pm_OpenOutput(), Pm_Read(), Pm_Write(). The - client does not need to call Pm_HasHostError(). Any pending error will be - reported the next time the client performs an explicit function call on - the stream, e.g. an input or output operation. Until the error is cleared, - no new error codes will be obtained, even for a different stream. -*/ -PMEXPORT int Pm_HasHostError( PortMidiStream * stream ); - - -/** Translate portmidi error number into human readable message. - These strings are constants (set at compile time) so client has - no need to allocate storage -*/ -PMEXPORT const char *Pm_GetErrorText( PmError errnum ); - -/** Translate portmidi host error into human readable message. - These strings are computed at run time, so client has to allocate storage. - After this routine executes, the host error is cleared. -*/ -PMEXPORT void Pm_GetHostErrorText(char * msg, unsigned int len); - -#define HDRLENGTH 50 -#define PM_HOST_ERROR_MSG_LEN 256u /* any host error msg will occupy less - than this number of characters */ - -/** - Device enumeration mechanism. - - Device ids range from 0 to Pm_CountDevices()-1. - -*/ -typedef int PmDeviceID; -#define pmNoDevice -1 -typedef struct { - int structVersion; /**< this internal structure version */ - const char *interf; /**< underlying MIDI API, e.g. MMSystem or DirectX */ - const char *name; /**< device name, e.g. USB MidiSport 1x1 */ - int input; /**< true iff input is available */ - int output; /**< true iff output is available */ - int opened; /**< used by generic PortMidi code to do error checking on arguments */ - -} PmDeviceInfo; - -/** Get devices count, ids range from 0 to Pm_CountDevices()-1. */ -PMEXPORT int Pm_CountDevices( void ); -/** - Pm_GetDefaultInputDeviceID(), Pm_GetDefaultOutputDeviceID() - - Return the default device ID or pmNoDevice if there are no devices. - The result (but not pmNoDevice) can be passed to Pm_OpenMidi(). - - The default device can be specified using a small application - named pmdefaults that is part of the PortMidi distribution. This - program in turn uses the Java Preferences object created by - java.util.prefs.Preferences.userRoot().node("/PortMidi"); the - preference is set by calling - prefs.put("PM_RECOMMENDED_OUTPUT_DEVICE", prefName); - or prefs.put("PM_RECOMMENDED_INPUT_DEVICE", prefName); - - In the statements above, prefName is a string describing the - MIDI device in the form "interf, name" where interf identifies - the underlying software system or API used by PortMdi to access - devices and name is the name of the device. These correspond to - the interf and name fields of a PmDeviceInfo. (Currently supported - interfaces are "MMSystem" for Win32, "ALSA" for Linux, and - "CoreMIDI" for OS X, so in fact, there is no choice of interface.) - In "interf, name", the strings are actually substrings of - the full interface and name strings. For example, the preference - "Core, Sport" will match a device with interface "CoreMIDI" - and name "In USB MidiSport 1x1". It will also match "CoreMIDI" - and "In USB MidiSport 2x2". The devices are enumerated in device - ID order, so the lowest device ID that matches the pattern becomes - the default device. Finally, if the comma-space (", ") separator - between interface and name parts of the preference is not found, - the entire preference string is interpreted as a name, and the - interface part is the empty string, which matches anything. - - On the MAC, preferences are stored in - /Users/$NAME/Library/Preferences/com.apple.java.util.prefs.plist - which is a binary file. In addition to the pmdefaults program, - there are utilities that can read and edit this preference file. - - On the PC, - - On Linux, - -*/ -PMEXPORT PmDeviceID Pm_GetDefaultInputDeviceID( void ); -/** see PmDeviceID Pm_GetDefaultInputDeviceID() */ -PMEXPORT PmDeviceID Pm_GetDefaultOutputDeviceID( void ); - -/** - PmTimestamp is used to represent a millisecond clock with arbitrary - start time. The type is used for all MIDI timestampes and clocks. -*/ -typedef int32_t PmTimestamp; -typedef PmTimestamp (*PmTimeProcPtr)(void *time_info); - -/** TRUE if t1 before t2 */ -#define PmBefore(t1,t2) ((t1-t2) < 0) -/** - \defgroup grp_device Input/Output Devices Handling - @{ -*/ -/** - Pm_GetDeviceInfo() returns a pointer to a PmDeviceInfo structure - referring to the device specified by id. - If id is out of range the function returns NULL. - - The returned structure is owned by the PortMidi implementation and must - not be manipulated or freed. The pointer is guaranteed to be valid - between calls to Pm_Initialize() and Pm_Terminate(). -*/ -PMEXPORT const PmDeviceInfo* Pm_GetDeviceInfo( PmDeviceID id ); - -/** - Pm_OpenInput() and Pm_OpenOutput() open devices. - - stream is the address of a PortMidiStream pointer which will receive - a pointer to the newly opened stream. - - inputDevice is the id of the device used for input (see PmDeviceID above). - - inputDriverInfo is a pointer to an optional driver specific data structure - containing additional information for device setup or handle processing. - inputDriverInfo is never required for correct operation. If not used - inputDriverInfo should be NULL. - - outputDevice is the id of the device used for output (see PmDeviceID above.) - - outputDriverInfo is a pointer to an optional driver specific data structure - containing additional information for device setup or handle processing. - outputDriverInfo is never required for correct operation. If not used - outputDriverInfo should be NULL. - - For input, the buffersize specifies the number of input events to be - buffered waiting to be read using Pm_Read(). For output, buffersize - specifies the number of output events to be buffered waiting for output. - (In some cases -- see below -- PortMidi does not buffer output at all - and merely passes data to a lower-level API, in which case buffersize - is ignored.) - - latency is the delay in milliseconds applied to timestamps to determine - when the output should actually occur. (If latency is < 0, 0 is assumed.) - If latency is zero, timestamps are ignored and all output is delivered - immediately. If latency is greater than zero, output is delayed until the - message timestamp plus the latency. (NOTE: the time is measured relative - to the time source indicated by time_proc. Timestamps are absolute, - not relative delays or offsets.) In some cases, PortMidi can obtain - better timing than your application by passing timestamps along to the - device driver or hardware. Latency may also help you to synchronize midi - data to audio data by matching midi latency to the audio buffer latency. - - time_proc is a pointer to a procedure that returns time in milliseconds. It - may be NULL, in which case a default millisecond timebase (PortTime) is - used. If the application wants to use PortTime, it should start the timer - (call Pt_Start) before calling Pm_OpenInput or Pm_OpenOutput. If the - application tries to start the timer *after* Pm_OpenInput or Pm_OpenOutput, - it may get a ptAlreadyStarted error from Pt_Start, and the application's - preferred time resolution and callback function will be ignored. - time_proc result values are appended to incoming MIDI data, and time_proc - times are used to schedule outgoing MIDI data (when latency is non-zero). - - time_info is a pointer passed to time_proc. - - Example: If I provide a timestamp of 5000, latency is 1, and time_proc - returns 4990, then the desired output time will be when time_proc returns - timestamp+latency = 5001. This will be 5001-4990 = 11ms from now. - - return value: - Upon success Pm_Open() returns PmNoError and places a pointer to a - valid PortMidiStream in the stream argument. - If a call to Pm_Open() fails a nonzero error code is returned (see - PMError above) and the value of port is invalid. - - Any stream that is successfully opened should eventually be closed - by calling Pm_Close(). - -*/ -PMEXPORT PmError Pm_OpenInput( PortMidiStream** stream, - PmDeviceID inputDevice, - void *inputDriverInfo, - int32_t bufferSize, - PmTimeProcPtr time_proc, - void *time_info ); - -PMEXPORT PmError Pm_OpenOutput( PortMidiStream** stream, - PmDeviceID outputDevice, - void *outputDriverInfo, - int32_t bufferSize, - PmTimeProcPtr time_proc, - void *time_info, - int32_t latency ); - /** @} */ - -/** - \defgroup grp_events_filters Events and Filters Handling - @{ -*/ - -/* \function PmError Pm_SetFilter( PortMidiStream* stream, int32_t filters ) - Pm_SetFilter() sets filters on an open input stream to drop selected - input types. By default, only active sensing messages are filtered. - To prohibit, say, active sensing and sysex messages, call - Pm_SetFilter(stream, PM_FILT_ACTIVE | PM_FILT_SYSEX); - - Filtering is useful when midi routing or midi thru functionality is being - provided by the user application. - For example, you may want to exclude timing messages (clock, MTC, start/stop/continue), - while allowing note-related messages to pass. - Or you may be using a sequencer or drum-machine for MIDI clock information but want to - exclude any notes it may play. - */ - -/* Filter bit-mask definitions */ -/** filter active sensing messages (0xFE): */ -#define PM_FILT_ACTIVE (1 << 0x0E) -/** filter system exclusive messages (0xF0): */ -#define PM_FILT_SYSEX (1 << 0x00) -/** filter MIDI clock message (0xF8) */ -#define PM_FILT_CLOCK (1 << 0x08) -/** filter play messages (start 0xFA, stop 0xFC, continue 0xFB) */ -#define PM_FILT_PLAY ((1 << 0x0A) | (1 << 0x0C) | (1 << 0x0B)) -/** filter tick messages (0xF9) */ -#define PM_FILT_TICK (1 << 0x09) -/** filter undefined FD messages */ -#define PM_FILT_FD (1 << 0x0D) -/** filter undefined real-time messages */ -#define PM_FILT_UNDEFINED PM_FILT_FD -/** filter reset messages (0xFF) */ -#define PM_FILT_RESET (1 << 0x0F) -/** filter all real-time messages */ -#define PM_FILT_REALTIME (PM_FILT_ACTIVE | PM_FILT_SYSEX | PM_FILT_CLOCK | \ - PM_FILT_PLAY | PM_FILT_UNDEFINED | PM_FILT_RESET | PM_FILT_TICK) -/** filter note-on and note-off (0x90-0x9F and 0x80-0x8F */ -#define PM_FILT_NOTE ((1 << 0x19) | (1 << 0x18)) -/** filter channel aftertouch (most midi controllers use this) (0xD0-0xDF)*/ -#define PM_FILT_CHANNEL_AFTERTOUCH (1 << 0x1D) -/** per-note aftertouch (0xA0-0xAF) */ -#define PM_FILT_POLY_AFTERTOUCH (1 << 0x1A) -/** filter both channel and poly aftertouch */ -#define PM_FILT_AFTERTOUCH (PM_FILT_CHANNEL_AFTERTOUCH | PM_FILT_POLY_AFTERTOUCH) -/** Program changes (0xC0-0xCF) */ -#define PM_FILT_PROGRAM (1 << 0x1C) -/** Control Changes (CC's) (0xB0-0xBF)*/ -#define PM_FILT_CONTROL (1 << 0x1B) -/** Pitch Bender (0xE0-0xEF*/ -#define PM_FILT_PITCHBEND (1 << 0x1E) -/** MIDI Time Code (0xF1)*/ -#define PM_FILT_MTC (1 << 0x01) -/** Song Position (0xF2) */ -#define PM_FILT_SONG_POSITION (1 << 0x02) -/** Song Select (0xF3)*/ -#define PM_FILT_SONG_SELECT (1 << 0x03) -/** Tuning request (0xF6)*/ -#define PM_FILT_TUNE (1 << 0x06) -/** All System Common messages (mtc, song position, song select, tune request) */ -#define PM_FILT_SYSTEMCOMMON (PM_FILT_MTC | PM_FILT_SONG_POSITION | PM_FILT_SONG_SELECT | PM_FILT_TUNE) - - -PMEXPORT PmError Pm_SetFilter( PortMidiStream* stream, int32_t filters ); - -#define Pm_Channel(channel) (1<<(channel)) -/** - Pm_SetChannelMask() filters incoming messages based on channel. - The mask is a 16-bit bitfield corresponding to appropriate channels. - The Pm_Channel macro can assist in calling this function. - i.e. to set receive only input on channel 1, call with - Pm_SetChannelMask(Pm_Channel(1)); - Multiple channels should be OR'd together, like - Pm_SetChannelMask(Pm_Channel(10) | Pm_Channel(11)) - - Note that channels are numbered 0 to 15 (not 1 to 16). Most - synthesizer and interfaces number channels starting at 1, but - PortMidi numbers channels starting at 0. - - All channels are allowed by default -*/ -PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask); - -/** - Pm_Abort() terminates outgoing messages immediately - The caller should immediately close the output port; - this call may result in transmission of a partial midi message. - There is no abort for Midi input because the user can simply - ignore messages in the buffer and close an input device at - any time. - */ -PMEXPORT PmError Pm_Abort( PortMidiStream* stream ); - -/** - Pm_Close() closes a midi stream, flushing any pending buffers. - (PortMidi attempts to close open streams when the application - exits -- this is particularly difficult under Windows.) -*/ -PMEXPORT PmError Pm_Close( PortMidiStream* stream ); - -/** - Pm_Synchronize() instructs PortMidi to (re)synchronize to the - time_proc passed when the stream was opened. Typically, this - is used when the stream must be opened before the time_proc - reference is actually advancing. In this case, message timing - may be erratic, but since timestamps of zero mean - "send immediately," initialization messages with zero timestamps - can be written without a functioning time reference and without - problems. Before the first MIDI message with a non-zero - timestamp is written to the stream, the time reference must - begin to advance (for example, if the time_proc computes time - based on audio samples, time might begin to advance when an - audio stream becomes active). After time_proc return values - become valid, and BEFORE writing the first non-zero timestamped - MIDI message, call Pm_Synchronize() so that PortMidi can observe - the difference between the current time_proc value and its - MIDI stream time. - - In the more normal case where time_proc - values advance continuously, there is no need to call - Pm_Synchronize. PortMidi will always synchronize at the - first output message and periodically thereafter. -*/ -PmError Pm_Synchronize( PortMidiStream* stream ); - - -/** - Pm_Message() encodes a short Midi message into a 32-bit word. If data1 - and/or data2 are not present, use zero. - - Pm_MessageStatus(), Pm_MessageData1(), and - Pm_MessageData2() extract fields from a 32-bit midi message. -*/ -#define Pm_Message(status, data1, data2) \ - ((((data2) << 16) & 0xFF0000) | \ - (((data1) << 8) & 0xFF00) | \ - ((status) & 0xFF)) -#define Pm_MessageStatus(msg) ((msg) & 0xFF) -#define Pm_MessageData1(msg) (((msg) >> 8) & 0xFF) -#define Pm_MessageData2(msg) (((msg) >> 16) & 0xFF) - -typedef int32_t PmMessage; /**< see PmEvent */ -/** - All midi data comes in the form of PmEvent structures. A sysex - message is encoded as a sequence of PmEvent structures, with each - structure carrying 4 bytes of the message, i.e. only the first - PmEvent carries the status byte. - - Note that MIDI allows nested messages: the so-called "real-time" MIDI - messages can be inserted into the MIDI byte stream at any location, - including within a sysex message. MIDI real-time messages are one-byte - messages used mainly for timing (see the MIDI spec). PortMidi retains - the order of non-real-time MIDI messages on both input and output, but - it does not specify exactly how real-time messages are processed. This - is particulary problematic for MIDI input, because the input parser - must either prepare to buffer an unlimited number of sysex message - bytes or to buffer an unlimited number of real-time messages that - arrive embedded in a long sysex message. To simplify things, the input - parser is allowed to pass real-time MIDI messages embedded within a - sysex message, and it is up to the client to detect, process, and - remove these messages as they arrive. - - When receiving sysex messages, the sysex message is terminated - by either an EOX status byte (anywhere in the 4 byte messages) or - by a non-real-time status byte in the low order byte of the message. - If you get a non-real-time status byte but there was no EOX byte, it - means the sysex message was somehow truncated. This is not - considered an error; e.g., a missing EOX can result from the user - disconnecting a MIDI cable during sysex transmission. - - A real-time message can occur within a sysex message. A real-time - message will always occupy a full PmEvent with the status byte in - the low-order byte of the PmEvent message field. (This implies that - the byte-order of sysex bytes and real-time message bytes may not - be preserved -- for example, if a real-time message arrives after - 3 bytes of a sysex message, the real-time message will be delivered - first. The first word of the sysex message will be delivered only - after the 4th byte arrives, filling the 4-byte PmEvent message field. - - The timestamp field is observed when the output port is opened with - a non-zero latency. A timestamp of zero means "use the current time", - which in turn means to deliver the message with a delay of - latency (the latency parameter used when opening the output port.) - Do not expect PortMidi to sort data according to timestamps -- - messages should be sent in the correct order, and timestamps MUST - be non-decreasing. See also "Example" for Pm_OpenOutput() above. - - A sysex message will generally fill many PmEvent structures. On - output to a PortMidiStream with non-zero latency, the first timestamp - on sysex message data will determine the time to begin sending the - message. PortMidi implementations may ignore timestamps for the - remainder of the sysex message. - - On input, the timestamp ideally denotes the arrival time of the - status byte of the message. The first timestamp on sysex message - data will be valid. Subsequent timestamps may denote - when message bytes were actually received, or they may be simply - copies of the first timestamp. - - Timestamps for nested messages: If a real-time message arrives in - the middle of some other message, it is enqueued immediately with - the timestamp corresponding to its arrival time. The interrupted - non-real-time message or 4-byte packet of sysex data will be enqueued - later. The timestamp of interrupted data will be equal to that of - the interrupting real-time message to insure that timestamps are - non-decreasing. - */ -typedef struct { - PmMessage message; - PmTimestamp timestamp; -} PmEvent; - -/** - @} -*/ -/** \defgroup grp_io Reading and Writing Midi Messages - @{ -*/ -/** - Pm_Read() retrieves midi data into a buffer, and returns the number - of events read. Result is a non-negative number unless an error occurs, - in which case a PmError value will be returned. - - Buffer Overflow - - The problem: if an input overflow occurs, data will be lost, ultimately - because there is no flow control all the way back to the data source. - When data is lost, the receiver should be notified and some sort of - graceful recovery should take place, e.g. you shouldn't resume receiving - in the middle of a long sysex message. - - With a lock-free fifo, which is pretty much what we're stuck with to - enable portability to the Mac, it's tricky for the producer and consumer - to synchronously reset the buffer and resume normal operation. - - Solution: the buffer managed by PortMidi will be flushed when an overflow - occurs. The consumer (Pm_Read()) gets an error message (pmBufferOverflow) - and ordinary processing resumes as soon as a new message arrives. The - remainder of a partial sysex message is not considered to be a "new - message" and will be flushed as well. - -*/ -PMEXPORT int Pm_Read( PortMidiStream *stream, PmEvent *buffer, int32_t length ); - -/** - Pm_Poll() tests whether input is available, - returning TRUE, FALSE, or an error value. -*/ -PMEXPORT PmError Pm_Poll( PortMidiStream *stream); - -/** - Pm_Write() writes midi data from a buffer. This may contain: - - short messages - or - - sysex messages that are converted into a sequence of PmEvent - structures, e.g. sending data from a file or forwarding them - from midi input. - - Use Pm_WriteSysEx() to write a sysex message stored as a contiguous - array of bytes. - - Sysex data may contain embedded real-time messages. -*/ -PMEXPORT PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, int32_t length ); - -/** - Pm_WriteShort() writes a timestamped non-system-exclusive midi message. - Messages are delivered in order as received, and timestamps must be - non-decreasing. (But timestamps are ignored if the stream was opened - with latency = 0.) -*/ -PMEXPORT PmError Pm_WriteShort( PortMidiStream *stream, PmTimestamp when, int32_t msg); - -/** - Pm_WriteSysEx() writes a timestamped system-exclusive midi message. -*/ -PMEXPORT PmError Pm_WriteSysEx( PortMidiStream *stream, PmTimestamp when, unsigned char *msg); - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PORT_MIDI_H */ diff --git a/libs/backends/wavesaudio/portmidi/porttime.h b/libs/backends/wavesaudio/portmidi/porttime.h deleted file mode 100644 index c7b7aff218..0000000000 --- a/libs/backends/wavesaudio/portmidi/porttime.h +++ /dev/null @@ -1,92 +0,0 @@ -/* porttime.h -- portable interface to millisecond timer */ - -/* CHANGE LOG FOR PORTTIME - 10-Jun-03 Mark Nelson & RBD - boost priority of timer thread in ptlinux.c implementation - */ - -/* Should there be a way to choose the source of time here? */ - -#ifdef WIN32 -#ifndef INT32_DEFINED -// rather than having users install a special .h file for windows, -// just put the required definitions inline here. portmidi.h uses -// these too, so the definitions are (unfortunately) duplicated there -typedef int int32_t; -typedef unsigned int uint32_t; -#define INT32_DEFINED -#endif -#else -#include // needed for int32_t -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef PMEXPORT -#ifdef _WINDLL -#define PMEXPORT __declspec(dllexport) -#else -#define PMEXPORT -#endif -#endif - -typedef enum { - ptNoError = 0, /* success */ - ptHostError = -10000, /* a system-specific error occurred */ - ptAlreadyStarted, /* cannot start timer because it is already started */ - ptAlreadyStopped, /* cannot stop timer because it is already stopped */ - ptInsufficientMemory /* memory could not be allocated */ -} PtError; - - -typedef int32_t PtTimestamp; - -typedef void (PtCallback)( PtTimestamp timestamp, void *userData ); - -/* - Pt_Start() starts a real-time service. - - resolution is the timer resolution in ms. The time will advance every - resolution ms. - - callback is a function pointer to be called every resolution ms. - - userData is passed to callback as a parameter. - - return value: - Upon success, returns ptNoError. See PtError for other values. -*/ -PMEXPORT PtError Pt_Start(int resolution, PtCallback *callback, void *userData); - -/* - Pt_Stop() stops the timer. - - return value: - Upon success, returns ptNoError. See PtError for other values. -*/ -PMEXPORT PtError Pt_Stop(); - -/* - Pt_Started() returns true iff the timer is running. -*/ -PMEXPORT int Pt_Started(); - -/* - Pt_Time() returns the current time in ms. -*/ -PMEXPORT PtTimestamp Pt_Time(); - -/* - Pt_Sleep() pauses, allowing other threads to run. - - duration is the length of the pause in ms. The true duration - of the pause may be rounded to the nearest or next clock tick - as determined by resolution in Pt_Start(). -*/ -PMEXPORT void Pt_Sleep(int32_t duration); - -#ifdef __cplusplus -} -#endif diff --git a/libs/backends/wavesaudio/portmidi/src/pm_common/pminternal.h b/libs/backends/wavesaudio/portmidi/src/pm_common/pminternal.h deleted file mode 100644 index 9894c69681..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_common/pminternal.h +++ /dev/null @@ -1,178 +0,0 @@ -/* pminternal.h -- header for interface implementations */ - -/* this file is included by files that implement library internals */ -/* Here is a guide to implementers: - provide an initialization function similar to pm_winmm_init() - add your initialization function to pm_init() - Note that your init function should never require not-standard - libraries or fail in any way. If the interface is not available, - simply do not call pm_add_device. This means that non-standard - libraries should try to do dynamic linking at runtime using a DLL - and return without error if the DLL cannot be found or if there - is any other failure. - implement functions as indicated in pm_fns_type to open, read, write, - close, etc. - call pm_add_device() for each input and output device, passing it a - pm_fns_type structure. - assumptions about pm_fns_type functions are given below. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern int pm_initialized; /* see note in portmidi.c */ - -/* these are defined in system-specific file */ -void *pm_alloc(size_t s); -void pm_free(void *ptr); - -/* if an error occurs while opening or closing a midi stream, set these: */ -extern int pm_hosterror; -extern char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN]; - -struct pm_internal_struct; - -/* these do not use PmInternal because it is not defined yet... */ -typedef PmError (*pm_write_short_fn)(struct pm_internal_struct *midi, - PmEvent *buffer); -typedef PmError (*pm_begin_sysex_fn)(struct pm_internal_struct *midi, - PmTimestamp timestamp); -typedef PmError (*pm_end_sysex_fn)(struct pm_internal_struct *midi, - PmTimestamp timestamp); -typedef PmError (*pm_write_byte_fn)(struct pm_internal_struct *midi, - unsigned char byte, PmTimestamp timestamp); -typedef PmError (*pm_write_realtime_fn)(struct pm_internal_struct *midi, - PmEvent *buffer); -typedef PmError (*pm_write_flush_fn)(struct pm_internal_struct *midi, - PmTimestamp timestamp); -typedef PmTimestamp (*pm_synchronize_fn)(struct pm_internal_struct *midi); -/* pm_open_fn should clean up all memory and close the device if any part - of the open fails */ -typedef PmError (*pm_open_fn)(struct pm_internal_struct *midi, - void *driverInfo); -typedef PmError (*pm_abort_fn)(struct pm_internal_struct *midi); -/* pm_close_fn should clean up all memory and close the device if any - part of the close fails. */ -typedef PmError (*pm_close_fn)(struct pm_internal_struct *midi); -typedef PmError (*pm_poll_fn)(struct pm_internal_struct *midi); -typedef void (*pm_host_error_fn)(struct pm_internal_struct *midi, char * msg, - unsigned int len); -typedef unsigned int (*pm_has_host_error_fn)(struct pm_internal_struct *midi); - -typedef struct { - pm_write_short_fn write_short; /* output short MIDI msg */ - pm_begin_sysex_fn begin_sysex; /* prepare to send a sysex message */ - pm_end_sysex_fn end_sysex; /* marks end of sysex message */ - pm_write_byte_fn write_byte; /* accumulate one more sysex byte */ - pm_write_realtime_fn write_realtime; /* send real-time message within sysex */ - pm_write_flush_fn write_flush; /* send any accumulated but unsent data */ - pm_synchronize_fn synchronize; /* synchronize portmidi time to stream time */ - pm_open_fn open; /* open MIDI device */ - pm_abort_fn abort; /* abort */ - pm_close_fn close; /* close device */ - pm_poll_fn poll; /* read pending midi events into portmidi buffer */ - pm_has_host_error_fn has_host_error; /* true when device has had host - error message */ - pm_host_error_fn host_error; /* provide text readable host error message - for device (clears and resets) */ -} pm_fns_node, *pm_fns_type; - - -/* when open fails, the dictionary gets this set of functions: */ -extern pm_fns_node pm_none_dictionary; - -typedef struct { - PmDeviceInfo pub; /* some portmidi state also saved in here (for autmatic - device closing (see PmDeviceInfo struct) */ - void *descriptor; /* ID number passed to win32 multimedia API open */ - void *internalDescriptor; /* points to PmInternal device, allows automatic - device closing */ - pm_fns_type dictionary; -} descriptor_node, *descriptor_type; - -extern int pm_descriptor_max; -extern descriptor_type descriptors; -extern int pm_descriptor_index; - -typedef uint32_t (*time_get_proc_type)(void *time_info); - -typedef struct pm_internal_struct { - int device_id; /* which device is open (index to descriptors) */ - short write_flag; /* MIDI_IN, or MIDI_OUT */ - - PmTimeProcPtr time_proc; /* where to get the time */ - void *time_info; /* pass this to get_time() */ - int32_t buffer_len; /* how big is the buffer or queue? */ - PmQueue *queue; - - int32_t latency; /* time delay in ms between timestamps and actual output */ - /* set to zero to get immediate, simple blocking output */ - /* if latency is zero, timestamps will be ignored; */ - /* if midi input device, this field ignored */ - - int sysex_in_progress; /* when sysex status is seen, this flag becomes - * true until EOX is seen. When true, new data is appended to the - * stream of outgoing bytes. When overflow occurs, sysex data is - * dropped (until an EOX or non-real-timei status byte is seen) so - * that, if the overflow condition is cleared, we don't start - * sending data from the middle of a sysex message. If a sysex - * message is filtered, sysex_in_progress is false, causing the - * message to be dropped. */ - PmMessage sysex_message; /* buffer for 4 bytes of sysex data */ - int sysex_message_count; /* how many bytes in sysex_message so far */ - - int32_t filters; /* flags that filter incoming message classes */ - int32_t channel_mask; /* filter incoming messages based on channel */ - PmTimestamp last_msg_time; /* timestamp of last message */ - PmTimestamp sync_time; /* time of last synchronization */ - PmTimestamp now; /* set by PmWrite to current time */ - int first_message; /* initially true, used to run first synchronization */ - pm_fns_type dictionary; /* implementation functions */ - void *descriptor; /* system-dependent state */ - /* the following are used to expedite sysex data */ - /* on windows, in debug mode, based on some profiling, these optimizations - * cut the time to process sysex bytes from about 7.5 to 0.26 usec/byte, - * but this does not count time in the driver, so I don't know if it is - * important - */ - unsigned char *fill_base; /* addr of ptr to sysex data */ - uint32_t *fill_offset_ptr; /* offset of next sysex byte */ - int32_t fill_length; /* how many sysex bytes to write */ -} PmInternal; - - -/* defined by system specific implementation, e.g. pmwinmm, used by PortMidi */ -void pm_init(void); -void pm_term(void); - -/* defined by portMidi, used by pmwinmm */ -PmError none_write_short(PmInternal *midi, PmEvent *buffer); -PmError none_write_byte(PmInternal *midi, unsigned char byte, - PmTimestamp timestamp); -PmTimestamp none_synchronize(PmInternal *midi); - -PmError pm_fail_fn(PmInternal *midi); -PmError pm_fail_timestamp_fn(PmInternal *midi, PmTimestamp timestamp); -PmError pm_success_fn(PmInternal *midi); -PmError pm_add_device(char *interf, char *name, int input, void *descriptor, - pm_fns_type dictionary); -uint32_t pm_read_bytes(PmInternal *midi, const unsigned char *data, int len, - PmTimestamp timestamp); -void pm_read_short(PmInternal *midi, PmEvent *event); - -#define none_write_flush pm_fail_timestamp_fn -#define none_sysex pm_fail_timestamp_fn -#define none_poll pm_fail_fn -#define success_poll pm_success_fn - -#define MIDI_REALTIME_MASK 0xf8 -#define is_real_time(msg) \ - ((Pm_MessageStatus(msg) & MIDI_REALTIME_MASK) == MIDI_REALTIME_MASK) - -int pm_find_default_device(char *pattern, int is_input); - -#ifdef __cplusplus -} -#endif - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_common/pmutil.c b/libs/backends/wavesaudio/portmidi/src/pm_common/pmutil.c deleted file mode 100644 index 859aa9c622..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_common/pmutil.c +++ /dev/null @@ -1,284 +0,0 @@ -/* pmutil.c -- some helpful utilities for building midi - applications that use PortMidi - */ -#include -#include -#include -#include "portmidi.h" -#include "pmutil.h" -#include "pminternal.h" - -#ifdef WIN32 -#define bzero(addr, siz) memset(addr, 0, siz) -#endif - -// #define QUEUE_DEBUG 1 -#ifdef QUEUE_DEBUG -#include "stdio.h" -#endif - -typedef struct { - long head; - long tail; - long len; - long overflow; - int32_t msg_size; /* number of int32_t in a message including extra word */ - int32_t peek_overflow; - int32_t *buffer; - int32_t *peek; - int32_t peek_flag; -} PmQueueRep; - - -PMEXPORT PmQueue *Pm_QueueCreate(long num_msgs, int32_t bytes_per_msg) -{ - int32_t int32s_per_msg = - (int32_t) (((bytes_per_msg + sizeof(int32_t) - 1) & - ~(sizeof(int32_t) - 1)) / sizeof(int32_t)); - PmQueueRep *queue = (PmQueueRep *) pm_alloc(sizeof(PmQueueRep)); - if (!queue) /* memory allocation failed */ - return NULL; - - /* need extra word per message for non-zero encoding */ - queue->len = num_msgs * (int32s_per_msg + 1); - queue->buffer = (int32_t *) pm_alloc(queue->len * sizeof(int32_t)); - bzero(queue->buffer, queue->len * sizeof(int32_t)); - if (!queue->buffer) { - pm_free(queue); - return NULL; - } else { /* allocate the "peek" buffer */ - queue->peek = (int32_t *) pm_alloc(int32s_per_msg * sizeof(int32_t)); - if (!queue->peek) { - /* free everything allocated so far and return */ - pm_free(queue->buffer); - pm_free(queue); - return NULL; - } - } - bzero(queue->buffer, queue->len * sizeof(int32_t)); - queue->head = 0; - queue->tail = 0; - /* msg_size is in words */ - queue->msg_size = int32s_per_msg + 1; /* note extra word is counted */ - queue->overflow = FALSE; - queue->peek_overflow = FALSE; - queue->peek_flag = FALSE; - return queue; -} - - -PMEXPORT PmError Pm_QueueDestroy(PmQueue *q) -{ - PmQueueRep *queue = (PmQueueRep *) q; - - /* arg checking */ - if (!queue || !queue->buffer || !queue->peek) - return pmBadPtr; - - pm_free(queue->peek); - pm_free(queue->buffer); - pm_free(queue); - return pmNoError; -} - - -PMEXPORT PmError Pm_Dequeue(PmQueue *q, void *msg) -{ - long head; - PmQueueRep *queue = (PmQueueRep *) q; - int i; - int32_t *msg_as_int32 = (int32_t *) msg; - - /* arg checking */ - if (!queue) - return pmBadPtr; - /* a previous peek operation encountered an overflow, but the overflow - * has not yet been reported to client, so do it now. No message is - * returned, but on the next call, we will return the peek buffer. - */ - if (queue->peek_overflow) { - queue->peek_overflow = FALSE; - return pmBufferOverflow; - } - if (queue->peek_flag) { - memcpy(msg, queue->peek, (queue->msg_size - 1) * sizeof(int32_t)); - queue->peek_flag = FALSE; - return pmGotData; - } - - head = queue->head; - /* if writer overflows, it writes queue->overflow = tail+1 so that - * when the reader gets to that position in the buffer, it can - * return the overflow condition to the reader. The problem is that - * at overflow, things have wrapped around, so tail == head, and the - * reader will detect overflow immediately instead of waiting until - * it reads everything in the buffer, wrapping around again to the - * point where tail == head. So the condition also checks that - * queue->buffer[head] is zero -- if so, then the buffer is now - * empty, and we're at the point in the msg stream where overflow - * occurred. It's time to signal overflow to the reader. If - * queue->buffer[head] is non-zero, there's a message there and we - * should read all the way around the buffer before signalling overflow. - * There is a write-order dependency here, but to fail, the overflow - * field would have to be written while an entire buffer full of - * writes are still pending. I'm assuming out-of-order writes are - * possible, but not that many. - */ - if (queue->overflow == head + 1 && !queue->buffer[head]) { - queue->overflow = 0; /* non-overflow condition */ - return pmBufferOverflow; - } - - /* test to see if there is data in the queue -- test from back - * to front so if writer is simultaneously writing, we don't - * waste time discovering the write is not finished - */ - for (i = queue->msg_size - 1; i >= 0; i--) { - if (!queue->buffer[head + i]) { - return pmNoData; - } - } - memcpy(msg, (char *) &queue->buffer[head + 1], - sizeof(int32_t) * (queue->msg_size - 1)); - /* fix up zeros */ - i = queue->buffer[head]; - while (i < queue->msg_size) { - int32_t j; - i--; /* msg does not have extra word so shift down */ - j = msg_as_int32[i]; - msg_as_int32[i] = 0; - i = j; - } - /* signal that data has been removed by zeroing: */ - bzero((char *) &queue->buffer[head], sizeof(int32_t) * queue->msg_size); - - /* update head */ - head += queue->msg_size; - if (head == queue->len) head = 0; - queue->head = head; - return pmGotData; /* success */ -} - - - -PMEXPORT PmError Pm_SetOverflow(PmQueue *q) -{ - PmQueueRep *queue = (PmQueueRep *) q; - long tail; - /* arg checking */ - if (!queue) - return pmBadPtr; - /* no more enqueue until receiver acknowledges overflow */ - if (queue->overflow) return pmBufferOverflow; - tail = queue->tail; - queue->overflow = tail + 1; - return pmBufferOverflow; -} - - -PMEXPORT PmError Pm_Enqueue(PmQueue *q, void *msg) -{ - PmQueueRep *queue = (PmQueueRep *) q; - long tail; - int i; - int32_t *src = (int32_t *) msg; - int32_t *ptr; - int32_t *dest; - int rslt; - if (!queue) - return pmBadPtr; - /* no more enqueue until receiver acknowledges overflow */ - if (queue->overflow) return pmBufferOverflow; - rslt = Pm_QueueFull(q); - /* already checked above: if (rslt == pmBadPtr) return rslt; */ - tail = queue->tail; - if (rslt) { - queue->overflow = tail + 1; - return pmBufferOverflow; - } - - /* queue is has room for message, and overflow flag is cleared */ - ptr = &queue->buffer[tail]; - dest = ptr + 1; - for (i = 1; i < queue->msg_size; i++) { - int32_t j = src[i - 1]; - if (!j) { - *ptr = i; - ptr = dest; - } else { - *dest = j; - } - dest++; - } - *ptr = i; - tail += queue->msg_size; - if (tail == queue->len) tail = 0; - queue->tail = tail; - return pmNoError; -} - - -PMEXPORT int Pm_QueueEmpty(PmQueue *q) -{ - PmQueueRep *queue = (PmQueueRep *) q; - return (!queue) || /* null pointer -> return "empty" */ - (queue->buffer[queue->head] == 0 && !queue->peek_flag); -} - - -PMEXPORT int Pm_QueueFull(PmQueue *q) -{ - long tail; - int i; - PmQueueRep *queue = (PmQueueRep *) q; - /* arg checking */ - if (!queue) - return pmBadPtr; - tail = queue->tail; - /* test to see if there is space in the queue */ - for (i = 0; i < queue->msg_size; i++) { - if (queue->buffer[tail + i]) { - return TRUE; - } - } - return FALSE; -} - - -PMEXPORT void *Pm_QueuePeek(PmQueue *q) -{ - PmError rslt; - int32_t temp; - PmQueueRep *queue = (PmQueueRep *) q; - /* arg checking */ - if (!queue) - return NULL; - - if (queue->peek_flag) { - return queue->peek; - } - /* this is ugly: if peek_overflow is set, then Pm_Dequeue() - * returns immediately with pmBufferOverflow, but here, we - * want Pm_Dequeue() to really check for data. If data is - * there, we can return it - */ - temp = queue->peek_overflow; - queue->peek_overflow = FALSE; - rslt = Pm_Dequeue(q, queue->peek); - queue->peek_overflow = temp; - - if (rslt == 1) { - queue->peek_flag = TRUE; - return queue->peek; - } else if (rslt == pmBufferOverflow) { - /* when overflow is indicated, the queue is empty and the - * first message that was dropped by Enqueue (signalling - * pmBufferOverflow to its caller) would have been the next - * message in the queue. Pm_QueuePeek will return NULL, but - * remember that an overflow occurred. (see Pm_Dequeue) - */ - queue->peek_overflow = TRUE; - } - return NULL; -} - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_common/portmidi.c b/libs/backends/wavesaudio/portmidi/src/pm_common/portmidi.c deleted file mode 100644 index 0b75222a33..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_common/portmidi.c +++ /dev/null @@ -1,1137 +0,0 @@ -#ifdef _MSC_VER - #pragma warning(disable: 4244) // stop warnings about downsize typecasts - #pragma warning(disable: 4018) // stop warnings about signed/unsigned -#endif - -#include "stdlib.h" -#include "string.h" -#include "portmidi.h" -#include "porttime.h" -#include "pmutil.h" -#include "pminternal.h" -#include - -#define MIDI_CLOCK 0xf8 -#define MIDI_ACTIVE 0xfe -#define MIDI_STATUS_MASK 0x80 -#define MIDI_SYSEX 0xf0 -#define MIDI_EOX 0xf7 -#define MIDI_START 0xFA -#define MIDI_STOP 0xFC -#define MIDI_CONTINUE 0xFB -#define MIDI_F9 0xF9 -#define MIDI_FD 0xFD -#define MIDI_RESET 0xFF -#define MIDI_NOTE_ON 0x90 -#define MIDI_NOTE_OFF 0x80 -#define MIDI_CHANNEL_AT 0xD0 -#define MIDI_POLY_AT 0xA0 -#define MIDI_PROGRAM 0xC0 -#define MIDI_CONTROL 0xB0 -#define MIDI_PITCHBEND 0xE0 -#define MIDI_MTC 0xF1 -#define MIDI_SONGPOS 0xF2 -#define MIDI_SONGSEL 0xF3 -#define MIDI_TUNE 0xF6 - -#define is_empty(midi) ((midi)->tail == (midi)->head) - -/* this is not static so that pm_init can set it directly if - * (see pmmac.c:pm_init()) - */ -int pm_initialized = FALSE; - -int pm_hosterror; -char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN]; - -#ifdef PM_CHECK_ERRORS - -#include - -#define STRING_MAX 80 - -static void prompt_and_exit(void) -{ - char line[STRING_MAX]; - printf("type ENTER..."); - fgets(line, STRING_MAX, stdin); - /* this will clean up open ports: */ - exit(-1); -} - - -static PmError pm_errmsg(PmError err) -{ - if (err == pmHostError) { - /* it seems pointless to allocate memory and copy the string, - * so I will do the work of Pm_GetHostErrorText directly - */ - printf("PortMidi found host error...\n %s\n", pm_hosterror_text); - pm_hosterror = FALSE; - pm_hosterror_text[0] = 0; /* clear the message */ - prompt_and_exit(); - } else if (err < 0) { - printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err)); - prompt_and_exit(); - } - return err; -} -#else -#define pm_errmsg(err) err -#endif - -/* -==================================================================== -system implementation of portmidi interface -==================================================================== -*/ - -int pm_descriptor_max = 0; -int pm_descriptor_index = 0; -descriptor_type descriptors = NULL; - -/* pm_add_device -- describe interface/device pair to library - * - * This is called at intialization time, once for each - * interface (e.g. DirectSound) and device (e.g. SoundBlaster 1) - * The strings are retained but NOT COPIED, so do not destroy them! - * - * returns pmInvalidDeviceId if device memory is exceeded - * otherwise returns pmNoError - */ -PmError pm_add_device(char *interf, char *name, int input, - void *descriptor, pm_fns_type dictionary) { - if (pm_descriptor_index >= pm_descriptor_max) { - // expand descriptors - descriptor_type new_descriptors = (descriptor_type) - pm_alloc(sizeof(descriptor_node) * (pm_descriptor_max + 32)); - if (!new_descriptors) return pmInsufficientMemory; - if (descriptors) { - memcpy(new_descriptors, descriptors, - sizeof(descriptor_node) * pm_descriptor_max); - free(descriptors); - } - pm_descriptor_max += 32; - descriptors = new_descriptors; - } - descriptors[pm_descriptor_index].pub.interf = interf; - descriptors[pm_descriptor_index].pub.name = name; - descriptors[pm_descriptor_index].pub.input = input; - descriptors[pm_descriptor_index].pub.output = !input; - - /* default state: nothing to close (for automatic device closing) */ - descriptors[pm_descriptor_index].pub.opened = FALSE; - - /* ID number passed to win32 multimedia API open */ - descriptors[pm_descriptor_index].descriptor = descriptor; - - /* points to PmInternal, allows automatic device closing */ - descriptors[pm_descriptor_index].internalDescriptor = NULL; - - descriptors[pm_descriptor_index].dictionary = dictionary; - - pm_descriptor_index++; - - return pmNoError; -} - - -/* utility to look up device, given a pattern, - note: pattern is modified - */ -int pm_find_default_device(char *pattern, int is_input) -{ - int id = pmNoDevice; - int i; - /* first parse pattern into name, interf parts */ - char *interf_pref = ""; /* initially assume it is not there */ - char *name_pref = strstr(pattern, ", "); - - if (name_pref) { /* found separator, adjust the pointer */ - interf_pref = pattern; - name_pref[0] = 0; - name_pref += 2; - } else { - name_pref = pattern; /* whole string is the name pattern */ - } - for (i = 0; i < pm_descriptor_index; i++) { - const PmDeviceInfo *info = Pm_GetDeviceInfo(i); - if (info->input == is_input && - strstr(info->name, name_pref) && - strstr(info->interf, interf_pref)) { - id = i; - break; - } - } - return id; -} - - -/* -==================================================================== -portmidi implementation -==================================================================== -*/ - -PMEXPORT int Pm_CountDevices( void ) { - Pm_Initialize(); - /* no error checking -- Pm_Initialize() does not fail */ - return pm_descriptor_index; -} - - -PMEXPORT const PmDeviceInfo* Pm_GetDeviceInfo( PmDeviceID id ) { - Pm_Initialize(); /* no error check needed */ - if (id >= 0 && id < pm_descriptor_index) { - return &descriptors[id].pub; - } - return NULL; -} - -/* pm_success_fn -- "noop" function pointer */ -PmError pm_success_fn(PmInternal *midi) { - return pmNoError; -} - -/* none_write -- returns an error if called */ -PmError none_write_short(PmInternal *midi, PmEvent *buffer) { - return pmBadPtr; -} - -/* pm_fail_timestamp_fn -- placeholder for begin_sysex and flush */ -PmError pm_fail_timestamp_fn(PmInternal *midi, PmTimestamp timestamp) { - return pmBadPtr; -} - -PmError none_write_byte(PmInternal *midi, unsigned char byte, - PmTimestamp timestamp) { - return pmBadPtr; -} - -/* pm_fail_fn -- generic function, returns error if called */ -PmError pm_fail_fn(PmInternal *midi) { - return pmBadPtr; -} - -static PmError none_open(PmInternal *midi, void *driverInfo) { - return pmBadPtr; -} -static void none_get_host_error(PmInternal * midi, char * msg, unsigned int len) { - *msg = 0; // empty string -} -static unsigned int none_has_host_error(PmInternal * midi) { - return FALSE; -} -PmTimestamp none_synchronize(PmInternal *midi) { - return 0; -} - -#define none_abort pm_fail_fn -#define none_close pm_fail_fn - -pm_fns_node pm_none_dictionary = { - none_write_short, - none_sysex, - none_sysex, - none_write_byte, - none_write_short, - none_write_flush, - none_synchronize, - none_open, - none_abort, - none_close, - none_poll, - none_has_host_error, - none_get_host_error -}; - - -PMEXPORT const char *Pm_GetErrorText( PmError errnum ) { - const char *msg; - - switch(errnum) - { - case pmNoError: - msg = ""; - break; - case pmHostError: - msg = "PortMidi: `Host error'"; - break; - case pmInvalidDeviceId: - msg = "PortMidi: `Invalid device ID'"; - break; - case pmInsufficientMemory: - msg = "PortMidi: `Insufficient memory'"; - break; - case pmBufferTooSmall: - msg = "PortMidi: `Buffer too small'"; - break; - case pmBadPtr: - msg = "PortMidi: `Bad pointer'"; - break; - case pmInternalError: - msg = "PortMidi: `Internal PortMidi Error'"; - break; - case pmBufferOverflow: - msg = "PortMidi: `Buffer overflow'"; - break; - case pmBadData: - msg = "PortMidi: `Invalid MIDI message Data'"; - break; - case pmBufferMaxSize: - msg = "PortMidi: `Buffer cannot be made larger'"; - break; - default: - msg = "PortMidi: `Illegal error number'"; - break; - } - return msg; -} - - -/* This can be called whenever you get a pmHostError return value. - * The error will always be in the global pm_hosterror_text. - */ -PMEXPORT void Pm_GetHostErrorText(char * msg, unsigned int len) { - assert(msg); - assert(len > 0); - if (pm_hosterror) { - strncpy(msg, (char *) pm_hosterror_text, len); - pm_hosterror = FALSE; - pm_hosterror_text[0] = 0; /* clear the message; not necessary, but it - might help with debugging */ - msg[len - 1] = 0; /* make sure string is terminated */ - } else { - msg[0] = 0; /* no string to return */ - } -} - - -PMEXPORT int Pm_HasHostError(PortMidiStream * stream) { - if (pm_hosterror) return TRUE; - if (stream) { - PmInternal * midi = (PmInternal *) stream; - pm_hosterror = (*midi->dictionary->has_host_error)(midi); - if (pm_hosterror) { - midi->dictionary->host_error(midi, pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - /* now error message is global */ - return TRUE; - } - } - return FALSE; -} - - -PMEXPORT PmError Pm_Initialize( void ) { - if (!pm_initialized) { - pm_hosterror = FALSE; - pm_hosterror_text[0] = 0; /* the null string */ - pm_init(); - pm_initialized = TRUE; - } - return pmNoError; -} - - -PMEXPORT PmError Pm_Terminate( void ) { - if (pm_initialized) { - pm_term(); - // if there are no devices, descriptors might still be NULL - if (descriptors != NULL) { - free(descriptors); - descriptors = NULL; - } - pm_descriptor_index = 0; - pm_descriptor_max = 0; - pm_initialized = FALSE; - } - return pmNoError; -} - - -/* Pm_Read -- read up to length messages from source into buffer */ -/* - * returns number of messages actually read, or error code - */ -PMEXPORT int Pm_Read(PortMidiStream *stream, PmEvent *buffer, int32_t length) { - PmInternal *midi = (PmInternal *) stream; - int n = 0; - PmError err = pmNoError; - pm_hosterror = FALSE; - /* arg checking */ - if(midi == NULL) - err = pmBadPtr; - else if(!descriptors[midi->device_id].pub.opened) - err = pmBadPtr; - else if(!descriptors[midi->device_id].pub.input) - err = pmBadPtr; - /* First poll for data in the buffer... - * This either simply checks for data, or attempts first to fill the buffer - * with data from the MIDI hardware; this depends on the implementation. - * We could call Pm_Poll here, but that would redo a lot of redundant - * parameter checking, so I copied some code from Pm_Poll to here: */ - else err = (*(midi->dictionary->poll))(midi); - - if (err != pmNoError) { - if (err == pmHostError) { - midi->dictionary->host_error(midi, pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - pm_hosterror = TRUE; - } - return pm_errmsg(err); - } - - while (n < length) { - PmError err = Pm_Dequeue(midi->queue, buffer++); - if (err == pmBufferOverflow) { - /* ignore the data we have retreived so far */ - return pm_errmsg(pmBufferOverflow); - } else if (err == 0) { /* empty queue */ - break; - } - n++; - } - return n; -} - -PMEXPORT PmError Pm_Poll( PortMidiStream *stream ) -{ - PmInternal *midi = (PmInternal *) stream; - PmError err; - - pm_hosterror = FALSE; - /* arg checking */ - if(midi == NULL) - err = pmBadPtr; - else if (!descriptors[midi->device_id].pub.opened) - err = pmBadPtr; - else if (!descriptors[midi->device_id].pub.input) - err = pmBadPtr; - else - err = (*(midi->dictionary->poll))(midi); - - if (err != pmNoError) { - if (err == pmHostError) { - midi->dictionary->host_error(midi, pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - pm_hosterror = TRUE; - } - return pm_errmsg(err); - } - - return (PmError) !Pm_QueueEmpty(midi->queue); -} - - -/* this is called from Pm_Write and Pm_WriteSysEx to issue a - * call to the system-dependent end_sysex function and handle - * the error return - */ -static PmError pm_end_sysex(PmInternal *midi) -{ - PmError err = (*midi->dictionary->end_sysex)(midi, 0); - midi->sysex_in_progress = FALSE; - if (err == pmHostError) { - midi->dictionary->host_error(midi, pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - pm_hosterror = TRUE; - } - return err; -} - - -/* to facilitate correct error-handling, Pm_Write, Pm_WriteShort, and - Pm_WriteSysEx all operate a state machine that "outputs" calls to - write_short, begin_sysex, write_byte, end_sysex, and write_realtime */ - -PMEXPORT PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, int32_t length) -{ - PmInternal *midi = (PmInternal *) stream; - PmError err = pmNoError; - int i; - int bits; - - pm_hosterror = FALSE; - /* arg checking */ - if(midi == NULL) - err = pmBadPtr; - else if(!descriptors[midi->device_id].pub.opened) - err = pmBadPtr; - else if(!descriptors[midi->device_id].pub.output) - err = pmBadPtr; - else - err = pmNoError; - - if (err != pmNoError) goto pm_write_error; - - if (midi->latency == 0) { - midi->now = 0; - } else { - midi->now = (*(midi->time_proc))(midi->time_info); - if (midi->first_message || midi->sync_time + 100 /*ms*/ < midi->now) { - /* time to resync */ - midi->now = (*midi->dictionary->synchronize)(midi); - midi->first_message = FALSE; - } - } - /* error recovery: when a sysex is detected, we call - * dictionary->begin_sysex() followed by calls to - * dictionary->write_byte() and dictionary->write_realtime() - * until an end-of-sysex is detected, when we call - * dictionary->end_sysex(). After an error occurs, - * Pm_Write() continues to call functions. For example, - * it will continue to call write_byte() even after - * an error sending a sysex message, and end_sysex() will be - * called when an EOX or non-real-time status is found. - * When errors are detected, Pm_Write() returns immediately, - * so it is possible that this will drop data and leave - * sysex messages in a partially transmitted state. - */ - for (i = 0; i < length; i++) { - uint32_t msg = buffer[i].message; - bits = 0; - /* is this a sysex message? */ - if (Pm_MessageStatus(msg) == MIDI_SYSEX) { - if (midi->sysex_in_progress) { - /* error: previous sysex was not terminated by EOX */ - midi->sysex_in_progress = FALSE; - err = pmBadData; - goto pm_write_error; - } - midi->sysex_in_progress = TRUE; - if ((err = (*midi->dictionary->begin_sysex)(midi, - buffer[i].timestamp)) != pmNoError) - goto pm_write_error; - if ((err = (*midi->dictionary->write_byte)(midi, MIDI_SYSEX, - buffer[i].timestamp)) != pmNoError) - goto pm_write_error; - bits = 8; - /* fall through to continue sysex processing */ - } else if ((msg & MIDI_STATUS_MASK) && - (Pm_MessageStatus(msg) != MIDI_EOX)) { - /* a non-sysex message */ - if (midi->sysex_in_progress) { - /* this should be a realtime message */ - if (is_real_time(msg)) { - if ((err = (*midi->dictionary->write_realtime)(midi, - &(buffer[i]))) != pmNoError) - goto pm_write_error; - } else { - midi->sysex_in_progress = FALSE; - err = pmBadData; - /* ignore any error from this, because we already have one */ - /* pass 0 as timestamp -- it's ignored */ - (*midi->dictionary->end_sysex)(midi, 0); - goto pm_write_error; - } - } else { /* regular short midi message */ - if ((err = (*midi->dictionary->write_short)(midi, - &(buffer[i]))) != pmNoError) - goto pm_write_error; - continue; - } - } - if (midi->sysex_in_progress) { /* send sysex bytes until EOX */ - /* see if we can accelerate data transfer */ - if (bits == 0 && midi->fill_base && /* 4 bytes to copy */ - (*midi->fill_offset_ptr) + 4 <= midi->fill_length && - (msg & 0x80808080) == 0) { /* all data */ - /* copy 4 bytes from msg to fill_base + fill_offset */ - unsigned char *ptr = midi->fill_base + - *(midi->fill_offset_ptr); - ptr[0] = msg; ptr[1] = msg >> 8; - ptr[2] = msg >> 16; ptr[3] = msg >> 24; - (*midi->fill_offset_ptr) += 4; - continue; - } - /* no acceleration, so do byte-by-byte copying */ - while (bits < 32) { - unsigned char midi_byte = (unsigned char) (msg >> bits); - if ((err = (*midi->dictionary->write_byte)(midi, midi_byte, - buffer[i].timestamp)) != pmNoError) - goto pm_write_error; - if (midi_byte == MIDI_EOX) { - err = pm_end_sysex(midi); - if (err != pmNoError) goto error_exit; - break; /* from while loop */ - } - bits += 8; - } - } else { - /* not in sysex mode, but message did not start with status */ - err = pmBadData; - goto pm_write_error; - } - } - /* after all messages are processed, send the data */ - if (!midi->sysex_in_progress) - err = (*midi->dictionary->write_flush)(midi, 0); -pm_write_error: - if (err == pmHostError) { - midi->dictionary->host_error(midi, pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - pm_hosterror = TRUE; - } -error_exit: - return pm_errmsg(err); -} - - -PMEXPORT PmError Pm_WriteShort(PortMidiStream *stream, PmTimestamp when, PmMessage msg) -{ - PmEvent event; - - event.timestamp = when; - event.message = msg; - return Pm_Write(stream, &event, 1); -} - - -PMEXPORT PmError Pm_WriteSysEx(PortMidiStream *stream, PmTimestamp when, - unsigned char *msg) -{ - /* allocate buffer space for PM_DEFAULT_SYSEX_BUFFER_SIZE bytes */ - /* each PmEvent holds sizeof(PmMessage) bytes of sysex data */ - #define BUFLEN ((int) (PM_DEFAULT_SYSEX_BUFFER_SIZE / sizeof(PmMessage))) - PmEvent buffer[BUFLEN]; - int buffer_size = 1; /* first time, send 1. After that, it's BUFLEN */ - PmInternal *midi = (PmInternal *) stream; - /* the next byte in the buffer is represented by an index, bufx, and - a shift in bits */ - int shift = 0; - int bufx = 0; - buffer[0].message = 0; - buffer[0].timestamp = when; - - while (1) { - /* insert next byte into buffer */ - buffer[bufx].message |= ((*msg) << shift); - shift += 8; - if (*msg++ == MIDI_EOX) break; - if (shift == 32) { - shift = 0; - bufx++; - if (bufx == buffer_size) { - PmError err = Pm_Write(stream, buffer, buffer_size); - /* note: Pm_Write has already called errmsg() */ - if (err) return err; - /* prepare to fill another buffer */ - bufx = 0; - buffer_size = BUFLEN; - /* optimization: maybe we can just copy bytes */ - if (midi->fill_base) { - PmError err; - while (*(midi->fill_offset_ptr) < midi->fill_length) { - midi->fill_base[(*midi->fill_offset_ptr)++] = *msg; - if (*msg++ == MIDI_EOX) { - err = pm_end_sysex(midi); - if (err != pmNoError) return pm_errmsg(err); - goto end_of_sysex; - } - } - /* I thought that I could do a pm_Write here and - * change this if to a loop, avoiding calls in Pm_Write - * to the slower write_byte, but since - * sysex_in_progress is true, this will not flush - * the buffer, and we'll infinite loop: */ - /* err = Pm_Write(stream, buffer, 0); - if (err) return err; */ - /* instead, the way this works is that Pm_Write calls - * write_byte on 4 bytes. The first, since the buffer - * is full, will flush the buffer and allocate a new - * one. This primes the buffer so - * that we can return to the loop above and fill it - * efficiently without a lot of function calls. - */ - buffer_size = 1; /* get another message started */ - } - } - buffer[bufx].message = 0; - buffer[bufx].timestamp = when; - } - /* keep inserting bytes until you find MIDI_EOX */ - } -end_of_sysex: - /* we're finished sending full buffers, but there may - * be a partial one left. - */ - if (shift != 0) bufx++; /* add partial message to buffer len */ - if (bufx) { /* bufx is number of PmEvents to send from buffer */ - PmError err = Pm_Write(stream, buffer, bufx); - if (err) return err; - } - return pmNoError; -} - - - -PMEXPORT PmError Pm_OpenInput(PortMidiStream** stream, - PmDeviceID inputDevice, - void *inputDriverInfo, - int32_t bufferSize, - PmTimeProcPtr time_proc, - void *time_info) -{ - PmInternal *midi; - PmError err = pmNoError; - pm_hosterror = FALSE; - *stream = NULL; - - /* arg checking */ - if (inputDevice < 0 || inputDevice >= pm_descriptor_index) - err = pmInvalidDeviceId; - else if (!descriptors[inputDevice].pub.input) - err = pmInvalidDeviceId; - else if(descriptors[inputDevice].pub.opened) - err = pmInvalidDeviceId; - - if (err != pmNoError) - goto error_return; - - /* create portMidi internal data */ - midi = (PmInternal *) pm_alloc(sizeof(PmInternal)); - *stream = midi; - if (!midi) { - err = pmInsufficientMemory; - goto error_return; - } - midi->device_id = inputDevice; - midi->write_flag = FALSE; - midi->time_proc = time_proc; - midi->time_info = time_info; - /* windows adds timestamps in the driver and these are more accurate than - using a time_proc, so do not automatically provide a time proc. Non-win - implementations may want to provide a default time_proc in their - system-specific midi_out_open() method. - */ - if (bufferSize <= 0) bufferSize = 256; /* default buffer size */ - midi->queue = Pm_QueueCreate(bufferSize, (int32_t) sizeof(PmEvent)); - if (!midi->queue) { - /* free portMidi data */ - *stream = NULL; - pm_free(midi); - err = pmInsufficientMemory; - goto error_return; - } - midi->buffer_len = bufferSize; /* portMidi input storage */ - midi->latency = 0; /* not used */ - midi->sysex_in_progress = FALSE; - midi->sysex_message = 0; - midi->sysex_message_count = 0; - midi->filters = PM_FILT_ACTIVE; - midi->channel_mask = 0xFFFF; - midi->sync_time = 0; - midi->first_message = TRUE; - midi->dictionary = descriptors[inputDevice].dictionary; - midi->fill_base = NULL; - midi->fill_offset_ptr = NULL; - midi->fill_length = 0; - descriptors[inputDevice].internalDescriptor = midi; - /* open system dependent input device */ - err = (*midi->dictionary->open)(midi, inputDriverInfo); - if (err) { - *stream = NULL; - descriptors[inputDevice].internalDescriptor = NULL; - /* free portMidi data */ - Pm_QueueDestroy(midi->queue); - pm_free(midi); - } else { - /* portMidi input open successful */ - descriptors[inputDevice].pub.opened = TRUE; - } -error_return: - /* note: if there is a pmHostError, it is the responsibility - * of the system-dependent code (*midi->dictionary->open)() - * to set pm_hosterror and pm_hosterror_text - */ - return pm_errmsg(err); -} - - -PMEXPORT PmError Pm_OpenOutput(PortMidiStream** stream, - PmDeviceID outputDevice, - void *outputDriverInfo, - int32_t bufferSize, - PmTimeProcPtr time_proc, - void *time_info, - int32_t latency ) -{ - PmInternal *midi; - PmError err = pmNoError; - pm_hosterror = FALSE; - *stream = NULL; - - /* arg checking */ - if (outputDevice < 0 || outputDevice >= pm_descriptor_index) - err = pmInvalidDeviceId; - else if (!descriptors[outputDevice].pub.output) - err = pmInvalidDeviceId; - else if (descriptors[outputDevice].pub.opened) - err = pmInvalidDeviceId; - if (err != pmNoError) - goto error_return; - - /* create portMidi internal data */ - midi = (PmInternal *) pm_alloc(sizeof(PmInternal)); - *stream = midi; - if (!midi) { - err = pmInsufficientMemory; - goto error_return; - } - midi->device_id = outputDevice; - midi->write_flag = TRUE; - midi->time_proc = time_proc; - /* if latency > 0, we need a time reference. If none is provided, - use PortTime library */ - if (time_proc == NULL && latency != 0) { - if (!Pt_Started()) - Pt_Start(1, 0, 0); - /* time_get does not take a parameter, so coerce */ - midi->time_proc = (PmTimeProcPtr) Pt_Time; - } - midi->time_info = time_info; - midi->buffer_len = bufferSize; - midi->queue = NULL; /* unused by output */ - /* if latency zero, output immediate (timestamps ignored) */ - /* if latency < 0, use 0 but don't return an error */ - if (latency < 0) latency = 0; - midi->latency = latency; - midi->sysex_in_progress = FALSE; - midi->sysex_message = 0; /* unused by output */ - midi->sysex_message_count = 0; /* unused by output */ - midi->filters = 0; /* not used for output */ - midi->channel_mask = 0xFFFF; - midi->sync_time = 0; - midi->first_message = TRUE; - midi->dictionary = descriptors[outputDevice].dictionary; - midi->fill_base = NULL; - midi->fill_offset_ptr = NULL; - midi->fill_length = 0; - descriptors[outputDevice].internalDescriptor = midi; - /* open system dependent output device */ - err = (*midi->dictionary->open)(midi, outputDriverInfo); - if (err) { - *stream = NULL; - descriptors[outputDevice].internalDescriptor = NULL; - /* free portMidi data */ - pm_free(midi); - } else { - /* portMidi input open successful */ - descriptors[outputDevice].pub.opened = TRUE; - } -error_return: - /* note: system-dependent code must set pm_hosterror and - * pm_hosterror_text if a pmHostError occurs - */ - return pm_errmsg(err); -} - - -PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask) -{ - PmInternal *midi = (PmInternal *) stream; - PmError err = pmNoError; - - if (midi == NULL) - err = pmBadPtr; - else - midi->channel_mask = mask; - - return pm_errmsg(err); -} - - -PMEXPORT PmError Pm_SetFilter(PortMidiStream *stream, int32_t filters) { - PmInternal *midi = (PmInternal *) stream; - PmError err = pmNoError; - - /* arg checking */ - if (midi == NULL) - err = pmBadPtr; - else if (!descriptors[midi->device_id].pub.opened) - err = pmBadPtr; - else - midi->filters = filters; - return pm_errmsg(err); -} - - -PMEXPORT PmError Pm_Close( PortMidiStream *stream ) { - PmInternal *midi = (PmInternal *) stream; - PmError err = pmNoError; - - pm_hosterror = FALSE; - /* arg checking */ - if (midi == NULL) /* midi must point to something */ - err = pmBadPtr; - /* if it is an open device, the device_id will be valid */ - else if (midi->device_id < 0 || midi->device_id >= pm_descriptor_index) - err = pmBadPtr; - /* and the device should be in the opened state */ - else if (!descriptors[midi->device_id].pub.opened) - err = pmBadPtr; - - if (err != pmNoError) - goto error_return; - - /* close the device */ - err = (*midi->dictionary->close)(midi); - /* even if an error occurred, continue with cleanup */ - descriptors[midi->device_id].internalDescriptor = NULL; - descriptors[midi->device_id].pub.opened = FALSE; - if (midi->queue) Pm_QueueDestroy(midi->queue); - pm_free(midi); -error_return: - /* system dependent code must set pm_hosterror and - * pm_hosterror_text if a pmHostError occurs. - */ - return pm_errmsg(err); -} - -PmError Pm_Synchronize( PortMidiStream* stream ) { - PmInternal *midi = (PmInternal *) stream; - PmError err = pmNoError; - if (midi == NULL) - err = pmBadPtr; - else if (!descriptors[midi->device_id].pub.output) - err = pmBadPtr; - else if (!descriptors[midi->device_id].pub.opened) - err = pmBadPtr; - else - midi->first_message = TRUE; - return err; -} - -PMEXPORT PmError Pm_Abort( PortMidiStream* stream ) { - PmInternal *midi = (PmInternal *) stream; - PmError err; - /* arg checking */ - if (midi == NULL) - err = pmBadPtr; - else if (!descriptors[midi->device_id].pub.output) - err = pmBadPtr; - else if (!descriptors[midi->device_id].pub.opened) - err = pmBadPtr; - else - err = (*midi->dictionary->abort)(midi); - - if (err == pmHostError) { - midi->dictionary->host_error(midi, pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - pm_hosterror = TRUE; - } - return pm_errmsg(err); -} - - - -/* pm_channel_filtered returns non-zero if the channel mask is blocking the current channel */ -#define pm_channel_filtered(status, mask) \ - ((((status) & 0xF0) != 0xF0) && (!(Pm_Channel((status) & 0x0F) & (mask)))) - - -/* The following two functions will checks to see if a MIDI message matches - the filtering criteria. Since the sysex routines only want to filter realtime messages, - we need to have separate routines. - */ - - -/* pm_realtime_filtered returns non-zero if the filter will kill the current message. - Note that only realtime messages are checked here. - */ -#define pm_realtime_filtered(status, filters) \ - ((((status) & 0xF0) == 0xF0) && ((1 << ((status) & 0xF)) & (filters))) - -/* - return ((status == MIDI_ACTIVE) && (filters & PM_FILT_ACTIVE)) - || ((status == MIDI_CLOCK) && (filters & PM_FILT_CLOCK)) - || ((status == MIDI_START) && (filters & PM_FILT_PLAY)) - || ((status == MIDI_STOP) && (filters & PM_FILT_PLAY)) - || ((status == MIDI_CONTINUE) && (filters & PM_FILT_PLAY)) - || ((status == MIDI_F9) && (filters & PM_FILT_F9)) - || ((status == MIDI_FD) && (filters & PM_FILT_FD)) - || ((status == MIDI_RESET) && (filters & PM_FILT_RESET)) - || ((status == MIDI_MTC) && (filters & PM_FILT_MTC)) - || ((status == MIDI_SONGPOS) && (filters & PM_FILT_SONG_POSITION)) - || ((status == MIDI_SONGSEL) && (filters & PM_FILT_SONG_SELECT)) - || ((status == MIDI_TUNE) && (filters & PM_FILT_TUNE)); -}*/ - - -/* pm_status_filtered returns non-zero if a filter will kill the current message, based on status. - Note that sysex and real time are not checked. It is up to the subsystem (winmm, core midi, alsa) - to filter sysex, as it is handled more easily and efficiently at that level. - Realtime message are filtered in pm_realtime_filtered. - */ -#define pm_status_filtered(status, filters) ((1 << (16 + ((status) >> 4))) & (filters)) - - -/* - return ((status == MIDI_NOTE_ON) && (filters & PM_FILT_NOTE)) - || ((status == MIDI_NOTE_OFF) && (filters & PM_FILT_NOTE)) - || ((status == MIDI_CHANNEL_AT) && (filters & PM_FILT_CHANNEL_AFTERTOUCH)) - || ((status == MIDI_POLY_AT) && (filters & PM_FILT_POLY_AFTERTOUCH)) - || ((status == MIDI_PROGRAM) && (filters & PM_FILT_PROGRAM)) - || ((status == MIDI_CONTROL) && (filters & PM_FILT_CONTROL)) - || ((status == MIDI_PITCHBEND) && (filters & PM_FILT_PITCHBEND)); - -} -*/ - -static void pm_flush_sysex(PmInternal *midi, PmTimestamp timestamp) -{ - PmEvent event; - - /* there may be nothing in the buffer */ - if (midi->sysex_message_count == 0) return; /* nothing to flush */ - - event.message = midi->sysex_message; - event.timestamp = timestamp; - /* copied from pm_read_short, avoids filtering */ - if (Pm_Enqueue(midi->queue, &event) == pmBufferOverflow) { - midi->sysex_in_progress = FALSE; - } - midi->sysex_message_count = 0; - midi->sysex_message = 0; -} - - -/* pm_read_short and pm_read_bytes - are the interface between system-dependent MIDI input handlers - and the system-independent PortMIDI code. - The input handler MUST obey these rules: - 1) all short input messages must be sent to pm_read_short, which - enqueues them to a FIFO for the application. - 2) each buffer of sysex bytes should be reported by calling pm_read_bytes - (which sets midi->sysex_in_progress). After the eox byte, - pm_read_bytes will clear sysex_in_progress - */ - -/* pm_read_short is the place where all input messages arrive from - system-dependent code such as pmwinmm.c. Here, the messages - are entered into the PortMidi input buffer. - */ -void pm_read_short(PmInternal *midi, PmEvent *event) -{ - int status; - /* arg checking */ - assert(midi != NULL); - /* midi filtering is applied here */ - status = Pm_MessageStatus(event->message); - if (!pm_status_filtered(status, midi->filters) - && (!is_real_time(status) || - !pm_realtime_filtered(status, midi->filters)) - && !pm_channel_filtered(status, midi->channel_mask)) { - /* if sysex is in progress and we get a status byte, it had - better be a realtime message or the starting SYSEX byte; - otherwise, we exit the sysex_in_progress state - */ - if (midi->sysex_in_progress && (status & MIDI_STATUS_MASK)) { - /* two choices: real-time or not. If it's real-time, then - * this should be delivered as a sysex byte because it is - * embedded in a sysex message - */ - if (is_real_time(status)) { - midi->sysex_message |= - (status << (8 * midi->sysex_message_count++)); - if (midi->sysex_message_count == 4) { - pm_flush_sysex(midi, event->timestamp); - } - } else { /* otherwise, it's not real-time. This interrupts - * a sysex message in progress */ - midi->sysex_in_progress = FALSE; - } - } else if (Pm_Enqueue(midi->queue, event) == pmBufferOverflow) { - midi->sysex_in_progress = FALSE; - } - } -} - -/* pm_read_bytes -- read one (partial) sysex msg from MIDI data */ -/* - * returns how many bytes processed - */ -unsigned int pm_read_bytes(PmInternal *midi, const unsigned char *data, - int len, PmTimestamp timestamp) -{ - int i = 0; /* index into data, must not be unsigned (!) */ - PmEvent event; - event.timestamp = timestamp; - assert(midi); - /* note that since buffers may not have multiples of 4 bytes, - * pm_read_bytes may be called in the middle of an outgoing - * 4-byte PortMidi message. sysex_in_progress indicates that - * a sysex has been sent but no eox. - */ - if (len == 0) return 0; /* sanity check */ - if (!midi->sysex_in_progress) { - while (i < len) { /* process all data */ - unsigned char byte = data[i++]; - if (byte == MIDI_SYSEX && - !pm_realtime_filtered(byte, midi->filters)) { - midi->sysex_in_progress = TRUE; - i--; /* back up so code below will get SYSEX byte */ - break; /* continue looping below to process msg */ - } else if (byte == MIDI_EOX) { - midi->sysex_in_progress = FALSE; - return i; /* done with one message */ - } else if (byte & MIDI_STATUS_MASK) { - /* We're getting MIDI but no sysex in progress. - * Either the SYSEX status byte was dropped or - * the message was filtered. Drop the data, but - * send any embedded realtime bytes. - */ - /* assume that this is a real-time message: - * it is an error to pass non-real-time messages - * to pm_read_bytes - */ - event.message = byte; - pm_read_short(midi, &event); - } - } /* all bytes in the buffer are processed */ - } - /* Now, isysex_in_progress) { - if (midi->sysex_message_count == 0 && i <= len - 4 && - ((event.message = (((PmMessage) data[i]) | - (((PmMessage) data[i+1]) << 8) | - (((PmMessage) data[i+2]) << 16) | - (((PmMessage) data[i+3]) << 24))) & - 0x80808080) == 0) { /* all data, no status */ - if (Pm_Enqueue(midi->queue, &event) == pmBufferOverflow) { - midi->sysex_in_progress = FALSE; - } - i += 4; - } else { - while (i < len) { - /* send one byte at a time */ - unsigned char byte = data[i++]; - if (is_real_time(byte) && - pm_realtime_filtered(byte, midi->filters)) { - continue; /* real-time data is filtered, so omit */ - } - midi->sysex_message |= - (byte << (8 * midi->sysex_message_count++)); - if (byte == MIDI_EOX) { - midi->sysex_in_progress = FALSE; - pm_flush_sysex(midi, event.timestamp); - return i; - } else if (midi->sysex_message_count == 4) { - pm_flush_sysex(midi, event.timestamp); - /* after handling at least one non-data byte - * and reaching a 4-byte message boundary, - * resume trying to send 4 at a time in outer loop - */ - break; - } - } - } - } - return i; -} - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/Makefile.osx b/libs/backends/wavesaudio/portmidi/src/pm_mac/Makefile.osx deleted file mode 100644 index 8c6862e28f..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/Makefile.osx +++ /dev/null @@ -1,129 +0,0 @@ -# MAKEFILE FOR PORTMIDI - -# Roger B. Dannenberg -# Sep 2009 - -# NOTE: you can use -# make -f pm_osx/Makefile.osx configuration=Release -# to override the default Debug configuration -configuration=Release - -PF=/usr/local - -# For debugging, define PM_CHECK_ERRORS -ifeq ($(configuration),Release) - CONFIG = Release -else - CONFIG = Debug -endif - -current: all - -all: $(CONFIG)/CMakeCache.txt - cd $(CONFIG); make - -$(CONFIG)/CMakeCache.txt: - rm -f CMakeCache.txt - mkdir -p $(CONFIG) - cd $(CONFIG); cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=$(CONFIG) - - -**** For instructions: make -f pm_mac\Makefile.osx help ****\n' - -help: - echo $$'\n\n\ -This is help for portmidi/pm_mac/Makefile.osx\n\n\ -Installation path for dylib is $(PF)\n\ -To build Release version libraries and test applications,\n \ -make -f pm_mac/Makefile.osx\n\ -To build Debug version libraries and test applications,\n \ -make -f pm_mac/Makefile.osx configuration=Debug\n\ -To install universal dynamic library,\n \ -sudo make -f pm_mac/Makefile.osx install\n\ -To install universal dynamic library with xcode,\n \ -make -f pm_mac/Makefile.osx install-with-xcode\n\ -To make PmDefaults Java application,\n \ -make -f pm_mac/Makefile.osx pmdefaults\n\n \ -configuration = $(configuration)\n' - - -clean: - rm -f *.o *~ core* */*.o */*/*.o */*~ */core* pm_test/*/pm_dll.dll - rm -f *.opt *.ncb *.plg pm_win/Debug/pm_dll.lib pm_win/Release/pm_dll.lib - rm -f pm_test/*.opt pm_test/*.ncb - rm -f pm_java/pmjni/*.o pm_java/pmjni/*~ pm_java/*.h - rm -rf Release/CMakeFiles Debug/CMakeFiles - rm -rf pm_mac/pmdefaults/lib pm_mac/pmdefaults/src - -cleaner: clean - rm -rf pm_mac/build - rm -rf pm_mac/Debug pm_mac/Release pm_test/Debug pm_test/Release - rm -f Debug/*.dylib Release/*.dylib - rm -f pm_java/pmjni/Debug/*.jnilib - rm -f pm_java/pmjni/Release/*.jnilib - -cleanest: cleaner - rm -f Debug/libportmidi_s.a Release/libportmidi_s.a - rm -f pm_test/Debug/test pm_test/Debug/sysex pm_test/Debug/midithread - rm -f pm_test/Debug/latency pm_test/Debug/midithru - rm -f pm_test/Debug/qtest pm_test/Debug/mm - rm -f pm_test/Release/test pm_test/Release/sysex pm_test/Release/midithread - rm -f pm_test/Release/latency pm_test/Release/midithru - rm -f pm_test/Release/qtest pm_test/Release/mm - rm -f pm_java/*/*.class - rm -f pm_java/pmjni/jportmidi_JPortMidiApi_PortMidiStream.h - -backup: cleanest - cd ..; zip -r portmidi.zip portmidi - -install: porttime/porttime.h pm_common/portmidi.h \ - $(CONFIG)/libportmidi.dylib - install porttime/porttime.h $(PF)/include/ - install pm_common/portmidi.h $(PF)/include - install $(CONFIG)/libportmidi.dylib $(PF)/lib/ - -# note - this uses xcode to build and install portmidi universal binaries -install-with-xcode: - sudo xcodebuild -project pm_mac/pm_mac.xcodeproj \ - -configuration Release install DSTROOT=/ - -##### build pmdefault ###### - -pm_java/pmjni/jportmidi_JPortMidiApi.h: pm_java/jportmidi/JPortMidiApi.class - cd pm_java; javah jportmidi.JPortMidiApi - mv pm_java/jportmidi_JportMidiApi.h pm_java/pmjni - -JAVASRC = pmdefaults/PmDefaultsFrame.java \ - pmdefaults/PmDefaults.java \ - jportmidi/JPortMidiApi.java jportmidi/JPortMidi.java \ - jportmidi/JPortMidiException.java - -# this compiles ALL of the java code -pm_java/jportmidi/JPortMidiApi.class: $(JAVASRC:%=pm_java/%) - cd pm_java; javac $(JAVASRC) - -$(CONFIG)/libpmjni.dylib: - mkdir -p $(CONFIG) - cd $(CONFIG); make -f ../pm_mac/$(MAKEFILE) - -pmdefaults: $(CONFIG)/libpmjni.dylib pm_java/jportmidi/JPortMidiApi.class -ifeq ($(CONFIG),Debug) - echo "Error: you cannot build pmdefaults in a Debug configuration \n\ - You should use configuration=Release in the Makefile command line. " - @exit 2 -endif - xcodebuild -project pm_mac/pm_mac.xcodeproj \ - -configuration Release -target PmDefaults - echo "pmdefaults java application is made" - -###### test plist reader ####### -PLHDR = pm_mac/readbinaryplist.h -PLSRC = pm_mac/plisttest.c pm_mac/readbinaryplist.c -pm_mac/plisttest: $(PLHDR) $(PLSRC) - cc $(VFLAGS) -Ipm_mac \ - -I/Developer/Headers/FlatCarbon \ - -I/System/Library/Frameworks/CoreFoundation.framework/Headers \ - -I/System/Library/Frameworks/CoreServices.framework/Headers \ - $(PLSRC) -o pm_mac/$(CONFIG)/plisttest \ - -framework CoreFoundation -framework CoreServices - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/README_MAC.txt b/libs/backends/wavesaudio/portmidi/src/pm_mac/README_MAC.txt deleted file mode 100644 index 1650dccecc..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/README_MAC.txt +++ /dev/null @@ -1,163 +0,0 @@ -README_MAC.txt for PortMidi -Roger Dannenberg -20 nov 2009 -revised 20 Sep 2010 for Xcode 3.2.4 and CMake 8.2-2 - -To build PortMidi for Mac OS X, you must install Xcode and -CMake. - -CMake can build either command-line Makefiles or Xcode projects. -These approaches are described in separate sections below. - -==== CLEANING UP ==== -(Skip this for now, but later you might want start from a clean -slate.) - -Start in the portmedia/portmidi directory. - -make -f pm_mac/Makefile.osx clean - -will remove .o, CMakeFiles, and other intermediate files. - -Using "cleaner" instead of "clean" will also remove jni-related -intermediate files. - -Using "cleanest" instead of "clean" or "cleaner" will also remove -application binaries and the portmidi libraries. (It will not -uninstall anything, however.) - -==== USING CMAKE (AND COMMAND LINE TOOLS) ==== - -Start in the portmedia/portmidi directory. - -make -f pm_mac/Makefile.osx - -(Begin note: make will invoke cmake to build a Makefile and then make to -build portmidi. This extra level allows you to correctly build -both Release and Debug versions. Release is the default, so to get -the Debug version, use: - -make -f pm_mac/Makefile.osx configuration=Debug -) - -Release version executables and libraries are now in - portmedia/portmidi/Release - -Debug version executables and libraries are created in - portmedia/portmidi/Debug -The Debug versions are compiled with PM_CHECK_ERRORS which -prints an error message and aborts when an error code is returned -by PortMidi functions. This is useful for small command line -applications. Otherwise, you should check and handle error returns -in your program. - -You can install portmidi as follows: - -cd Release; sudo make install - -This will install /usr/local/include/{portmidi.h, porttime.h} -and /usr/local/lib/{libportmidi.dylib, libportmidi_s.a, libpmjni.dylib} - -You should now make the pmdefaults.app: - -make -f pm_mac/Makefile.osx pmdefaults - -NOTE: pmdefaults.app will be in pm_mac/Release/. - -Please copy pmdefaults.app to your Applications folder or wherever -you would normally expect to find it. - -==== USING CMAKE TO BUILD Xcode PROJECT ==== - -Before you can use Xcode, you need a portmidi.xcodeproj file. -CMake builds a location-dependent Xcode project, so unfortunately -it is not easy to provide an Xcode project that is ready to use. -Therefore, you should make your own. Once you have it, you can -use it almost like any other Xcode project, and you will not have -to go back to CMake. - -(1) Install CMake if you do not have it already. - -(2) Open portmedia/portmidi/CMakeLists.txt with CMake - -(3) Use Configure and Generate buttons - -(4) This creates portmedia/portmidi/portmidi.xcodeproj. - -Note: You will also use pm_mac/pm_mac.xcodeproj, which -is not generated by CMake. - -(5) Open portmidi/portmidi.xcodeproj with Xcode and -build what you need. The simplest thing is to build the -ALL_BUILD target. The default will be to build the Debug -version, but you may want to change this to Release. - -NOTE: ALL_BUILD may report errors. Try simply building again -or rebuilding specific targets that fail until they build -without errors. There appears to be a race condition or -missing dependencies in the build system. - -The Debug version is compiled with PM_CHECK_ERRORS, and the -Release version is not. PM_CHECK_ERRORS will print an error -message and exit your program if any error is returned from -a call into PortMidi. - -CMake (currently) also creates MinSizRel and RelWithDebInfo -versions, but only because I cannot figure out how to disable -them. - -You will probably want the application PmDefaults, which sets -default MIDI In and Out devices for PortMidi. You may also -want to build a Java application using PortMidi. Since I have -not figured out how to use CMake to make an OS X Java application, -use pm_mac/pm_mac.xcodeproj as follows: - -(6) open pm_mac/pm_mac.xcodeproj - -(7) pm_java/pmjni/portmidi_JportmidiApi.h is needed -by libpmjni.jnilib, the Java native interface library. Since -portmidi_JportmidiApi.h is included with PortMidi, you can skip -to step 8, but if you really want to rebuild everything from -scratch, build the JPortMidiHeaders project first, and continue -with step 8: - -(8) If you did not build libpmjni.dylib using portmidi.xcodeproj, -do it now. (It depends on portmidi_JportmidiApi.h, and the -PmDefaults project depends on libpmjni.dylib.) - -(9) Returning to pm_mac.xcodeproj, build the PmDefaults program. - -(10) If you wish, copy pm_mac/build/Deployment/PmDefaults.app to -your applications folder. - -(11) If you want to install libportmidi.dylib, first make it with -Xcode, then - sudo make -f pm_mac/Makefile.osx install -This command will install /usr/local/include/{porttime.h, portmidi.h} -and /usr/local/lib/libportmidi.dylib -Note that the "install" function of xcode creates portmidi/Release -and does not install the library to /usr/local/lib, so please use -the command line installer. - - -CHANGELOG - -20-Sep-2010 Roger B. Dannenberg - Adapted to Xcode 3.2.4 -20-Nov-2009 Roger B. Dannenberg - Added some install instructions -26-Sep-2009 Roger B. Dannenberg - More changes for using CMake, Makefiles, XCode -20-Sep-2009 Roger B. Dannenberg - Modifications for using CMake -14-Sep-2009 Roger B. Dannenberg - Modifications for using CMake -17-Jan-2007 Roger B. Dannenberg - Explicit instructions for Xcode -15-Jan-2007 Roger B. Dannenberg - Changed instructions because of changes to Makefile.osx -07-Oct-2006 Roger B. Dannenberg - Added directions for xcodebuild -29-aug-2006 Roger B. Dannenberg - Updated this documentation. - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/finddefault.c b/libs/backends/wavesaudio/portmidi/src/pm_mac/finddefault.c deleted file mode 100644 index 59e02a10be..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/finddefault.c +++ /dev/null @@ -1,57 +0,0 @@ -/* finddefault.c -- find_default_device() implementation - Roger Dannenberg, June 2008 -*/ - -#include -#include -#include "portmidi.h" -#include "pmutil.h" -#include "pminternal.h" -#include "pmmacosxcm.h" -#include "readbinaryplist.h" - -/* Parse preference files, find default device, search devices -- - This parses the preference file(s) once for input and once for - output, which is inefficient but much simpler to manage. Note - that using the readbinaryplist.c module, you cannot keep two - plist files (user and system) open at once (due to a simple - memory management scheme). -*/ -PmDeviceID find_default_device(char *path, int input, PmDeviceID id) -/* path -- the name of the preference we are searching for - input -- true iff this is an input device - id -- current default device id - returns matching device id if found, otherwise id -*/ -{ - static char *pref_file = "com.apple.java.util.prefs.plist"; - char *pref_str = NULL; - // read device preferences - value_ptr prefs = bplist_read_user_pref(pref_file); - if (prefs) { - value_ptr pref_val = value_dict_lookup_using_path(prefs, path); - if (pref_val) { - pref_str = value_get_asciistring(pref_val); - } - } - if (!pref_str) { - bplist_free_data(); /* look elsewhere */ - prefs = bplist_read_system_pref(pref_file); - if (prefs) { - value_ptr pref_val = value_dict_lookup_using_path(prefs, path); - if (pref_val) { - pref_str = value_get_asciistring(pref_val); - } - } - } - if (pref_str) { /* search devices for match */ - int i = pm_find_default_device(pref_str, input); - if (i != pmNoDevice) { - id = i; - } - } - if (prefs) { - bplist_free_data(); - } - return id; -} diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.pbxproj b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.pbxproj deleted file mode 100644 index 0d06e565ea..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.pbxproj +++ /dev/null @@ -1,594 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 44; - objects = { - -/* Begin PBXAggregateTarget section */ - 3D634CAB1247805C0020F829 /* JPortMidiHeaders */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 3D634CAE1247807A0020F829 /* Build configuration list for PBXAggregateTarget "JPortMidiHeaders" */; - buildPhases = ( - 3D634CAA1247805C0020F829 /* ShellScript */, - ); - dependencies = ( - 3D634CB0124781580020F829 /* PBXTargetDependency */, - ); - name = JPortMidiHeaders; - productName = JPortMidiHeaders; - }; - 3DE2142D124662AA0033C839 /* CopyJavaSources */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 3DE21434124662FF0033C839 /* Build configuration list for PBXAggregateTarget "CopyJavaSources" */; - buildPhases = ( - 3DE2142C124662AA0033C839 /* CopyFiles */, - ); - comments = "The reason for copying files here is that the Compile Java target looks in a particular place for sources. It would be much better to simply have Compile Java look in the original location for all sources, but I don't know how to do that. -RBD\n"; - dependencies = ( - ); - name = CopyJavaSources; - productName = CopyJavaSources; - }; - 89D0F1C90F3B704E007831A7 /* PmDefaults */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 89D0F1D20F3B7080007831A7 /* Build configuration list for PBXAggregateTarget "PmDefaults" */; - buildPhases = ( - ); - dependencies = ( - 89D0F1D10F3B7062007831A7 /* PBXTargetDependency */, - 89D0F1CD0F3B7062007831A7 /* PBXTargetDependency */, - 3DE21431124662C50033C839 /* PBXTargetDependency */, - ); - name = PmDefaults; - productName = pmdefaults; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 3DE2137F124653FB0033C839 /* portmusic_logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 3DE2137E124653FB0033C839 /* portmusic_logo.png */; }; - 3DE21435124663860033C839 /* PmDefaultsFrame.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE2137D124653CB0033C839 /* PmDefaultsFrame.java */; }; - 3DE214361246638A0033C839 /* PmDefaults.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE2137B1246538B0033C839 /* PmDefaults.java */; }; - 3DE214371246638F0033C839 /* JPortMidiException.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE21382124654DE0033C839 /* JPortMidiException.java */; }; - 3DE214381246638F0033C839 /* JPortMidiApi.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE21381124654CF0033C839 /* JPortMidiApi.java */; }; - 3DE214391246638F0033C839 /* JPortMidi.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE21380124654BC0033C839 /* JPortMidi.java */; }; - 3DE216131246AC0E0033C839 /* libpmjni.dylib in Copy Java Resources */ = {isa = PBXBuildFile; fileRef = 3DE216101246ABE30033C839 /* libpmjni.dylib */; }; - 3DE216951246D57A0033C839 /* pmdefaults.icns in Resources */ = {isa = PBXBuildFile; fileRef = 3DE216901246C6410033C839 /* pmdefaults.icns */; }; - 89C3F2920F5250A300B0048E /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 89C3F2900F5250A300B0048E /* Credits.rtf */; }; - 89D0F0240F392F20007831A7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 89D0F0210F392F20007831A7 /* InfoPlist.strings */; }; - 89D0F0410F39306C007831A7 /* JavaApplicationStub in Copy Executable */ = {isa = PBXBuildFile; fileRef = 89D0F03E0F39304A007831A7 /* JavaApplicationStub */; }; - 89D0F16A0F3A124E007831A7 /* pmdefaults.jar in Copy Java Resources */ = {isa = PBXBuildFile; fileRef = 89D0F15D0F3A0FF7007831A7 /* pmdefaults.jar */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 3D634CAF124781580020F829 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 89D0F1C90F3B704E007831A7; - remoteInfo = PmDefaults; - }; - 3DE21430124662C50033C839 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3DE2142D124662AA0033C839; - remoteInfo = CopyJavaSources; - }; - 3DE2145D124666900033C839 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3DE2142D124662AA0033C839; - remoteInfo = CopyJavaSources; - }; - 89D0F1CC0F3B7062007831A7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D1107260486CEB800E47090; - remoteInfo = "Assemble Application"; - }; - 89D0F1D00F3B7062007831A7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 89D0F0480F393A6F007831A7; - remoteInfo = "Compile Java"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 3DE2142C124662AA0033C839 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "${PROJECT_DIR}/pmdefaults/src/java"; - dstSubfolderSpec = 0; - files = ( - 3DE21435124663860033C839 /* PmDefaultsFrame.java in CopyFiles */, - 3DE214361246638A0033C839 /* PmDefaults.java in CopyFiles */, - 3DE214371246638F0033C839 /* JPortMidiException.java in CopyFiles */, - 3DE214381246638F0033C839 /* JPortMidiApi.java in CopyFiles */, - 3DE214391246638F0033C839 /* JPortMidi.java in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 89D0F0440F393070007831A7 /* Copy Executable */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 6; - files = ( - 89D0F0410F39306C007831A7 /* JavaApplicationStub in Copy Executable */, - ); - name = "Copy Executable"; - runOnlyForDeploymentPostprocessing = 0; - }; - 89D0F11F0F394189007831A7 /* Copy Java Resources */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 15; - files = ( - 89D0F16A0F3A124E007831A7 /* pmdefaults.jar in Copy Java Resources */, - 3DE216131246AC0E0033C839 /* libpmjni.dylib in Copy Java Resources */, - ); - name = "Copy Java Resources"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 3DE2137B1246538B0033C839 /* PmDefaults.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = PmDefaults.java; path = ../pm_java/pmdefaults/PmDefaults.java; sourceTree = SOURCE_ROOT; }; - 3DE2137D124653CB0033C839 /* PmDefaultsFrame.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = PmDefaultsFrame.java; path = ../pm_java/pmdefaults/PmDefaultsFrame.java; sourceTree = SOURCE_ROOT; }; - 3DE2137E124653FB0033C839 /* portmusic_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = portmusic_logo.png; path = ../pm_java/pmdefaults/portmusic_logo.png; sourceTree = SOURCE_ROOT; }; - 3DE21380124654BC0033C839 /* JPortMidi.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = JPortMidi.java; path = ../pm_java/jportmidi/JPortMidi.java; sourceTree = SOURCE_ROOT; }; - 3DE21381124654CF0033C839 /* JPortMidiApi.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = JPortMidiApi.java; path = ../pm_java/jportmidi/JPortMidiApi.java; sourceTree = SOURCE_ROOT; }; - 3DE21382124654DE0033C839 /* JPortMidiException.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = JPortMidiException.java; path = ../pm_java/jportmidi/JPortMidiException.java; sourceTree = SOURCE_ROOT; }; - 3DE213841246555A0033C839 /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = /System/Library/Frameworks/CoreMIDI.framework; sourceTree = ""; }; - 3DE21390124655760033C839 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; - 3DE213BE1246557F0033C839 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; - 3DE216101246ABE30033C839 /* libpmjni.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpmjni.dylib; path = ../Release/libpmjni.dylib; sourceTree = SOURCE_ROOT; }; - 3DE216901246C6410033C839 /* pmdefaults.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = pmdefaults.icns; path = ../pm_java/pmdefaults/pmdefaults.icns; sourceTree = SOURCE_ROOT; }; - 89C3F2910F5250A300B0048E /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/Credits.rtf; sourceTree = ""; }; - 89D0F0220F392F20007831A7 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; - 89D0F0230F392F20007831A7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 89D0F03E0F39304A007831A7 /* JavaApplicationStub */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = JavaApplicationStub; path = /System/Library/Frameworks/JavaVM.framework/Versions/A/Resources/MacOS/JavaApplicationStub; sourceTree = ""; }; - 89D0F0840F394066007831A7 /* JavaNativeFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaNativeFoundation.framework; path = /System/Library/Frameworks/JavaVM.framework/Versions/A/Frameworks/JavaNativeFoundation.framework; sourceTree = ""; }; - 89D0F1390F3948A9007831A7 /* pmdefaults/make */ = {isa = PBXFileReference; lastKnownFileType = folder; path = pmdefaults/make; sourceTree = ""; }; - 89D0F15D0F3A0FF7007831A7 /* pmdefaults.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = pmdefaults.jar; path = build/Release/pmdefaults.jar; sourceTree = SOURCE_ROOT; }; - 89D0F1860F3A2442007831A7 /* JavaVM.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaVM.framework; path = /System/Library/Frameworks/JavaVM.framework; sourceTree = ""; }; - 8D1107320486CEB800E47090 /* PmDefaults.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PmDefaults.app; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXGroup section */ - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 3DE213841246555A0033C839 /* CoreMIDI.framework */, - 3DE21390124655760033C839 /* CoreFoundation.framework */, - 3DE213BE1246557F0033C839 /* CoreAudio.framework */, - 89D0F1860F3A2442007831A7 /* JavaVM.framework */, - 89D0F0840F394066007831A7 /* JavaNativeFoundation.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 89D0F15D0F3A0FF7007831A7 /* pmdefaults.jar */, - 8D1107320486CEB800E47090 /* PmDefaults.app */, - ); - name = Products; - sourceTree = ""; - }; - 29B97314FDCFA39411CA2CEA /* pmdefaults */ = { - isa = PBXGroup; - children = ( - 3DE216101246ABE30033C839 /* libpmjni.dylib */, - 89D0F0260F392F48007831A7 /* Source */, - 89D0F0200F392F20007831A7 /* Resources */, - 89D0F1390F3948A9007831A7 /* pmdefaults/make */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - ); - name = pmdefaults; - sourceTree = ""; - }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; - 3DE2136A124652E20033C839 /* pm_java */ = { - isa = PBXGroup; - children = ( - 3DE21379124653150033C839 /* pmdefaults */, - 3DE2137A1246531D0033C839 /* jportmidi */, - ); - name = pm_java; - path = ..; - sourceTree = ""; - }; - 3DE21379124653150033C839 /* pmdefaults */ = { - isa = PBXGroup; - children = ( - 3DE2137D124653CB0033C839 /* PmDefaultsFrame.java */, - 3DE2137B1246538B0033C839 /* PmDefaults.java */, - ); - name = pmdefaults; - sourceTree = ""; - }; - 3DE2137A1246531D0033C839 /* jportmidi */ = { - isa = PBXGroup; - children = ( - 3DE21382124654DE0033C839 /* JPortMidiException.java */, - 3DE21381124654CF0033C839 /* JPortMidiApi.java */, - 3DE21380124654BC0033C839 /* JPortMidi.java */, - ); - name = jportmidi; - sourceTree = ""; - }; - 89D0F0200F392F20007831A7 /* Resources */ = { - isa = PBXGroup; - children = ( - 3DE216901246C6410033C839 /* pmdefaults.icns */, - 3DE2137E124653FB0033C839 /* portmusic_logo.png */, - 89C3F2900F5250A300B0048E /* Credits.rtf */, - 89D0F0230F392F20007831A7 /* Info.plist */, - 89D0F0210F392F20007831A7 /* InfoPlist.strings */, - 89D0F03E0F39304A007831A7 /* JavaApplicationStub */, - ); - name = Resources; - path = pmdefaults/resources; - sourceTree = ""; - }; - 89D0F0260F392F48007831A7 /* Source */ = { - isa = PBXGroup; - children = ( - 3DE2136A124652E20033C839 /* pm_java */, - ); - name = Source; - path = pmdefaults/src; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXLegacyTarget section */ - 89D0F0480F393A6F007831A7 /* Compile Java */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "-e -f \"${SRCROOT}/make/build.xml\" -debug \"$ACTION\""; - buildConfigurationList = 89D0F04B0F393AB7007831A7 /* Build configuration list for PBXLegacyTarget "Compile Java" */; - buildPhases = ( - ); - buildToolPath = /usr/bin/ant; - buildWorkingDirectory = ""; - dependencies = ( - 3DE2145E124666900033C839 /* PBXTargetDependency */, - ); - name = "Compile Java"; - passBuildSettingsInEnvironment = 1; - productName = "Compile Java"; - }; -/* End PBXLegacyTarget section */ - -/* Begin PBXNativeTarget section */ - 8D1107260486CEB800E47090 /* Assemble Application */ = { - isa = PBXNativeTarget; - buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Assemble Application" */; - buildPhases = ( - 89D0F0440F393070007831A7 /* Copy Executable */, - 89D0F11F0F394189007831A7 /* Copy Java Resources */, - 8D1107290486CEB800E47090 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "Assemble Application"; - productInstallPath = "$(HOME)/Applications"; - productName = pmdefaults; - productReference = 8D1107320486CEB800E47090 /* PmDefaults.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "pm_mac" */; - compatibilityVersion = "Xcode 3.0"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 29B97314FDCFA39411CA2CEA /* pmdefaults */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 3D634CAB1247805C0020F829 /* JPortMidiHeaders */, - 89D0F1C90F3B704E007831A7 /* PmDefaults */, - 3DE2142D124662AA0033C839 /* CopyJavaSources */, - 89D0F0480F393A6F007831A7 /* Compile Java */, - 8D1107260486CEB800E47090 /* Assemble Application */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D1107290486CEB800E47090 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3DE216951246D57A0033C839 /* pmdefaults.icns in Resources */, - 89D0F0240F392F20007831A7 /* InfoPlist.strings in Resources */, - 89C3F2920F5250A300B0048E /* Credits.rtf in Resources */, - 3DE2137F124653FB0033C839 /* portmusic_logo.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3D634CAA1247805C0020F829 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo BUILT_PRODUCTS_DIR is ${BUILT_PRODUCTS_DIR}\njavah -classpath \"${BUILT_PRODUCTS_DIR}/pmdefaults.jar\" -force -o \"${BUILT_PRODUCTS_DIR}/jportmidi_JportMidiApi.h\" \"jportmidi.JPortMidiApi\"\nmv \"${BUILT_PRODUCTS_DIR}/jportmidi_JportMidiApi.h\" ../pm_java/pmjni/\necho \"Created ../pm_java/pmjni/jportmidi_JportMidiApi.h\"\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 3D634CB0124781580020F829 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 89D0F1C90F3B704E007831A7 /* PmDefaults */; - targetProxy = 3D634CAF124781580020F829 /* PBXContainerItemProxy */; - }; - 3DE21431124662C50033C839 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3DE2142D124662AA0033C839 /* CopyJavaSources */; - targetProxy = 3DE21430124662C50033C839 /* PBXContainerItemProxy */; - }; - 3DE2145E124666900033C839 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3DE2142D124662AA0033C839 /* CopyJavaSources */; - targetProxy = 3DE2145D124666900033C839 /* PBXContainerItemProxy */; - }; - 89D0F1CD0F3B7062007831A7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D1107260486CEB800E47090 /* Assemble Application */; - targetProxy = 89D0F1CC0F3B7062007831A7 /* PBXContainerItemProxy */; - }; - 89D0F1D10F3B7062007831A7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 89D0F0480F393A6F007831A7 /* Compile Java */; - targetProxy = 89D0F1D00F3B7062007831A7 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 89C3F2900F5250A300B0048E /* Credits.rtf */ = { - isa = PBXVariantGroup; - children = ( - 89C3F2910F5250A300B0048E /* English */, - ); - name = Credits.rtf; - sourceTree = ""; - }; - 89D0F0210F392F20007831A7 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 89D0F0220F392F20007831A7 /* English */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 3D634CAC1247805C0020F829 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - PRODUCT_NAME = JPortMidiHeaders; - }; - name = Debug; - }; - 3D634CAD1247805C0020F829 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PRODUCT_NAME = JPortMidiHeaders; - ZERO_LINK = NO; - }; - name = Release; - }; - 3DE2142E124662AB0033C839 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - PRODUCT_NAME = CopyJavaSources; - }; - name = Debug; - }; - 3DE2142F124662AB0033C839 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PRODUCT_NAME = CopyJavaSources; - ZERO_LINK = NO; - }; - name = Release; - }; - 89D0F0490F393A6F007831A7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = pmdefaults; - SRCROOT = ./pmdefaults; - }; - name = Debug; - }; - 89D0F04A0F393A6F007831A7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = pmdefaults; - SRCROOT = ./pmdefaults; - }; - name = Release; - }; - 89D0F1CA0F3B704F007831A7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = pmdefaults; - }; - name = Debug; - }; - 89D0F1CB0F3B704F007831A7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = pmdefaults; - }; - name = Release; - }; - C01FCF4B08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CONFIGURATION_BUILD_DIR = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - COPY_PHASE_STRIP = NO; - INFOPLIST_FILE = pmdefaults/resources/Info.plist; - INSTALL_PATH = "$(HOME)/Applications"; - PRODUCT_NAME = pmdefaults; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - C01FCF4C08A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CONFIGURATION_BUILD_DIR = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - INFOPLIST_FILE = pmdefaults/resources/Info.plist; - INSTALL_PATH = "$(HOME)/Applications"; - PRODUCT_NAME = PmDefaults; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; - C01FCF4F08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - }; - name = Debug; - }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 3D634CAE1247807A0020F829 /* Build configuration list for PBXAggregateTarget "JPortMidiHeaders" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3D634CAC1247805C0020F829 /* Debug */, - 3D634CAD1247805C0020F829 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3DE21434124662FF0033C839 /* Build configuration list for PBXAggregateTarget "CopyJavaSources" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3DE2142E124662AB0033C839 /* Debug */, - 3DE2142F124662AB0033C839 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 89D0F04B0F393AB7007831A7 /* Build configuration list for PBXLegacyTarget "Compile Java" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 89D0F0490F393A6F007831A7 /* Debug */, - 89D0F04A0F393A6F007831A7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 89D0F1D20F3B7080007831A7 /* Build configuration list for PBXAggregateTarget "PmDefaults" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 89D0F1CA0F3B704F007831A7 /* Debug */, - 89D0F1CB0F3B704F007831A7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Assemble Application" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4B08A954540054247B /* Debug */, - C01FCF4C08A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "pm_mac" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 570e6faa82..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.xcworkspace/xcuserdata/VKamyshniy.xcuserdatad/UserInterfaceState.xcuserstate b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.xcworkspace/xcuserdata/VKamyshniy.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 104c0fe910..0000000000 Binary files a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/project.xcworkspace/xcuserdata/VKamyshniy.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Assemble Application.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Assemble Application.xcscheme deleted file mode 100644 index b2051a67b0..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Assemble Application.xcscheme +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Compile Java.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Compile Java.xcscheme deleted file mode 100644 index 415b487914..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Compile Java.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/CopyJavaSources.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/CopyJavaSources.xcscheme deleted file mode 100644 index ad37276ccc..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/CopyJavaSources.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme deleted file mode 100644 index de0f0bcef7..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/PmDefaults.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/PmDefaults.xcscheme deleted file mode 100644 index 23d63e9bac..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/PmDefaults.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/xcschememanagement.plist b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index a57f870bb5..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - SchemeUserState - - Assemble Application.xcscheme - - orderHint - 4 - - Compile Java.xcscheme - - orderHint - 3 - - CopyJavaSources.xcscheme - - orderHint - 2 - - JPortMidiHeaders.xcscheme - - orderHint - 0 - - PmDefaults.xcscheme - - orderHint - 1 - - - SuppressBuildableAutocreation - - 3D634CAB1247805C0020F829 - - primary - - - 3DE2142D124662AA0033C839 - - primary - - - 89D0F0480F393A6F007831A7 - - primary - - - 89D0F1C90F3B704E007831A7 - - primary - - - 8D1107260486CEB800E47090 - - primary - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Assemble Application.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Assemble Application.xcscheme deleted file mode 100644 index b2051a67b0..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Assemble Application.xcscheme +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Compile Java.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Compile Java.xcscheme deleted file mode 100644 index 415b487914..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Compile Java.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/CopyJavaSources.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/CopyJavaSources.xcscheme deleted file mode 100644 index ad37276ccc..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/CopyJavaSources.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme deleted file mode 100644 index de0f0bcef7..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/PmDefaults.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/PmDefaults.xcscheme deleted file mode 100644 index 23d63e9bac..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/PmDefaults.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/xcschememanagement.plist b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 4c011dee54..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - SchemeUserState - - Assemble Application.xcscheme - - orderHint - 5 - - Compile Java.xcscheme - - orderHint - 4 - - CopyJavaSources.xcscheme - - orderHint - 3 - - JPortMidiHeaders.xcscheme - - orderHint - 1 - - PmDefaults.xcscheme - - orderHint - 2 - - - SuppressBuildableAutocreation - - 3D634CAB1247805C0020F829 - - primary - - - 3DE2142D124662AA0033C839 - - primary - - - 89D0F0480F393A6F007831A7 - - primary - - - 89D0F1C90F3B704E007831A7 - - primary - - - 8D1107260486CEB800E47090 - - primary - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.pbxproj b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.pbxproj deleted file mode 100644 index 0d06e565ea..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.pbxproj +++ /dev/null @@ -1,594 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 44; - objects = { - -/* Begin PBXAggregateTarget section */ - 3D634CAB1247805C0020F829 /* JPortMidiHeaders */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 3D634CAE1247807A0020F829 /* Build configuration list for PBXAggregateTarget "JPortMidiHeaders" */; - buildPhases = ( - 3D634CAA1247805C0020F829 /* ShellScript */, - ); - dependencies = ( - 3D634CB0124781580020F829 /* PBXTargetDependency */, - ); - name = JPortMidiHeaders; - productName = JPortMidiHeaders; - }; - 3DE2142D124662AA0033C839 /* CopyJavaSources */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 3DE21434124662FF0033C839 /* Build configuration list for PBXAggregateTarget "CopyJavaSources" */; - buildPhases = ( - 3DE2142C124662AA0033C839 /* CopyFiles */, - ); - comments = "The reason for copying files here is that the Compile Java target looks in a particular place for sources. It would be much better to simply have Compile Java look in the original location for all sources, but I don't know how to do that. -RBD\n"; - dependencies = ( - ); - name = CopyJavaSources; - productName = CopyJavaSources; - }; - 89D0F1C90F3B704E007831A7 /* PmDefaults */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 89D0F1D20F3B7080007831A7 /* Build configuration list for PBXAggregateTarget "PmDefaults" */; - buildPhases = ( - ); - dependencies = ( - 89D0F1D10F3B7062007831A7 /* PBXTargetDependency */, - 89D0F1CD0F3B7062007831A7 /* PBXTargetDependency */, - 3DE21431124662C50033C839 /* PBXTargetDependency */, - ); - name = PmDefaults; - productName = pmdefaults; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 3DE2137F124653FB0033C839 /* portmusic_logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 3DE2137E124653FB0033C839 /* portmusic_logo.png */; }; - 3DE21435124663860033C839 /* PmDefaultsFrame.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE2137D124653CB0033C839 /* PmDefaultsFrame.java */; }; - 3DE214361246638A0033C839 /* PmDefaults.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE2137B1246538B0033C839 /* PmDefaults.java */; }; - 3DE214371246638F0033C839 /* JPortMidiException.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE21382124654DE0033C839 /* JPortMidiException.java */; }; - 3DE214381246638F0033C839 /* JPortMidiApi.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE21381124654CF0033C839 /* JPortMidiApi.java */; }; - 3DE214391246638F0033C839 /* JPortMidi.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE21380124654BC0033C839 /* JPortMidi.java */; }; - 3DE216131246AC0E0033C839 /* libpmjni.dylib in Copy Java Resources */ = {isa = PBXBuildFile; fileRef = 3DE216101246ABE30033C839 /* libpmjni.dylib */; }; - 3DE216951246D57A0033C839 /* pmdefaults.icns in Resources */ = {isa = PBXBuildFile; fileRef = 3DE216901246C6410033C839 /* pmdefaults.icns */; }; - 89C3F2920F5250A300B0048E /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 89C3F2900F5250A300B0048E /* Credits.rtf */; }; - 89D0F0240F392F20007831A7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 89D0F0210F392F20007831A7 /* InfoPlist.strings */; }; - 89D0F0410F39306C007831A7 /* JavaApplicationStub in Copy Executable */ = {isa = PBXBuildFile; fileRef = 89D0F03E0F39304A007831A7 /* JavaApplicationStub */; }; - 89D0F16A0F3A124E007831A7 /* pmdefaults.jar in Copy Java Resources */ = {isa = PBXBuildFile; fileRef = 89D0F15D0F3A0FF7007831A7 /* pmdefaults.jar */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 3D634CAF124781580020F829 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 89D0F1C90F3B704E007831A7; - remoteInfo = PmDefaults; - }; - 3DE21430124662C50033C839 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3DE2142D124662AA0033C839; - remoteInfo = CopyJavaSources; - }; - 3DE2145D124666900033C839 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3DE2142D124662AA0033C839; - remoteInfo = CopyJavaSources; - }; - 89D0F1CC0F3B7062007831A7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 8D1107260486CEB800E47090; - remoteInfo = "Assemble Application"; - }; - 89D0F1D00F3B7062007831A7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 89D0F0480F393A6F007831A7; - remoteInfo = "Compile Java"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 3DE2142C124662AA0033C839 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "${PROJECT_DIR}/pmdefaults/src/java"; - dstSubfolderSpec = 0; - files = ( - 3DE21435124663860033C839 /* PmDefaultsFrame.java in CopyFiles */, - 3DE214361246638A0033C839 /* PmDefaults.java in CopyFiles */, - 3DE214371246638F0033C839 /* JPortMidiException.java in CopyFiles */, - 3DE214381246638F0033C839 /* JPortMidiApi.java in CopyFiles */, - 3DE214391246638F0033C839 /* JPortMidi.java in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 89D0F0440F393070007831A7 /* Copy Executable */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 6; - files = ( - 89D0F0410F39306C007831A7 /* JavaApplicationStub in Copy Executable */, - ); - name = "Copy Executable"; - runOnlyForDeploymentPostprocessing = 0; - }; - 89D0F11F0F394189007831A7 /* Copy Java Resources */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 15; - files = ( - 89D0F16A0F3A124E007831A7 /* pmdefaults.jar in Copy Java Resources */, - 3DE216131246AC0E0033C839 /* libpmjni.dylib in Copy Java Resources */, - ); - name = "Copy Java Resources"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 3DE2137B1246538B0033C839 /* PmDefaults.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = PmDefaults.java; path = ../pm_java/pmdefaults/PmDefaults.java; sourceTree = SOURCE_ROOT; }; - 3DE2137D124653CB0033C839 /* PmDefaultsFrame.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = PmDefaultsFrame.java; path = ../pm_java/pmdefaults/PmDefaultsFrame.java; sourceTree = SOURCE_ROOT; }; - 3DE2137E124653FB0033C839 /* portmusic_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = portmusic_logo.png; path = ../pm_java/pmdefaults/portmusic_logo.png; sourceTree = SOURCE_ROOT; }; - 3DE21380124654BC0033C839 /* JPortMidi.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = JPortMidi.java; path = ../pm_java/jportmidi/JPortMidi.java; sourceTree = SOURCE_ROOT; }; - 3DE21381124654CF0033C839 /* JPortMidiApi.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = JPortMidiApi.java; path = ../pm_java/jportmidi/JPortMidiApi.java; sourceTree = SOURCE_ROOT; }; - 3DE21382124654DE0033C839 /* JPortMidiException.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = JPortMidiException.java; path = ../pm_java/jportmidi/JPortMidiException.java; sourceTree = SOURCE_ROOT; }; - 3DE213841246555A0033C839 /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = /System/Library/Frameworks/CoreMIDI.framework; sourceTree = ""; }; - 3DE21390124655760033C839 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; - 3DE213BE1246557F0033C839 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; - 3DE216101246ABE30033C839 /* libpmjni.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpmjni.dylib; path = ../Release/libpmjni.dylib; sourceTree = SOURCE_ROOT; }; - 3DE216901246C6410033C839 /* pmdefaults.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = pmdefaults.icns; path = ../pm_java/pmdefaults/pmdefaults.icns; sourceTree = SOURCE_ROOT; }; - 89C3F2910F5250A300B0048E /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/Credits.rtf; sourceTree = ""; }; - 89D0F0220F392F20007831A7 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; - 89D0F0230F392F20007831A7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 89D0F03E0F39304A007831A7 /* JavaApplicationStub */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = JavaApplicationStub; path = /System/Library/Frameworks/JavaVM.framework/Versions/A/Resources/MacOS/JavaApplicationStub; sourceTree = ""; }; - 89D0F0840F394066007831A7 /* JavaNativeFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaNativeFoundation.framework; path = /System/Library/Frameworks/JavaVM.framework/Versions/A/Frameworks/JavaNativeFoundation.framework; sourceTree = ""; }; - 89D0F1390F3948A9007831A7 /* pmdefaults/make */ = {isa = PBXFileReference; lastKnownFileType = folder; path = pmdefaults/make; sourceTree = ""; }; - 89D0F15D0F3A0FF7007831A7 /* pmdefaults.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = pmdefaults.jar; path = build/Release/pmdefaults.jar; sourceTree = SOURCE_ROOT; }; - 89D0F1860F3A2442007831A7 /* JavaVM.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaVM.framework; path = /System/Library/Frameworks/JavaVM.framework; sourceTree = ""; }; - 8D1107320486CEB800E47090 /* PmDefaults.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PmDefaults.app; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXGroup section */ - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 3DE213841246555A0033C839 /* CoreMIDI.framework */, - 3DE21390124655760033C839 /* CoreFoundation.framework */, - 3DE213BE1246557F0033C839 /* CoreAudio.framework */, - 89D0F1860F3A2442007831A7 /* JavaVM.framework */, - 89D0F0840F394066007831A7 /* JavaNativeFoundation.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 89D0F15D0F3A0FF7007831A7 /* pmdefaults.jar */, - 8D1107320486CEB800E47090 /* PmDefaults.app */, - ); - name = Products; - sourceTree = ""; - }; - 29B97314FDCFA39411CA2CEA /* pmdefaults */ = { - isa = PBXGroup; - children = ( - 3DE216101246ABE30033C839 /* libpmjni.dylib */, - 89D0F0260F392F48007831A7 /* Source */, - 89D0F0200F392F20007831A7 /* Resources */, - 89D0F1390F3948A9007831A7 /* pmdefaults/make */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - ); - name = pmdefaults; - sourceTree = ""; - }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; - 3DE2136A124652E20033C839 /* pm_java */ = { - isa = PBXGroup; - children = ( - 3DE21379124653150033C839 /* pmdefaults */, - 3DE2137A1246531D0033C839 /* jportmidi */, - ); - name = pm_java; - path = ..; - sourceTree = ""; - }; - 3DE21379124653150033C839 /* pmdefaults */ = { - isa = PBXGroup; - children = ( - 3DE2137D124653CB0033C839 /* PmDefaultsFrame.java */, - 3DE2137B1246538B0033C839 /* PmDefaults.java */, - ); - name = pmdefaults; - sourceTree = ""; - }; - 3DE2137A1246531D0033C839 /* jportmidi */ = { - isa = PBXGroup; - children = ( - 3DE21382124654DE0033C839 /* JPortMidiException.java */, - 3DE21381124654CF0033C839 /* JPortMidiApi.java */, - 3DE21380124654BC0033C839 /* JPortMidi.java */, - ); - name = jportmidi; - sourceTree = ""; - }; - 89D0F0200F392F20007831A7 /* Resources */ = { - isa = PBXGroup; - children = ( - 3DE216901246C6410033C839 /* pmdefaults.icns */, - 3DE2137E124653FB0033C839 /* portmusic_logo.png */, - 89C3F2900F5250A300B0048E /* Credits.rtf */, - 89D0F0230F392F20007831A7 /* Info.plist */, - 89D0F0210F392F20007831A7 /* InfoPlist.strings */, - 89D0F03E0F39304A007831A7 /* JavaApplicationStub */, - ); - name = Resources; - path = pmdefaults/resources; - sourceTree = ""; - }; - 89D0F0260F392F48007831A7 /* Source */ = { - isa = PBXGroup; - children = ( - 3DE2136A124652E20033C839 /* pm_java */, - ); - name = Source; - path = pmdefaults/src; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXLegacyTarget section */ - 89D0F0480F393A6F007831A7 /* Compile Java */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "-e -f \"${SRCROOT}/make/build.xml\" -debug \"$ACTION\""; - buildConfigurationList = 89D0F04B0F393AB7007831A7 /* Build configuration list for PBXLegacyTarget "Compile Java" */; - buildPhases = ( - ); - buildToolPath = /usr/bin/ant; - buildWorkingDirectory = ""; - dependencies = ( - 3DE2145E124666900033C839 /* PBXTargetDependency */, - ); - name = "Compile Java"; - passBuildSettingsInEnvironment = 1; - productName = "Compile Java"; - }; -/* End PBXLegacyTarget section */ - -/* Begin PBXNativeTarget section */ - 8D1107260486CEB800E47090 /* Assemble Application */ = { - isa = PBXNativeTarget; - buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Assemble Application" */; - buildPhases = ( - 89D0F0440F393070007831A7 /* Copy Executable */, - 89D0F11F0F394189007831A7 /* Copy Java Resources */, - 8D1107290486CEB800E47090 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "Assemble Application"; - productInstallPath = "$(HOME)/Applications"; - productName = pmdefaults; - productReference = 8D1107320486CEB800E47090 /* PmDefaults.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "pm_mac" */; - compatibilityVersion = "Xcode 3.0"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 29B97314FDCFA39411CA2CEA /* pmdefaults */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 3D634CAB1247805C0020F829 /* JPortMidiHeaders */, - 89D0F1C90F3B704E007831A7 /* PmDefaults */, - 3DE2142D124662AA0033C839 /* CopyJavaSources */, - 89D0F0480F393A6F007831A7 /* Compile Java */, - 8D1107260486CEB800E47090 /* Assemble Application */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D1107290486CEB800E47090 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3DE216951246D57A0033C839 /* pmdefaults.icns in Resources */, - 89D0F0240F392F20007831A7 /* InfoPlist.strings in Resources */, - 89C3F2920F5250A300B0048E /* Credits.rtf in Resources */, - 3DE2137F124653FB0033C839 /* portmusic_logo.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3D634CAA1247805C0020F829 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo BUILT_PRODUCTS_DIR is ${BUILT_PRODUCTS_DIR}\njavah -classpath \"${BUILT_PRODUCTS_DIR}/pmdefaults.jar\" -force -o \"${BUILT_PRODUCTS_DIR}/jportmidi_JportMidiApi.h\" \"jportmidi.JPortMidiApi\"\nmv \"${BUILT_PRODUCTS_DIR}/jportmidi_JportMidiApi.h\" ../pm_java/pmjni/\necho \"Created ../pm_java/pmjni/jportmidi_JportMidiApi.h\"\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 3D634CB0124781580020F829 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 89D0F1C90F3B704E007831A7 /* PmDefaults */; - targetProxy = 3D634CAF124781580020F829 /* PBXContainerItemProxy */; - }; - 3DE21431124662C50033C839 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3DE2142D124662AA0033C839 /* CopyJavaSources */; - targetProxy = 3DE21430124662C50033C839 /* PBXContainerItemProxy */; - }; - 3DE2145E124666900033C839 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 3DE2142D124662AA0033C839 /* CopyJavaSources */; - targetProxy = 3DE2145D124666900033C839 /* PBXContainerItemProxy */; - }; - 89D0F1CD0F3B7062007831A7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 8D1107260486CEB800E47090 /* Assemble Application */; - targetProxy = 89D0F1CC0F3B7062007831A7 /* PBXContainerItemProxy */; - }; - 89D0F1D10F3B7062007831A7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 89D0F0480F393A6F007831A7 /* Compile Java */; - targetProxy = 89D0F1D00F3B7062007831A7 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 89C3F2900F5250A300B0048E /* Credits.rtf */ = { - isa = PBXVariantGroup; - children = ( - 89C3F2910F5250A300B0048E /* English */, - ); - name = Credits.rtf; - sourceTree = ""; - }; - 89D0F0210F392F20007831A7 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 89D0F0220F392F20007831A7 /* English */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 3D634CAC1247805C0020F829 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - PRODUCT_NAME = JPortMidiHeaders; - }; - name = Debug; - }; - 3D634CAD1247805C0020F829 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PRODUCT_NAME = JPortMidiHeaders; - ZERO_LINK = NO; - }; - name = Release; - }; - 3DE2142E124662AB0033C839 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - PRODUCT_NAME = CopyJavaSources; - }; - name = Debug; - }; - 3DE2142F124662AB0033C839 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - PRODUCT_NAME = CopyJavaSources; - ZERO_LINK = NO; - }; - name = Release; - }; - 89D0F0490F393A6F007831A7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = pmdefaults; - SRCROOT = ./pmdefaults; - }; - name = Debug; - }; - 89D0F04A0F393A6F007831A7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = pmdefaults; - SRCROOT = ./pmdefaults; - }; - name = Release; - }; - 89D0F1CA0F3B704F007831A7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = pmdefaults; - }; - name = Debug; - }; - 89D0F1CB0F3B704F007831A7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = pmdefaults; - }; - name = Release; - }; - C01FCF4B08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CONFIGURATION_BUILD_DIR = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - COPY_PHASE_STRIP = NO; - INFOPLIST_FILE = pmdefaults/resources/Info.plist; - INSTALL_PATH = "$(HOME)/Applications"; - PRODUCT_NAME = pmdefaults; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - C01FCF4C08A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CONFIGURATION_BUILD_DIR = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - INFOPLIST_FILE = pmdefaults/resources/Info.plist; - INSTALL_PATH = "$(HOME)/Applications"; - PRODUCT_NAME = PmDefaults; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; - C01FCF4F08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - }; - name = Debug; - }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 3D634CAE1247807A0020F829 /* Build configuration list for PBXAggregateTarget "JPortMidiHeaders" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3D634CAC1247805C0020F829 /* Debug */, - 3D634CAD1247805C0020F829 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3DE21434124662FF0033C839 /* Build configuration list for PBXAggregateTarget "CopyJavaSources" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3DE2142E124662AB0033C839 /* Debug */, - 3DE2142F124662AB0033C839 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 89D0F04B0F393AB7007831A7 /* Build configuration list for PBXLegacyTarget "Compile Java" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 89D0F0490F393A6F007831A7 /* Debug */, - 89D0F04A0F393A6F007831A7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 89D0F1D20F3B7080007831A7 /* Build configuration list for PBXAggregateTarget "PmDefaults" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 89D0F1CA0F3B704F007831A7 /* Debug */, - 89D0F1CB0F3B704F007831A7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Assemble Application" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4B08A954540054247B /* Debug */, - C01FCF4C08A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "pm_mac" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 570e6faa82..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.xcworkspace/xcuserdata/VKamyshniy.xcuserdatad/UserInterfaceState.xcuserstate b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.xcworkspace/xcuserdata/VKamyshniy.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 104c0fe910..0000000000 Binary files a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/project.xcworkspace/xcuserdata/VKamyshniy.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Assemble Application.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Assemble Application.xcscheme deleted file mode 100644 index b2051a67b0..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Assemble Application.xcscheme +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Compile Java.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Compile Java.xcscheme deleted file mode 100644 index 415b487914..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/Compile Java.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/CopyJavaSources.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/CopyJavaSources.xcscheme deleted file mode 100644 index ad37276ccc..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/CopyJavaSources.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme deleted file mode 100644 index de0f0bcef7..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/PmDefaults.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/PmDefaults.xcscheme deleted file mode 100644 index 23d63e9bac..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/PmDefaults.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/xcschememanagement.plist b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index a57f870bb5..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/VKamyshniy.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - SchemeUserState - - Assemble Application.xcscheme - - orderHint - 4 - - Compile Java.xcscheme - - orderHint - 3 - - CopyJavaSources.xcscheme - - orderHint - 2 - - JPortMidiHeaders.xcscheme - - orderHint - 0 - - PmDefaults.xcscheme - - orderHint - 1 - - - SuppressBuildableAutocreation - - 3D634CAB1247805C0020F829 - - primary - - - 3DE2142D124662AA0033C839 - - primary - - - 89D0F0480F393A6F007831A7 - - primary - - - 89D0F1C90F3B704E007831A7 - - primary - - - 8D1107260486CEB800E47090 - - primary - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Assemble Application.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Assemble Application.xcscheme deleted file mode 100644 index b2051a67b0..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Assemble Application.xcscheme +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Compile Java.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Compile Java.xcscheme deleted file mode 100644 index 415b487914..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/Compile Java.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/CopyJavaSources.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/CopyJavaSources.xcscheme deleted file mode 100644 index ad37276ccc..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/CopyJavaSources.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme deleted file mode 100644 index de0f0bcef7..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/JPortMidiHeaders.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/PmDefaults.xcscheme b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/PmDefaults.xcscheme deleted file mode 100644 index 23d63e9bac..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/PmDefaults.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/xcschememanagement.plist b/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 4c011dee54..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pm_mac.xcodeproj/xcuserdata/gzharun.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - SchemeUserState - - Assemble Application.xcscheme - - orderHint - 5 - - Compile Java.xcscheme - - orderHint - 4 - - CopyJavaSources.xcscheme - - orderHint - 3 - - JPortMidiHeaders.xcscheme - - orderHint - 1 - - PmDefaults.xcscheme - - orderHint - 2 - - - SuppressBuildableAutocreation - - 3D634CAB1247805C0020F829 - - primary - - - 3DE2142D124662AA0033C839 - - primary - - - 89D0F0480F393A6F007831A7 - - primary - - - 89D0F1C90F3B704E007831A7 - - primary - - - 8D1107260486CEB800E47090 - - primary - - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/make/build.xml b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/make/build.xml deleted file mode 100644 index bd08c68208..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/make/build.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "Nothing to do for install-headers phase" - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/make/find-classrefs.sh b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/make/find-classrefs.sh deleted file mode 100755 index 2217580d0d..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/make/find-classrefs.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -# Prints all class references made by all classes in a Jar file -# Depends on the output formatting of javap - -# create a temporary working directory -dir=`mktemp -d $TMPDIR/classrefs.XXXXXX` - -asm_dump="$dir/asm_dump" -all_classes="$dir/all_classes" - -# for each class in a Jar file, dump the full assembly -javap -c -classpath "$1" `/usr/bin/jar tf "$1" | grep "\.class" | sort | xargs | sed -e 's/\.class//g'` > $asm_dump - -# dump the initial list of all classes in the Jar file -/usr/bin/jar tf $1 | grep "\.class" | sed -e 's/\.class//g' >> $all_classes - -# dump all static class references -cat $asm_dump | grep //class | awk -F"//class " '{print $2}' | sort | uniq >> $all_classes - -# dump all references to classes made in methods -cat $asm_dump | grep //Method | awk -F"//Method " '{print $2}' | sort | uniq | grep "\." | awk -F"." '{print $1}' | sort | uniq >> $all_classes - -# dump all references to classes by direct field access -cat $asm_dump | grep //Field | awk -F"//Field " '{print $2}' | sort | uniq | grep "\:L" | awk -F"\:L" '{print $2}' | sort | uniq | awk -F"\;" '{print $1}' >> $all_classes - -# sort and reformat -sort $all_classes | uniq | grep -v "\"" | sed -e 's/\//\./g' - -# cleanup -rm -rf $dir diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/English.lproj/Credits.rtf b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/English.lproj/Credits.rtf deleted file mode 100644 index 18f83781e7..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/English.lproj/Credits.rtf +++ /dev/null @@ -1,14 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural - -\f0\b\fs24 \cf0 Author: -\b0 \ - Roger B. Dannenberg\ -\ - -\b With special thanks to: -\b0 \ - National Science Foundation\ -} \ No newline at end of file diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/English.lproj/InfoPlist.strings b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/English.lproj/InfoPlist.strings deleted file mode 100644 index 7c414663d0..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/English.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Localized versions of Info.plist keys */ - -NSHumanReadableCopyright = "© Carnegie Mellon University, 2010"; \ No newline at end of file diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/Info.plist b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/Info.plist deleted file mode 100644 index 58bedb4501..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/Info.plist +++ /dev/null @@ -1,40 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - JavaApplicationStub - CFBundleIconFile - pmdefaults.icns - CFBundleIdentifier - - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - PmDefaults - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - 1.0 - CFBundleShortVersionString - 1.0 - Java - - ClassPath - $JAVAROOT/pmdefaults.jar - JVMVersion - 1.5+ - MainClass - pmdefaults.PmDefaults - Properties - - apple.laf.useScreenMenuBar - true - - - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/Manifest b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/Manifest deleted file mode 100644 index 5dee9b0dc1..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmdefaults/resources/Manifest +++ /dev/null @@ -1 +0,0 @@ -Main-Class: pmdefaults/PmDefaults diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmac.c b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmac.c deleted file mode 100644 index 8e049fa21f..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmac.c +++ /dev/null @@ -1,59 +0,0 @@ -/* pmmac.c -- PortMidi os-dependent code */ - -/* This file only needs to implement: -pm_init(), which calls various routines to register the -available midi devices, -Pm_GetDefaultInputDeviceID(), and -Pm_GetDefaultOutputDeviceID(). -It is seperate from pmmacosxcm because we might want to register -non-CoreMIDI devices. -*/ - -#include "stdlib.h" -#include "portmidi.h" -#include "pmutil.h" -#include "pminternal.h" -#include "pmmacosxcm.h" - -PmDeviceID pm_default_input_device_id = -1; -PmDeviceID pm_default_output_device_id = -1; - -void pm_init() -{ - PmError err = pm_macosxcm_init(); - // this is set when we return to Pm_Initialize, but we need it - // now in order to (successfully) call Pm_CountDevices() - pm_initialized = TRUE; - if (!err) { - pm_default_input_device_id = find_default_device( - "/PortMidi/PM_RECOMMENDED_INPUT_DEVICE", TRUE, - pm_default_input_device_id); - pm_default_output_device_id = find_default_device( - "/PortMidi/PM_RECOMMENDED_OUTPUT_DEVICE", FALSE, - pm_default_output_device_id); - } -} - - -void pm_term(void) -{ - pm_macosxcm_term(); -} - - -PmDeviceID Pm_GetDefaultInputDeviceID() -{ - Pm_Initialize(); - return pm_default_input_device_id; -} - -PmDeviceID Pm_GetDefaultOutputDeviceID() { - Pm_Initialize(); - return pm_default_output_device_id; -} - -void *pm_alloc(size_t s) { return malloc(s); } - -void pm_free(void *ptr) { free(ptr); } - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmac.h b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmac.h deleted file mode 100644 index 6b64fff2a9..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmac.h +++ /dev/null @@ -1,4 +0,0 @@ -/* pmmac.h */ - -extern PmDeviceID pm_default_input_device_id; -extern PmDeviceID pm_default_output_device_id; diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmacosxcm.c b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmacosxcm.c deleted file mode 100644 index 6432d2b55d..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmacosxcm.c +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * Platform interface to the MacOS X CoreMIDI framework - * - * Jon Parise - * and subsequent work by Andrew Zeldis and Zico Kolter - * and Roger B. Dannenberg - * - * $Id: pmmacosx.c,v 1.17 2002/01/27 02:40:40 jon Exp $ - */ - -/* Notes: - since the input and output streams are represented by MIDIEndpointRef - values and almost no other state, we store the MIDIEndpointRef on - descriptors[midi->device_id].descriptor. The only other state we need - is for errors: we need to know if there is an error and if so, what is - the error text. We use a structure with two kinds of - host error: "error" and "callback_error". That way, asynchronous callbacks - do not interfere with other error information. - - OS X does not seem to have an error-code-to-text function, so we will - just use text messages instead of error codes. - */ - -#include - -//#define CM_DEBUG 1 - -#include "portmidi.h" -#include "pmutil.h" -#include "pminternal.h" -#include "porttime.h" -#include "pmmac.h" -#include "pmmacosxcm.h" - -#include -#include - -#include -#include -#include -#include - -#define PACKET_BUFFER_SIZE 1024 -/* maximum overall data rate (OS X limit is 15000 bytes/second) */ -#define MAX_BYTES_PER_S 14000 - -/* Apple reports that packets are dropped when the MIDI bytes/sec - exceeds 15000. This is computed by "tracking the number of MIDI - bytes scheduled into 1-second buckets over the last six seconds - and averaging these counts." - - This is apparently based on timestamps, not on real time, so - we have to avoid constructing packets that schedule high speed - output even if the actual writes are delayed (which was my first - solution). - - The LIMIT_RATE symbol, if defined, enables code to modify - timestamps as follows: - After each packet is formed, the next allowable timestamp is - computed as this_packet_time + this_packet_len * delay_per_byte - - This is the minimum timestamp allowed in the next packet. - - Note that this distorts accurate timestamps somewhat. - */ -#define LIMIT_RATE 1 - -#define SYSEX_BUFFER_SIZE 128 - -#define VERBOSE_ON 1 -#define VERBOSE if (VERBOSE_ON) - -#define MIDI_SYSEX 0xf0 -#define MIDI_EOX 0xf7 -#define MIDI_STATUS_MASK 0x80 - -// "Ref"s are pointers on 32-bit machines and ints on 64 bit machines -// NULL_REF is our representation of either 0 or NULL -#ifdef __LP64__ -#define NULL_REF 0 -#else -#define NULL_REF NULL -#endif - -static MIDIClientRef client = NULL_REF; /* Client handle to the MIDI server */ -static MIDIPortRef portIn = NULL_REF; /* Input port handle */ -static MIDIPortRef portOut = NULL_REF; /* Output port handle */ - -extern pm_fns_node pm_macosx_in_dictionary; -extern pm_fns_node pm_macosx_out_dictionary; - -typedef struct midi_macosxcm_struct { - PmTimestamp sync_time; /* when did we last determine delta? */ - UInt64 delta; /* difference between stream time and real time in ns */ - UInt64 last_time; /* last output time in host units*/ - int first_message; /* tells midi_write to sychronize timestamps */ - int sysex_mode; /* middle of sending sysex */ - uint32_t sysex_word; /* accumulate data when receiving sysex */ - uint32_t sysex_byte_count; /* count how many received */ - char error[PM_HOST_ERROR_MSG_LEN]; - char callback_error[PM_HOST_ERROR_MSG_LEN]; - Byte packetBuffer[PACKET_BUFFER_SIZE]; - MIDIPacketList *packetList; /* a pointer to packetBuffer */ - MIDIPacket *packet; - Byte sysex_buffer[SYSEX_BUFFER_SIZE]; /* temp storage for sysex data */ - MIDITimeStamp sysex_timestamp; /* timestamp to use with sysex data */ - /* allow for running status (is running status possible here? -rbd): -cpr */ - unsigned char last_command; - int32_t last_msg_length; - /* limit midi data rate (a CoreMidi requirement): */ - UInt64 min_next_time; /* when can the next send take place? */ - int byte_count; /* how many bytes in the next packet list? */ - Float64 us_per_host_tick; /* host clock frequency, units of min_next_time */ - UInt64 host_ticks_per_byte; /* host clock units per byte at maximum rate */ -} midi_macosxcm_node, *midi_macosxcm_type; - -/* private function declarations */ -MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp); -PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp); - -char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint); - - -static int -midi_length(int32_t msg) -{ - int status, high, low; - static int high_lengths[] = { - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 through 0x70 */ - 3, 3, 3, 3, 2, 2, 3, 1 /* 0x80 through 0xf0 */ - }; - static int low_lengths[] = { - 1, 2, 3, 2, 1, 1, 1, 1, /* 0xf0 through 0xf8 */ - 1, 1, 1, 1, 1, 1, 1, 1 /* 0xf9 through 0xff */ - }; - - status = msg & 0xFF; - high = status >> 4; - low = status & 15; - - return (high != 0xF) ? high_lengths[high] : low_lengths[low]; -} - -static PmTimestamp midi_synchronize(PmInternal *midi) -{ - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - UInt64 pm_stream_time_2 = - AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); - PmTimestamp real_time; - UInt64 pm_stream_time; - /* if latency is zero and this is an output, there is no - time reference and midi_synchronize should never be called */ - assert(midi->time_proc); - assert(!(midi->write_flag && midi->latency == 0)); - do { - /* read real_time between two reads of stream time */ - pm_stream_time = pm_stream_time_2; - real_time = (*midi->time_proc)(midi->time_info); - pm_stream_time_2 = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); - /* repeat if more than 0.5 ms has elapsed */ - } while (pm_stream_time_2 > pm_stream_time + 500000); - m->delta = pm_stream_time - ((UInt64) real_time * (UInt64) 1000000); - m->sync_time = real_time; - return real_time; -} - - -static void -process_packet(MIDIPacket *packet, PmEvent *event, - PmInternal *midi, midi_macosxcm_type m) -{ - /* handle a packet of MIDI messages from CoreMIDI */ - /* there may be multiple short messages in one packet (!) */ - unsigned int remaining_length = packet->length; - unsigned char *cur_packet_data = packet->data; - while (remaining_length > 0) { - if (cur_packet_data[0] == MIDI_SYSEX || - /* are we in the middle of a sysex message? */ - (m->last_command == 0 && - !(cur_packet_data[0] & MIDI_STATUS_MASK))) { - m->last_command = 0; /* no running status */ - unsigned int amt = pm_read_bytes(midi, cur_packet_data, - remaining_length, - event->timestamp); - remaining_length -= amt; - cur_packet_data += amt; - } else if (cur_packet_data[0] == MIDI_EOX) { - /* this should never happen, because pm_read_bytes should - * get and read all EOX bytes*/ - midi->sysex_in_progress = FALSE; - m->last_command = 0; - } else if (cur_packet_data[0] & MIDI_STATUS_MASK) { - /* compute the length of the next (short) msg in packet */ - unsigned int cur_message_length = midi_length(cur_packet_data[0]); - if (cur_message_length > remaining_length) { -#ifdef DEBUG - printf("PortMidi debug msg: not enough data"); -#endif - /* since there's no more data, we're done */ - return; - } - m->last_msg_length = cur_message_length; - m->last_command = cur_packet_data[0]; - switch (cur_message_length) { - case 1: - event->message = Pm_Message(cur_packet_data[0], 0, 0); - break; - case 2: - event->message = Pm_Message(cur_packet_data[0], - cur_packet_data[1], 0); - break; - case 3: - event->message = Pm_Message(cur_packet_data[0], - cur_packet_data[1], - cur_packet_data[2]); - break; - default: - /* PortMIDI internal error; should never happen */ - assert(cur_message_length == 1); - return; /* give up on packet if continued after assert */ - } - pm_read_short(midi, event); - remaining_length -= m->last_msg_length; - cur_packet_data += m->last_msg_length; - } else if (m->last_msg_length > remaining_length + 1) { - /* we have running status, but not enough data */ -#ifdef DEBUG - printf("PortMidi debug msg: not enough data in CoreMIDI packet"); -#endif - /* since there's no more data, we're done */ - return; - } else { /* output message using running status */ - switch (m->last_msg_length) { - case 1: - event->message = Pm_Message(m->last_command, 0, 0); - break; - case 2: - event->message = Pm_Message(m->last_command, - cur_packet_data[0], 0); - break; - case 3: - event->message = Pm_Message(m->last_command, - cur_packet_data[0], - cur_packet_data[1]); - break; - default: - /* last_msg_length is invalid -- internal PortMIDI error */ - assert(m->last_msg_length == 1); - } - pm_read_short(midi, event); - remaining_length -= (m->last_msg_length - 1); - cur_packet_data += (m->last_msg_length - 1); - } - } -} - - - -/* called when MIDI packets are received */ -static void -readProc(const MIDIPacketList *newPackets, void *refCon, void *connRefCon) -{ - PmInternal *midi; - midi_macosxcm_type m; - PmEvent event; - MIDIPacket *packet; - unsigned int packetIndex; - uint32_t now; - unsigned int status; - -#ifdef CM_DEBUG - printf("readProc: numPackets %d: ", newPackets->numPackets); -#endif - - /* Retrieve the context for this connection */ - midi = (PmInternal *) connRefCon; - m = (midi_macosxcm_type) midi->descriptor; - assert(m); - - /* synchronize time references every 100ms */ - now = (*midi->time_proc)(midi->time_info); - if (m->first_message || m->sync_time + 100 /*ms*/ < now) { - /* time to resync */ - now = midi_synchronize(midi); - m->first_message = FALSE; - } - - packet = (MIDIPacket *) &newPackets->packet[0]; - /* printf("readproc packet status %x length %d\n", packet->data[0], - packet->length); */ - for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) { - /* Set the timestamp and dispatch this message */ - event.timestamp = (PmTimestamp) /* explicit conversion */ ( - (AudioConvertHostTimeToNanos(packet->timeStamp) - m->delta) / - (UInt64) 1000000); - status = packet->data[0]; - /* process packet as sysex data if it begins with MIDI_SYSEX, or - MIDI_EOX or non-status byte with no running status */ -#ifdef CM_DEBUG - printf(" %d", packet->length); -#endif - if (status == MIDI_SYSEX || status == MIDI_EOX || - ((!(status & MIDI_STATUS_MASK)) && !m->last_command)) { - /* previously was: !(status & MIDI_STATUS_MASK)) { - * but this could mistake running status for sysex data - */ - /* reset running status data -cpr */ - m->last_command = 0; - m->last_msg_length = 0; - /* printf("sysex packet length: %d\n", packet->length); */ - pm_read_bytes(midi, packet->data, packet->length, event.timestamp); - } else { - process_packet(packet, &event, midi, m); - } - packet = MIDIPacketNext(packet); - } -#ifdef CM_DEBUG - printf("\n"); -#endif -} - -static PmError -midi_in_open(PmInternal *midi, void *driverInfo) -{ - MIDIEndpointRef endpoint; - midi_macosxcm_type m; - OSStatus macHostError; - - /* insure that we have a time_proc for timing */ - if (midi->time_proc == NULL) { - if (!Pt_Started()) - Pt_Start(1, 0, 0); - /* time_get does not take a parameter, so coerce */ - midi->time_proc = (PmTimeProcPtr) Pt_Time; - } - endpoint = (MIDIEndpointRef) (long) descriptors[midi->device_id].descriptor; - if (endpoint == NULL_REF) { - return pmInvalidDeviceId; - } - - m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */ - midi->descriptor = m; - if (!m) { - return pmInsufficientMemory; - } - m->error[0] = 0; - m->callback_error[0] = 0; - m->sync_time = 0; - m->delta = 0; - m->last_time = 0; - m->first_message = TRUE; - m->sysex_mode = FALSE; - m->sysex_word = 0; - m->sysex_byte_count = 0; - m->packetList = NULL; - m->packet = NULL; - m->last_command = 0; - m->last_msg_length = 0; - - macHostError = MIDIPortConnectSource(portIn, endpoint, midi); - if (macHostError != noErr) { - pm_hosterror = macHostError; - sprintf(pm_hosterror_text, - "Host error %ld: MIDIPortConnectSource() in midi_in_open()", - (long) macHostError); - midi->descriptor = NULL; - pm_free(m); - return pmHostError; - } - - return pmNoError; -} - -static PmError -midi_in_close(PmInternal *midi) -{ - MIDIEndpointRef endpoint; - OSStatus macHostError; - PmError err = pmNoError; - - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - - if (!m) return pmBadPtr; - - endpoint = (MIDIEndpointRef) (long) descriptors[midi->device_id].descriptor; - if (endpoint == NULL_REF) { - pm_hosterror = pmBadPtr; - } - - /* shut off the incoming messages before freeing data structures */ - macHostError = MIDIPortDisconnectSource(portIn, endpoint); - if (macHostError != noErr) { - pm_hosterror = macHostError; - sprintf(pm_hosterror_text, - "Host error %ld: MIDIPortDisconnectSource() in midi_in_close()", - (long) macHostError); - err = pmHostError; - } - - midi->descriptor = NULL; - pm_free(midi->descriptor); - - return err; -} - - -static PmError -midi_out_open(PmInternal *midi, void *driverInfo) -{ - midi_macosxcm_type m; - - m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */ - midi->descriptor = m; - if (!m) { - return pmInsufficientMemory; - } - m->error[0] = 0; - m->callback_error[0] = 0; - m->sync_time = 0; - m->delta = 0; - m->last_time = 0; - m->first_message = TRUE; - m->sysex_mode = FALSE; - m->sysex_word = 0; - m->sysex_byte_count = 0; - m->packetList = (MIDIPacketList *) m->packetBuffer; - m->packet = NULL; - m->last_command = 0; - m->last_msg_length = 0; - m->min_next_time = 0; - m->byte_count = 0; - m->us_per_host_tick = 1000000.0 / AudioGetHostClockFrequency(); - m->host_ticks_per_byte = (UInt64) (1000000.0 / - (m->us_per_host_tick * MAX_BYTES_PER_S)); - return pmNoError; -} - - -static PmError -midi_out_close(PmInternal *midi) -{ - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - if (!m) return pmBadPtr; - - midi->descriptor = NULL; - pm_free(midi->descriptor); - - return pmNoError; -} - -static PmError -midi_abort(PmInternal *midi) -{ - PmError err = pmNoError; - OSStatus macHostError; - MIDIEndpointRef endpoint = - (MIDIEndpointRef) (long) descriptors[midi->device_id].descriptor; - macHostError = MIDIFlushOutput(endpoint); - if (macHostError != noErr) { - pm_hosterror = macHostError; - sprintf(pm_hosterror_text, - "Host error %ld: MIDIFlushOutput()", (long) macHostError); - err = pmHostError; - } - return err; -} - - -static PmError -midi_write_flush(PmInternal *midi, PmTimestamp timestamp) -{ - OSStatus macHostError; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - MIDIEndpointRef endpoint = - (MIDIEndpointRef) (long) descriptors[midi->device_id].descriptor; - assert(m); - assert(endpoint); - if (m->packet != NULL) { - /* out of space, send the buffer and start refilling it */ - /* before we can send, maybe delay to limit data rate. OS X allows - * 15KB/s. */ - UInt64 now = AudioGetCurrentHostTime(); - if (now < m->min_next_time) { - usleep((useconds_t) - ((m->min_next_time - now) * m->us_per_host_tick)); - } - macHostError = MIDISend(portOut, endpoint, m->packetList); - m->packet = NULL; /* indicate no data in packetList now */ - m->min_next_time = now + m->byte_count * m->host_ticks_per_byte; - m->byte_count = 0; - if (macHostError != noErr) goto send_packet_error; - } - return pmNoError; - -send_packet_error: - pm_hosterror = macHostError; - sprintf(pm_hosterror_text, - "Host error %ld: MIDISend() in midi_write()", - (long) macHostError); - return pmHostError; - -} - - -static PmError -send_packet(PmInternal *midi, Byte *message, unsigned int messageLength, - MIDITimeStamp timestamp) -{ - PmError err; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - assert(m); - - /* printf("add %d to packet %p len %d\n", message[0], m->packet, messageLength); */ - m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), - m->packet, timestamp, messageLength, - message); - m->byte_count += messageLength; - if (m->packet == NULL) { - /* out of space, send the buffer and start refilling it */ - /* make midi->packet non-null to fool midi_write_flush into sending */ - m->packet = (MIDIPacket *) 4; - /* timestamp is 0 because midi_write_flush ignores timestamp since - * timestamps are already in packets. The timestamp parameter is here - * because other API's need it. midi_write_flush can be called - * from system-independent code that must be cross-API. - */ - if ((err = midi_write_flush(midi, 0)) != pmNoError) return err; - m->packet = MIDIPacketListInit(m->packetList); - assert(m->packet); /* if this fails, it's a programming error */ - m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), - m->packet, timestamp, messageLength, - message); - assert(m->packet); /* can't run out of space on first message */ - } - return pmNoError; -} - - -static PmError -midi_write_short(PmInternal *midi, PmEvent *event) -{ - PmTimestamp when = event->timestamp; - PmMessage what = event->message; - MIDITimeStamp timestamp; - UInt64 when_ns; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - Byte message[4]; - unsigned int messageLength; - - if (m->packet == NULL) { - m->packet = MIDIPacketListInit(m->packetList); - /* this can never fail, right? failure would indicate something - unrecoverable */ - assert(m->packet); - } - - /* compute timestamp */ - if (when == 0) when = midi->now; - /* if latency == 0, midi->now is not valid. We will just set it to zero */ - if (midi->latency == 0) when = 0; - when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta; - timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns); - - message[0] = Pm_MessageStatus(what); - message[1] = Pm_MessageData1(what); - message[2] = Pm_MessageData2(what); - messageLength = midi_length(what); - - /* make sure we go foreward in time */ - if (timestamp < m->min_next_time) timestamp = m->min_next_time; - - #ifdef LIMIT_RATE - if (timestamp < m->last_time) - timestamp = m->last_time; - m->last_time = timestamp + messageLength * m->host_ticks_per_byte; - #endif - - /* Add this message to the packet list */ - return send_packet(midi, message, messageLength, timestamp); -} - - -static PmError -midi_begin_sysex(PmInternal *midi, PmTimestamp when) -{ - UInt64 when_ns; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - assert(m); - m->sysex_byte_count = 0; - - /* compute timestamp */ - if (when == 0) when = midi->now; - /* if latency == 0, midi->now is not valid. We will just set it to zero */ - if (midi->latency == 0) when = 0; - when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta; - m->sysex_timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns); - - if (m->packet == NULL) { - m->packet = MIDIPacketListInit(m->packetList); - /* this can never fail, right? failure would indicate something - unrecoverable */ - assert(m->packet); - } - return pmNoError; -} - - -static PmError -midi_end_sysex(PmInternal *midi, PmTimestamp when) -{ - PmError err; - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - assert(m); - - /* make sure we go foreward in time */ - if (m->sysex_timestamp < m->min_next_time) - m->sysex_timestamp = m->min_next_time; - - #ifdef LIMIT_RATE - if (m->sysex_timestamp < m->last_time) - m->sysex_timestamp = m->last_time; - m->last_time = m->sysex_timestamp + m->sysex_byte_count * - m->host_ticks_per_byte; - #endif - - /* now send what's in the buffer */ - err = send_packet(midi, m->sysex_buffer, m->sysex_byte_count, - m->sysex_timestamp); - m->sysex_byte_count = 0; - if (err != pmNoError) { - m->packet = NULL; /* flush everything in the packet list */ - return err; - } - return pmNoError; -} - - -static PmError -midi_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp) -{ - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - assert(m); - if (m->sysex_byte_count >= SYSEX_BUFFER_SIZE) { - PmError err = midi_end_sysex(midi, timestamp); - if (err != pmNoError) return err; - } - m->sysex_buffer[m->sysex_byte_count++] = byte; - return pmNoError; -} - - -static PmError -midi_write_realtime(PmInternal *midi, PmEvent *event) -{ - /* to send a realtime message during a sysex message, first - flush all pending sysex bytes into packet list */ - PmError err = midi_end_sysex(midi, 0); - if (err != pmNoError) return err; - /* then we can just do a normal midi_write_short */ - return midi_write_short(midi, event); -} - -static unsigned int midi_has_host_error(PmInternal *midi) -{ - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - return (m->callback_error[0] != 0) || (m->error[0] != 0); -} - - -static void midi_get_host_error(PmInternal *midi, char *msg, unsigned int len) -{ - midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; - msg[0] = 0; /* initialize to empty string */ - if (m) { /* make sure there is an open device to examine */ - if (m->error[0]) { - strncpy(msg, m->error, len); - m->error[0] = 0; /* clear the error */ - } else if (m->callback_error[0]) { - strncpy(msg, m->callback_error, len); - m->callback_error[0] = 0; /* clear the error */ - } - msg[len - 1] = 0; /* make sure string is terminated */ - } -} - - -MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) -{ - UInt64 nanos; - if (timestamp <= 0) { - return (MIDITimeStamp)0; - } else { - nanos = (UInt64)timestamp * (UInt64)1000000; - return (MIDITimeStamp)AudioConvertNanosToHostTime(nanos); - } -} - -PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp) -{ - UInt64 nanos; - nanos = AudioConvertHostTimeToNanos(timestamp); - return (PmTimestamp)(nanos / (UInt64)1000000); -} - - -// -// Code taken from http://developer.apple.com/qa/qa2004/qa1374.html -////////////////////////////////////// -// Obtain the name of an endpoint without regard for whether it has connections. -// The result should be released by the caller. -CFStringRef EndpointName(MIDIEndpointRef endpoint, bool isExternal) -{ - CFMutableStringRef result = CFStringCreateMutable(NULL, 0); - CFStringRef str; - - // begin with the endpoint's name - str = NULL; - MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &str); - if (str != NULL) { - CFStringAppend(result, str); - CFRelease(str); - } - - MIDIEntityRef entity = NULL_REF; - MIDIEndpointGetEntity(endpoint, &entity); - if (entity == NULL_REF) - // probably virtual - return result; - - if (CFStringGetLength(result) == 0) { - // endpoint name has zero length -- try the entity - str = NULL; - MIDIObjectGetStringProperty(entity, kMIDIPropertyName, &str); - if (str != NULL) { - CFStringAppend(result, str); - CFRelease(str); - } - } - // now consider the device's name - MIDIDeviceRef device = NULL_REF; - MIDIEntityGetDevice(entity, &device); - if (device == NULL_REF) - return result; - - str = NULL; - MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str); - if (CFStringGetLength(result) == 0) { - CFRelease(result); - return str; - } - if (str != NULL) { - // if an external device has only one entity, throw away - // the endpoint name and just use the device name - if (isExternal && MIDIDeviceGetNumberOfEntities(device) < 2) { - CFRelease(result); - return str; - } else { - if (CFStringGetLength(str) == 0) { - CFRelease(str); - return result; - } - // does the entity name already start with the device name? - // (some drivers do this though they shouldn't) - // if so, do not prepend - if (CFStringCompareWithOptions( result, /* endpoint name */ - str /* device name */, - CFRangeMake(0, CFStringGetLength(str)), 0) != kCFCompareEqualTo) { - // prepend the device name to the entity name - if (CFStringGetLength(result) > 0) - CFStringInsert(result, 0, CFSTR(" ")); - CFStringInsert(result, 0, str); - } - CFRelease(str); - } - } - return result; -} - - -// Obtain the name of an endpoint, following connections. -// The result should be released by the caller. -static CFStringRef ConnectedEndpointName(MIDIEndpointRef endpoint) -{ - CFMutableStringRef result = CFStringCreateMutable(NULL, 0); - CFStringRef str; - OSStatus err; - long i; - - // Does the endpoint have connections? - CFDataRef connections = NULL; - long nConnected = 0; - bool anyStrings = false; - err = MIDIObjectGetDataProperty(endpoint, kMIDIPropertyConnectionUniqueID, &connections); - if (connections != NULL) { - // It has connections, follow them - // Concatenate the names of all connected devices - nConnected = CFDataGetLength(connections) / (int32_t) sizeof(MIDIUniqueID); - if (nConnected) { - const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections)); - for (i = 0; i < nConnected; ++i, ++pid) { - MIDIUniqueID id = EndianS32_BtoN(*pid); - MIDIObjectRef connObject; - MIDIObjectType connObjectType; - err = MIDIObjectFindByUniqueID(id, &connObject, &connObjectType); - if (err == noErr) { - if (connObjectType == kMIDIObjectType_ExternalSource || - connObjectType == kMIDIObjectType_ExternalDestination) { - // Connected to an external device's endpoint (10.3 and later). - str = EndpointName((MIDIEndpointRef)(connObject), true); - } else { - // Connected to an external device (10.2) (or something else, catch-all) - str = NULL; - MIDIObjectGetStringProperty(connObject, kMIDIPropertyName, &str); - } - if (str != NULL) { - if (anyStrings) - CFStringAppend(result, CFSTR(", ")); - else anyStrings = true; - CFStringAppend(result, str); - CFRelease(str); - } - } - } - } - CFRelease(connections); - } - if (anyStrings) - return result; - - // Here, either the endpoint had no connections, or we failed to obtain names for any of them. - return EndpointName(endpoint, false); -} - - -char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint) -{ -#ifdef OLDCODE - MIDIEntityRef entity; - MIDIDeviceRef device; - - CFStringRef endpointName = NULL; - CFStringRef deviceName = NULL; -#endif - CFStringRef fullName = NULL; - CFStringEncoding defaultEncoding; - char* newName; - - /* get the default string encoding */ - defaultEncoding = CFStringGetSystemEncoding(); - - fullName = ConnectedEndpointName(endpoint); - -#ifdef OLDCODE - /* get the entity and device info */ - MIDIEndpointGetEntity(endpoint, &entity); - MIDIEntityGetDevice(entity, &device); - - /* create the nicely formated name */ - MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &endpointName); - MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName); - if (deviceName != NULL) { - fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"), - deviceName, endpointName); - } else { - fullName = endpointName; - } -#endif - /* copy the string into our buffer */ - if (fullName) { - newName = (char *) malloc(CFStringGetLength(fullName) + 1); - CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1, - defaultEncoding); - } else { - newName = NULL; - } - - /* clean up */ -#ifdef OLDCODE - if (endpointName) CFRelease(endpointName); - if (deviceName) CFRelease(deviceName); -#endif - if (fullName) CFRelease(fullName); - - return newName; -} - - - -pm_fns_node pm_macosx_in_dictionary = { - none_write_short, - none_sysex, - none_sysex, - none_write_byte, - none_write_short, - none_write_flush, - none_synchronize, - midi_in_open, - midi_abort, - midi_in_close, - success_poll, - midi_has_host_error, - midi_get_host_error, -}; - -pm_fns_node pm_macosx_out_dictionary = { - midi_write_short, - midi_begin_sysex, - midi_end_sysex, - midi_write_byte, - midi_write_realtime, - midi_write_flush, - midi_synchronize, - midi_out_open, - midi_abort, - midi_out_close, - success_poll, - midi_has_host_error, - midi_get_host_error, -}; - - -PmError pm_macosxcm_init(void) -{ - ItemCount numInputs, numOutputs, numDevices; - MIDIEndpointRef endpoint; - int i; - OSStatus macHostError; - char *error_text; - - /* Determine the number of MIDI devices on the system */ - numDevices = MIDIGetNumberOfDevices(); - numInputs = MIDIGetNumberOfSources(); - numOutputs = MIDIGetNumberOfDestinations(); - - /* Return prematurely if no devices exist on the system - Note that this is not an error. There may be no devices. - Pm_CountDevices() will return zero, which is correct and - useful information - */ - if (numDevices <= 0) { - return pmNoError; - } - - - /* Initialize the client handle */ - macHostError = MIDIClientCreate(CFSTR("PortMidi"), NULL, NULL, &client); - if (macHostError != noErr) { - error_text = "MIDIClientCreate() in pm_macosxcm_init()"; - goto error_return; - } - - /* Create the input port */ - macHostError = MIDIInputPortCreate(client, CFSTR("Input port"), readProc, - NULL, &portIn); - if (macHostError != noErr) { - error_text = "MIDIInputPortCreate() in pm_macosxcm_init()"; - goto error_return; - } - - /* Create the output port */ - macHostError = MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut); - if (macHostError != noErr) { - error_text = "MIDIOutputPortCreate() in pm_macosxcm_init()"; - goto error_return; - } - - /* Iterate over the MIDI input devices */ - for (i = 0; i < numInputs; i++) { - endpoint = MIDIGetSource(i); - if (endpoint == NULL_REF) { - continue; - } - - /* set the first input we see to the default */ - if (pm_default_input_device_id == -1) - pm_default_input_device_id = pm_descriptor_index; - - /* Register this device with PortMidi */ - char* full_endpoint_name = cm_get_full_endpoint_name(endpoint); - if (full_endpoint_name != NULL) { - pm_add_device("CoreMIDI", full_endpoint_name, - TRUE, (void *) (long) endpoint, &pm_macosx_in_dictionary); - - } - } - - /* Iterate over the MIDI output devices */ - for (i = 0; i < numOutputs; i++) { - endpoint = MIDIGetDestination(i); - if (endpoint == NULL_REF) { - continue; - } - - /* set the first output we see to the default */ - if (pm_default_output_device_id == -1) - pm_default_output_device_id = pm_descriptor_index; - - /* Register this device with PortMidi */ - char* full_endpoint_name = cm_get_full_endpoint_name(endpoint); - if (full_endpoint_name != NULL) { - pm_add_device("CoreMIDI", full_endpoint_name, - FALSE, (void *) (long) endpoint, - &pm_macosx_out_dictionary); - } - } - return pmNoError; - -error_return: - pm_hosterror = macHostError; - sprintf(pm_hosterror_text, "Host error %ld: %s\n", (long) macHostError, - error_text); - pm_macosxcm_term(); /* clear out any opened ports */ - return pmHostError; -} - -void pm_macosxcm_term(void) -{ - if (client != NULL_REF) MIDIClientDispose(client); - if (portIn != NULL_REF) MIDIPortDispose(portIn); - if (portOut != NULL_REF) MIDIPortDispose(portOut); -} diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmacosxcm.h b/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmacosxcm.h deleted file mode 100644 index ea79902d40..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/pmmacosxcm.h +++ /dev/null @@ -1,6 +0,0 @@ -/* system-specific definitions */ - -PmError pm_macosxcm_init(void); -void pm_macosxcm_term(void); - -PmDeviceID find_default_device(char *path, int input, PmDeviceID id); diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/readbinaryplist.c b/libs/backends/wavesaudio/portmidi/src/pm_mac/readbinaryplist.c deleted file mode 100644 index 88830310e6..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/readbinaryplist.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - -readbinaryplist.c -- Roger B. Dannenberg, Jun 2008 -Based on ReadBinaryPList.m by Jens Ayton, 2007 - -Note that this code is intended to read preference files and has an upper -bound on file size (currently 100MB) and assumes in some places that 32 bit -offsets are sufficient. - -Here are his comments: - -Reader for binary property list files (version 00). - -This has been found to work on all 566 binary plists in my ~/Library/Preferences/ -and /Library/Preferences/ directories. This probably does not provide full -test coverage. It has also been found to provide different data to Apple's -implementation when presented with a key-value archive. This is because Apple's -implementation produces undocumented CFKeyArchiverUID objects. My implementation -produces dictionaries instead, matching the in-file representation used in XML -and OpenStep plists. See extract_uid(). - -Full disclosure: in implementing this software, I read one comment and one -struct defintion in CFLite, Apple's implementation, which is under the APSL -license. I also deduced the information about CFKeyArchiverUID from that code. -However, none of the implementation was copied. - -Copyright (C) 2007 Jens Ayton - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -/* A note about memory management: -Strings and possibly other values are unique and because the values -associated with IDs are cached, you end up with a directed graph rather -than a tree. It is tricky to free the data because if you do a simple -depth-first search to free nodes, you will free nodes twice. I decided -to allocate memory from blocks of 1024 bytes and keep the blocks in a -list associated with but private to this module. So the user should -access this module by calling: - bplist_read_file() or bplist_read_user_pref() or - bplist_read_system_pref() -which returns a value. When you are done with the value, call - bplist_free_data() -This will of course free the value_ptr returned by bplist_read_*() - -To deal with memory exhaustion (what happens when malloc returns -NULL?), use setjmp/longjmp -- a single setjmp protects the whole -parser, and allocate uses longjmp to abort. After abort, memory -is freed and NULL is returned to caller. There is not much here -in the way of error reporting. - -Memory is obtained by calling allocate which either returns the -memory requested or calls longjmp, so callers don't have to check. - -*/ - -#include -#include -#include -#include -#include -#include -#include "readbinaryplist.h" -#include - -#define NO 0 -#define YES 1 -#define BOOL int - -#define MAXPATHLEN 256 - -/* there are 2 levels of error logging/printing: - * BPLIST_LOG and BPLIST_LOG_VERBOSE - * either or both can be set to non-zero to turn on - * If BPLIST_LOG_VERBOSE is true, then BPLIST_LOG - * is also true. - * - * In the code, logging is done by calling either - * bplist_log() or bplist_log_verbose(), which take - * parameters like printf but might be a no-op. - */ - -/* #define BPLIST_LOG_VERBOSE 1 */ - -#if BPLIST_LOG_VERBOSE - #ifndef BPLIST_LOG - #define BPLIST_LOG 1 - #endif -#endif - -#if BPLIST_LOG - #define bplist_log printf -#else - #define bplist_log(...) -#endif - -#if BPLIST_LOG_VERBOSE - #define bplist_log_verbose bplist_log -#else - #define bplist_log_verbose(...) -#endif - - -/********* MEMORY MANAGEMENT ********/ -#define BLOCK_SIZE 1024 -// memory is aligned to multiples of this; assume malloc automatically -// aligns to this number and assume this number is > sizeof(void *) -#define ALIGNMENT 8 -static void *block_list = NULL; -static char *free_ptr = NULL; -static char *end_ptr = NULL; -static jmp_buf abort_parsing; - -static void *allocate(size_t size) -{ - void *result; - if (free_ptr + size > end_ptr) { - size_t how_much = BLOCK_SIZE; - // align everything to 8 bytes - if (size > BLOCK_SIZE - ALIGNMENT) { - how_much = size + ALIGNMENT; - } - result = malloc(how_much); - if (result == NULL) { - /* serious problem */ - longjmp(abort_parsing, 1); - } - *((void **)result) = block_list; - block_list = result; - free_ptr = ((char *) result) + ALIGNMENT; - end_ptr = ((char *) result) + how_much; - } - // now, there is enough rooom at free_ptr - result = free_ptr; - free_ptr += size; - return result; -} - -void bplist_free_data() -{ - while (block_list) { - void *next = *(void **)block_list; - free(block_list); - block_list = next; - } - free_ptr = NULL; - end_ptr = NULL; -} - -// layout of trailer -- last 32 bytes in plist data - uint8_t unused[6]; - uint8_t offset_int_size; - uint8_t object_ref_size; - uint64_t object_count; - uint64_t top_level_object; - uint64_t offset_table_offset; - - -enum -{ - kHEADER_SIZE = 8, - kTRAILER_SIZE = 32, //sizeof(bplist_trailer_node), - kMINIMUM_SANE_SIZE = kHEADER_SIZE + kTRAILER_SIZE -}; - - -static const char kHEADER_BYTES[kHEADER_SIZE] = "bplist00"; - -// map from UID key to previously parsed value -typedef struct cache_struct { - uint64_t key; - value_ptr value; - struct cache_struct *next; -} cache_node, *cache_ptr; - - -typedef struct bplist_info -{ - uint64_t object_count; - const uint8_t *data_bytes; - uint64_t length; - uint64_t offset_table_offset; - uint8_t offset_int_size; - uint8_t object_ref_size; - cache_ptr cache; -} bplist_info_node, *bplist_info_ptr; - - -static value_ptr bplist_read_pldata(pldata_ptr data); -static value_ptr bplist_read_pref(char *filename, OSType folder_type); -static uint64_t read_sized_int(bplist_info_ptr bplist, uint64_t offset, uint8_t size); -static uint64_t read_offset(bplist_info_ptr bplist, uint64_t index); -static BOOL read_self_sized_int(bplist_info_ptr bplist, uint64_t offset, uint64_t *outValue, size_t *outSize); - -static value_ptr extract_object(bplist_info_ptr bplist, uint64_t objectRef); -static value_ptr extract_simple(bplist_info_ptr bplist, uint64_t offset); -static value_ptr extract_int(bplist_info_ptr bplist, uint64_t offset); -static value_ptr extract_real(bplist_info_ptr bplist, uint64_t offset); -static value_ptr extract_date(bplist_info_ptr bplist, uint64_t offset); -static value_ptr extract_data(bplist_info_ptr bplist, uint64_t offset); -static value_ptr extract_ascii_string(bplist_info_ptr bplist, uint64_t offset); -static value_ptr extract_unicode_string(bplist_info_ptr bplist, uint64_t offset); -static value_ptr extract_uid(bplist_info_ptr bplist, uint64_t offset); -static value_ptr extract_array(bplist_info_ptr bplist, uint64_t offset); -static value_ptr extract_dictionary(bplist_info_ptr bplist, uint64_t offset); - - -value_ptr value_create() -{ - value_ptr value = (value_ptr) allocate(sizeof(value_node)); - return value; -} - - -void value_set_integer(value_ptr v, int64_t i) { - v->tag = kTAG_INT; v->integer = i; -} - -void value_set_real(value_ptr v, double d) { - v->tag = kTAG_REAL; v->real = d; -} - -// d is seconds since 1 January 2001 -void value_set_date(value_ptr v, double d) { - v->tag = kTAG_DATE; v->real = d; -} - -void value_set_ascii_string(value_ptr v, const uint8_t *s, size_t len) { - v->tag = kTAG_ASCIISTRING; - v->string = (char *) allocate(len + 1); - memcpy(v->string, s, len); - v->string[len] = 0; -} - -void value_set_unicode_string(value_ptr v, const uint8_t *s, size_t len) { - v->tag = kTAG_UNICODESTRING; - v->string = (char *) allocate(len + 1); - memcpy(v->string, s, len); - v->string[len] = 0; -} - -void value_set_uid(value_ptr v, uint64_t uid) -{ - v->tag = kTAG_UID; v->uinteger = uid; -} - -// v->data points to a pldata that points to the actual bytes -// the bytes are copied, so caller must free byte source (*data) -void value_set_data(value_ptr v, const uint8_t *data, size_t len) { - v->tag = kTAG_DATA; - pldata_ptr pldata = (pldata_ptr) allocate(sizeof(pldata_node)); - pldata->data = (uint8_t *) allocate(len); - memcpy(pldata->data, data, len); - pldata->len = len; - v->data = pldata; - printf("value at %p gets data at %p\n", v, pldata); -} - -// caller releases ownership of array to value_ptr v -void value_set_array(value_ptr v, value_ptr *array, size_t length) { - array_ptr a = (array_ptr) allocate(sizeof(array_node)); - a->array = array; - a->length = length; - v->tag = kTAG_ARRAY; - v->array = a; -} - -// caller releases ownership of dict to value_ptr v -void value_set_dict(value_ptr v, dict_ptr dict) { - v->tag = kTAG_DICTIONARY; - v->dict = dict; -} - - -// look up an objectref in the cache, a ref->value_ptr mapping -value_ptr cache_lookup(cache_ptr cache, uint64_t ref) -{ - while (cache) { - if (cache->key == ref) { - return cache->value; - } - cache = cache->next; - } - return NULL; -} - - -// insert an objectref and value in the cache -void cache_insert(cache_ptr *cache, uint64_t ref, value_ptr value) -{ - cache_ptr c = (cache_ptr) allocate(sizeof(cache_node)); - c->key = ref; - c->value = value; - c->next = *cache; - *cache = c; -} - - -// insert an objectref and value in a dictionary -void dict_insert(dict_ptr *dict, value_ptr key, value_ptr value) -{ - dict_ptr d = (dict_ptr) allocate(sizeof(dict_node)); - d->key = key; - d->value = value; - d->next = *dict; - *dict = d; -} - - -BOOL is_binary_plist(pldata_ptr data) -{ - if (data->len < kMINIMUM_SANE_SIZE) return NO; - return memcmp(data->data, kHEADER_BYTES, kHEADER_SIZE) == 0; -} - - -value_ptr bplist_read_file(char *filename) -{ - struct stat stbuf; - pldata_node pldata; - FILE *file; - size_t n; - value_ptr value; - int rslt = stat(filename, &stbuf); - if (rslt) { - #if BPLIST_LOG - perror("in stat"); - #endif - bplist_log("Could not stat %s, error %d\n", filename, rslt); - return NULL; - } - // if file is >100MB, assume it is not a preferences file and give up - if (stbuf.st_size > 100000000) { - bplist_log("Large file %s encountered (%llu bytes) -- not read\n", - filename, stbuf.st_size); - return NULL; - } - pldata.len = (size_t) stbuf.st_size; - // note: this is supposed to be malloc, not allocate. It is separate - // from the graph structure, large, and easy to free right after - // parsing. - pldata.data = (uint8_t *) malloc(pldata.len); - if (!pldata.data) { - bplist_log("Could not allocate %lu bytes for %s\n", - (unsigned long) pldata.len, filename); - return NULL; - } - file = fopen(filename, "rb"); - if (!file) { - bplist_log("Could not open %s\n", filename); - return NULL; - } - n = fread(pldata.data, 1, pldata.len, file); - if (n != pldata.len) { - bplist_log("Error reading from %s\n", filename); - return NULL; - } - value = bplist_read_pldata(&pldata); - free(pldata.data); - return value; -} - - -value_ptr bplist_read_pref(char *filename, OSType folder_type) -{ - FSRef prefdir; - char cstr[MAXPATHLEN]; - - OSErr err = FSFindFolder(kOnAppropriateDisk, folder_type, - FALSE, &prefdir); - if (err) { - bplist_log("Error finding preferences folder: %d\n", err); - return NULL; - } - err = FSRefMakePath(&prefdir, (UInt8 *) cstr, (UInt32) (MAXPATHLEN - 1)); - if (err) { - bplist_log("Error making path name for preferences folder: %d\n", err); - return NULL; - } - strlcat(cstr, "/", MAXPATHLEN); - strlcat(cstr, filename, MAXPATHLEN); - return bplist_read_file(cstr); -} - - -value_ptr bplist_read_system_pref(char *filename) { - return bplist_read_pref(filename, kSystemPreferencesFolderType); -} - - -value_ptr bplist_read_user_pref(char *filename) { - return bplist_read_pref(filename, kPreferencesFolderType); -} - - -// data is stored with high-order bytes first. -// read from plist data in a machine-independent fashion -// -uint64_t convert_uint64(uint8_t *ptr) -{ - uint64_t rslt = 0; - int i; - // shift in bytes, high-order first - for (i = 0; i < sizeof(uint64_t); i++) { - rslt <<= 8; - rslt += ptr[i]; - } - return rslt; -} - - -value_ptr bplist_read_pldata(pldata_ptr data) -{ - value_ptr result = NULL; - bplist_info_node bplist; - uint8_t *ptr; - uint64_t top_level_object; - int i; - - if (data == NULL) return NULL; - if (!is_binary_plist(data)) { - bplist_log("Bad binary plist: too short or invalid header.\n"); - return NULL; - } - - // read trailer - ptr = (uint8_t *) (data->data + data->len - kTRAILER_SIZE); - bplist.offset_int_size = ptr[6]; - bplist.object_ref_size = ptr[7]; - bplist.object_count = convert_uint64(ptr + 8); - top_level_object = convert_uint64(ptr + 16); - bplist.offset_table_offset = convert_uint64(ptr + 24); - - // Basic sanity checks - if (bplist.offset_int_size < 1 || bplist.offset_int_size > 8 || - bplist.object_ref_size < 1 || bplist.object_ref_size > 8 || - bplist.offset_table_offset < kHEADER_SIZE) { - bplist_log("Bad binary plist: trailer declared insane.\n"); - return NULL; - } - - // Ensure offset table is inside file - uint64_t offsetTableSize = bplist.offset_int_size * bplist.object_count; - if (offsetTableSize + bplist.offset_table_offset + kTRAILER_SIZE > - data->len) { - bplist_log("Bad binary plist: offset table overlaps end of container.\n"); - return NULL; - } - - bplist.data_bytes = data->data; - bplist.length = data->len; - bplist.cache = NULL; /* dictionary is empty */ - - bplist_log_verbose("Got a sane bplist with %llu items, offset_int_size: %u, object_ref_size: %u\n", - bplist.object_count, bplist.offset_int_size, - bplist.object_ref_size); - /* at this point, we are ready to do some parsing which allocates - memory for the result data structure. If memory allocation (using - allocate fails, a longjmp will return to here and we simply give up - */ - i = setjmp(abort_parsing); - if (i == 0) { - result = extract_object(&bplist, top_level_object); - } else { - bplist_log("allocate() failed to allocate memory. Giving up.\n"); - result = NULL; - } - if (!result) { - bplist_free_data(); - } - return result; -} - - -static value_ptr extract_object(bplist_info_ptr bplist, uint64_t objectRef) -{ - uint64_t offset; - value_ptr result = NULL; - uint8_t objectTag; - - if (objectRef >= bplist->object_count) { - // Out-of-range object reference. - bplist_log("Bad binary plist: object index is out of range.\n"); - return NULL; - } - - // Use cached object if it exists - result = cache_lookup(bplist->cache, objectRef); - if (result != NULL) return result; - - // Otherwise, find object in file. - offset = read_offset(bplist, objectRef); - if (offset > bplist->length) { - // Out-of-range offset. - bplist_log("Bad binary plist: object outside container.\n"); - return NULL; - } - objectTag = *(bplist->data_bytes + offset); - switch (objectTag & 0xF0) { - case kTAG_SIMPLE: - result = extract_simple(bplist, offset); - break; - - case kTAG_INT: - result = extract_int(bplist, offset); - break; - - case kTAG_REAL: - result = extract_real(bplist, offset); - break; - - case kTAG_DATE: - result = extract_date(bplist, offset); - break; - - case kTAG_DATA: - result = extract_data(bplist, offset); - break; - - case kTAG_ASCIISTRING: - result = extract_ascii_string(bplist, offset); - break; - - case kTAG_UNICODESTRING: - result = extract_unicode_string(bplist, offset); - break; - - case kTAG_UID: - result = extract_uid(bplist, offset); - break; - - case kTAG_ARRAY: - result = extract_array(bplist, offset); - break; - - case kTAG_DICTIONARY: - result = extract_dictionary(bplist, offset); - break; - - default: - // Unknown tag. - bplist_log("Bad binary plist: unknown tag 0x%X.\n", - (objectTag & 0x0F) >> 4); - result = NULL; - } - - // Cache and return result. - if (result != NULL) - cache_insert(&bplist->cache, objectRef, result); - return result; -} - - -static uint64_t read_sized_int(bplist_info_ptr bplist, uint64_t offset, - uint8_t size) -{ - assert(bplist->data_bytes != NULL && size >= 1 && size <= 8 && - offset + size <= bplist->length); - - uint64_t result = 0; - const uint8_t *byte = bplist->data_bytes + offset; - - do { - // note that ints seem to be high-order first - result = (result << 8) | *byte++; - } while (--size); - - return result; -} - - -static uint64_t read_offset(bplist_info_ptr bplist, uint64_t index) -{ - assert(index < bplist->object_count); - - return read_sized_int(bplist, - bplist->offset_table_offset + bplist->offset_int_size * index, - bplist->offset_int_size); -} - - -static BOOL read_self_sized_int(bplist_info_ptr bplist, uint64_t offset, - uint64_t *outValue, size_t *outSize) -{ - uint32_t size; - int64_t value; - - assert(bplist->data_bytes != NULL && offset < bplist->length); - - size = 1 << (bplist->data_bytes[offset] & 0x0F); - if (size > 8) { - // Maximum allowable size in this implementation is 1<<3 = 8 bytes. - // This also happens to be the biggest we can handle. - return NO; - } - - if (offset + 1 + size > bplist->length) { - // Out of range. - return NO; - } - - value = read_sized_int(bplist, offset + 1, size); - - if (outValue != NULL) *outValue = value; - if (outSize != NULL) *outSize = size + 1; // +1 for tag byte. - return YES; -} - - -static value_ptr extract_simple(bplist_info_ptr bplist, uint64_t offset) -{ - assert(bplist->data_bytes != NULL && offset < bplist->length); - value_ptr value = value_create(); - - switch (bplist->data_bytes[offset]) { - case kVALUE_NULL: - value->tag = kVALUE_NULL; - return value; - - case kVALUE_TRUE: - value->tag = kVALUE_TRUE; - return value; - - case kVALUE_FALSE: - value->tag = kVALUE_FALSE; - return value; - } - - // Note: kVALUE_FILLER is treated as invalid, because it, er, is. - bplist_log("Bad binary plist: invalid atom.\n"); - free(value); - return NULL; -} - - -static value_ptr extract_int(bplist_info_ptr bplist, uint64_t offset) -{ - value_ptr value = value_create(); - value->tag = kTAG_INT; - - if (!read_self_sized_int(bplist, offset, &value->uinteger, NULL)) { - bplist_log("Bad binary plist: invalid integer object.\n"); - } - - /* NOTE: originally, I sign-extended here. This was the wrong thing; it - turns out that negative ints are always stored as 64-bit, and smaller - ints are unsigned. - */ - return value; -} - - -static value_ptr extract_real(bplist_info_ptr bplist, uint64_t offset) -{ - value_ptr value = value_create(); - uint32_t size; - - assert(bplist->data_bytes != NULL && offset < bplist->length); - - size = 1 << (bplist->data_bytes[offset] & 0x0F); - - // FIXME: what to do if faced with other sizes for float/double? - assert (sizeof (float) == sizeof (uint32_t) && - sizeof (double) == sizeof (uint64_t)); - - if (offset + 1 + size > bplist->length) { - bplist_log("Bad binary plist: %s object overlaps end of container.\n", - "floating-point number"); - free(value); - return NULL; - } - - if (size == sizeof (float)) { - // cast is ok because we know size is 4 bytes - uint32_t i = (uint32_t) read_sized_int(bplist, offset + 1, size); - // Note that this handles byte swapping. - value_set_real(value, *(float *)&i); - return value; - } else if (size == sizeof (double)) { - uint64_t i = read_sized_int(bplist, offset + 1, size); - // Note that this handles byte swapping. - value_set_real(value, *(double *)&i); - return value; - } else { - // Can't handle floats of other sizes. - bplist_log("Bad binary plist: can't handle %u-byte float.\n", size); - free(value); - return NULL; - } -} - - -static value_ptr extract_date(bplist_info_ptr bplist, uint64_t offset) -{ - value_ptr value; - assert(bplist->data_bytes != NULL && offset < bplist->length); - - // Data has size code like int and real, but only 3 (meaning 8 bytes) is valid. - if (bplist->data_bytes[offset] != kVALUE_FULLDATETAG) { - bplist_log("Bad binary plist: invalid size for date object.\n"); - return NULL; - } - - if (offset + 1 + sizeof (double) > bplist->length) { - bplist_log("Bad binary plist: %s object overlaps end of container.\n", - "date"); - return NULL; - } - - // FIXME: what to do if faced with other sizes for double? - assert (sizeof (double) == sizeof (uint64_t)); - - uint64_t date = read_sized_int(bplist, offset + 1, sizeof(double)); - // Note that this handles byte swapping. - value = value_create(); - value_set_date(value, *(double *)&date); - return value; -} - - -uint64_t bplist_get_a_size(bplist_info_ptr bplist, - uint64_t *offset_ptr, char *msg) -{ - uint64_t size = bplist->data_bytes[*offset_ptr] & 0x0F; - (*offset_ptr)++; - if (size == 0x0F) { - // 0x0F means separate int size follows. - // Smaller values are used for short data. - size_t extra; // the length of the data size we are about to read - if ((bplist->data_bytes[*offset_ptr] & 0xF0) != kTAG_INT) { - // Bad data, mistagged size int - bplist_log("Bad binary plist: %s object size is not tagged as int.\n", - msg); - return UINT64_MAX; // error - } - - // read integer data as size, extra tells how many bytes to skip - if (!read_self_sized_int(bplist, *offset_ptr, &size, &extra)) { - bplist_log("Bad binary plist: invalid %s object size tag.\n", - "data"); - return UINT64_MAX; // error - } - (*offset_ptr) += extra; - } - - if (*offset_ptr + size > bplist->length) { - bplist_log("Bad binary plist: %s object overlaps end of container.\n", - "data"); - return UINT64_MAX; // error - } - return size; -} - - -static value_ptr extract_data(bplist_info_ptr bplist, uint64_t offset) -{ - uint64_t size; - value_ptr value; - - assert(bplist->data_bytes != NULL && offset < bplist->length); - - if ((size = bplist_get_a_size(bplist, &offset, "data")) == UINT64_MAX) - return NULL; - - value = value_create(); - // cast is ok because we only allow files up to 100MB: - value_set_data(value, bplist->data_bytes + (size_t) offset, (size_t) size); - return value; -} - - -static value_ptr extract_ascii_string(bplist_info_ptr bplist, uint64_t offset) -{ - uint64_t size; - value_ptr value; // return value - - assert(bplist->data_bytes != NULL && offset < bplist->length); - - if ((size = bplist_get_a_size(bplist, &offset, "ascii string")) == - UINT64_MAX) - return NULL; - - value = value_create(); - // cast is ok because we only allow 100MB files - value_set_ascii_string(value, bplist->data_bytes + (size_t) offset, - (size_t) size); - return value; -} - - -static value_ptr extract_unicode_string(bplist_info_ptr bplist, uint64_t offset) -{ - uint64_t size; - value_ptr value; - - assert(bplist->data_bytes != NULL && offset < bplist->length); - - if ((size = bplist_get_a_size(bplist, &offset, "unicode string")) == - UINT64_MAX) - return NULL; - - value = value_create(); - // cast is ok because we only allow 100MB files - value_set_unicode_string(value, bplist->data_bytes + (size_t) offset, - (size_t) size); - return value; -} - - -static value_ptr extract_uid(bplist_info_ptr bplist, uint64_t offset) -{ - /* UIDs are used by Cocoa's key-value coder. - When writing other plist formats, they are expanded to dictionaries of - the form CF$UIDvalue, so we - do the same here on reading. This results in plists identical to what - running plutil -convert xml1 gives us. However, this is not the same - result as [Core]Foundation's plist parser, which extracts them as un- - introspectable CF objects. In fact, it even seems to convert the CF$UID - dictionaries from XML plists on the fly. - */ - - value_ptr value; - uint64_t uid; - - if (!read_self_sized_int(bplist, offset, &uid, NULL)) { - bplist_log("Bad binary plist: invalid UID object.\n"); - return NULL; - } - - // assert(NO); // original code suggests using a string for a key - // but our dictionaries all use big ints for keys, so I don't know - // what to do here - - // In practice, I believe this code is never executed by PortMidi. - // I changed it to do something and not raise compiler warnings, but - // not sure what the code should do. - - value = value_create(); - value_set_uid(value, uid); - // return [NSDictionary dictionaryWithObject: - // [NSNumber numberWithUnsignedLongLong:value] - // forKey:"CF$UID"]; - return value; -} - - -static value_ptr extract_array(bplist_info_ptr bplist, uint64_t offset) -{ - uint64_t i, count; - uint64_t size; - uint64_t elementID; - value_ptr element = NULL; - value_ptr *array = NULL; - value_ptr value = NULL; - BOOL ok = YES; - - assert(bplist->data_bytes != NULL && offset < bplist->length); - - if ((count = bplist_get_a_size(bplist, &offset, "array")) == UINT64_MAX) - return NULL; - - if (count > UINT64_MAX / bplist->object_ref_size - offset) { - // Offset overflow. - bplist_log("Bad binary plist: %s object overlaps end of container.\n", - "array"); - return NULL; - } - - size = bplist->object_ref_size * count; - if (size + offset > bplist->length) { - bplist_log("Bad binary plist: %s object overlaps end of container.\n", - "array"); - return NULL; - } - - // got count, the number of array elements - - value = value_create(); - assert(value); - - if (count == 0) { - // count must be size_t or smaller because max file size is 100MB - value_set_array(value, array, (size_t) count); - return value; - } - - array = allocate(sizeof(value_ptr) * (size_t) count); - - for (i = 0; i != count; ++i) { - bplist_log_verbose("[%u]\n", i); - elementID = read_sized_int(bplist, offset + i * bplist->object_ref_size, - bplist->object_ref_size); - element = extract_object(bplist, elementID); - if (element != NULL) { - array[i] = element; - } else { - ok = NO; - break; - } - } - if (ok) { // count is smaller than size_t max because of 100MB file limit - value_set_array(value, array, (size_t) count); - } - - return value; -} - - -static value_ptr extract_dictionary(bplist_info_ptr bplist, uint64_t offset) -{ - uint64_t i, count; - uint64_t size; - uint64_t elementID; - value_ptr value = NULL; - dict_ptr dict = NULL; - BOOL ok = YES; - - assert(bplist->data_bytes != NULL && offset < bplist->length); - - - if ((count = bplist_get_a_size(bplist, &offset, "array")) == UINT64_MAX) - return NULL; - - if (count > UINT64_MAX / (bplist->object_ref_size * 2) - offset) { - // Offset overflow. - bplist_log("Bad binary plist: %s object overlaps end of container.\n", - "dictionary"); - return NULL; - } - - size = bplist->object_ref_size * count * 2; - if (size + offset > bplist->length) { - bplist_log("Bad binary plist: %s object overlaps end of container.\n", - "dictionary"); - return NULL; - } - - value = value_create(); - if (count == 0) { - value_set_dict(value, NULL); - return value; - } - - for (i = 0; i != count; ++i) { - value_ptr key; - value_ptr val; - elementID = read_sized_int(bplist, offset + i * bplist->object_ref_size, - bplist->object_ref_size); - key = extract_object(bplist, elementID); - if (key != NULL) { - bplist_log_verbose("key: %p\n", key); - } else { - ok = NO; - break; - } - - elementID = read_sized_int(bplist, - offset + (i + count) * bplist->object_ref_size, - bplist->object_ref_size); - val = extract_object(bplist, elementID); - if (val != NULL) { - dict_insert(&dict, key, val); - } else { - ok = NO; - break; - } - } - if (ok) { - value_set_dict(value, dict); - } - - return value; -} - -/*************** functions for accessing values ****************/ - - -char *value_get_asciistring(value_ptr v) -{ - if (v->tag != kTAG_ASCIISTRING) return NULL; - return v->string; -} - - -value_ptr value_dict_lookup_using_string(value_ptr v, char *key) -{ - dict_ptr dict; - if (v->tag != kTAG_DICTIONARY) return NULL; // not a dictionary - dict = v->dict; - /* search for key */ - while (dict) { - if (dict->key && dict->key->tag == kTAG_ASCIISTRING && - strcmp(key, dict->key->string) == 0) { // found it - return dict->value; - } - dict = dict->next; - } - return NULL; /* not found */ -} - -value_ptr value_dict_lookup_using_path(value_ptr v, char *path) -{ - char key[MAX_KEY_SIZE]; - while (*path) { /* more to the path */ - int i = 0; - while (i < MAX_KEY_SIZE - 1) { - key[i] = *path++; - if (key[i] == '/') { /* end of entry in path */ - key[i + 1] = 0; - break; - } - if (!key[i]) { - path--; /* back up to end of string char */ - break; /* this will cause outer loop to exit */ - } - i++; - } - if (!v || v->tag != kTAG_DICTIONARY) return NULL; - /* now, look up the key to get next value */ - v = value_dict_lookup_using_string(v, key); - if (v == NULL) return NULL; - } - return v; -} - - -/*************** functions for debugging ***************/ - -void plist_print(value_ptr v) -{ - size_t i; - int comma_needed; - dict_ptr dict; - if (!v) { - printf("NULL"); - return; - } - switch (v->tag & 0xF0) { - case kTAG_SIMPLE: - switch (v->tag) { - case kVALUE_NULL: - printf("NULL@%p", v); break; - case kVALUE_FALSE: - printf("FALSE@%p", v); break; - case kVALUE_TRUE: - printf("TRUE@%p", v); break; - default: - printf("UNKNOWN tag=%x@%p", v->tag, v); break; - } - break; - case kTAG_INT: - printf("%lld@%p", v->integer, v); break; - case kTAG_REAL: - printf("%g@%p", v->real, v); break; - case kTAG_DATE: - printf("date:%g@%p", v->real, v); break; - case kTAG_DATA: - printf("data@%p->%p:[%p:", v, v->data, v->data->data); - for (i = 0; i < v->data->len; i++) { - printf(" %2x", v->data->data[i]); - } - printf("]"); break; - case kTAG_ASCIISTRING: - printf("%p:\"%s\"@%p", v->string, v->string, v); break; - case kTAG_UNICODESTRING: - printf("unicode:%p:\"%s\"@%p", v->string, v->string, v); break; - case kTAG_UID: - printf("UID:%llu@%p", v->uinteger, v); break; - case kTAG_ARRAY: - comma_needed = FALSE; - printf("%p->%p:[%p:", v, v->array, v->array->array); - for (i = 0; i < v->array->length; i++) { - if (comma_needed) printf(", "); - plist_print(v->array->array[i]); - comma_needed = TRUE; - } - printf("]"); break; - case kTAG_DICTIONARY: - comma_needed = FALSE; - printf("%p:[", v); - dict = v->dict; - while (dict) { - if (comma_needed) printf(", "); - printf("%p:", dict); - plist_print(dict->key); - printf("->"); - plist_print(dict->value); - comma_needed = TRUE; - dict = dict->next; - } - printf("]"); break; - default: - printf("UNKNOWN tag=%x", v->tag); - break; - } -} - - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_mac/readbinaryplist.h b/libs/backends/wavesaudio/portmidi/src/pm_mac/readbinaryplist.h deleted file mode 100644 index f1123c13d0..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_mac/readbinaryplist.h +++ /dev/null @@ -1,88 +0,0 @@ -/* readbinaryplist.h -- header to read preference files - - Roger B. Dannenberg, Jun 2008 -*/ - -#include /* for uint8_t ... */ - -#ifndef TRUE - #define TRUE 1 - #define FALSE 0 -#endif - -#define MAX_KEY_SIZE 256 - -enum -{ - // Object tags (high nybble) - kTAG_SIMPLE = 0x00, // Null, true, false, filler, or invalid - kTAG_INT = 0x10, - kTAG_REAL = 0x20, - kTAG_DATE = 0x30, - kTAG_DATA = 0x40, - kTAG_ASCIISTRING = 0x50, - kTAG_UNICODESTRING = 0x60, - kTAG_UID = 0x80, - kTAG_ARRAY = 0xA0, - kTAG_DICTIONARY = 0xD0, - - // "simple" object values - kVALUE_NULL = 0x00, - kVALUE_FALSE = 0x08, - kVALUE_TRUE = 0x09, - kVALUE_FILLER = 0x0F, - - kVALUE_FULLDATETAG = 0x33 // Dates are tagged with a whole byte. -}; - - -typedef struct pldata_struct { - uint8_t *data; - size_t len; -} pldata_node, *pldata_ptr; - - -typedef struct array_struct { - struct value_struct **array; - uint64_t length; -} array_node, *array_ptr; - - -// a dict_node is a list of pairs -typedef struct dict_struct { - struct value_struct *key; - struct value_struct *value; - struct dict_struct *next; -} dict_node, *dict_ptr; - - -// an value_node is a value with a tag telling the type -typedef struct value_struct { - int tag; - union { - int64_t integer; - uint64_t uinteger; - double real; - char *string; - pldata_ptr data; - array_ptr array; - struct dict_struct *dict; - }; -} value_node, *value_ptr; - - -value_ptr bplist_read_file(char *filename); -value_ptr bplist_read_user_pref(char *filename); -value_ptr bplist_read_system_pref(char *filename); -void bplist_free_data(); - -/*************** functions for accessing values ****************/ - -char *value_get_asciistring(value_ptr v); -value_ptr value_dict_lookup_using_string(value_ptr v, char *key); -value_ptr value_dict_lookup_using_path(value_ptr v, char *path); - -/*************** functions for debugging ***************/ - -void plist_print(value_ptr v); - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_win/pmwin.c b/libs/backends/wavesaudio/portmidi/src/pm_win/pmwin.c deleted file mode 100644 index cd1f001b5f..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_win/pmwin.c +++ /dev/null @@ -1,142 +0,0 @@ -/* pmwin.c -- PortMidi os-dependent code */ - -/* This file only needs to implement: - pm_init(), which calls various routines to register the - available midi devices, - Pm_GetDefaultInputDeviceID(), and - Pm_GetDefaultOutputDeviceID(). - This file must - be separate from the main portmidi.c file because it is system - dependent, and it is separate from, say, pmwinmm.c, because it - might need to register devices for winmm, directx, and others. - - */ - -#include "stdlib.h" -#include "portmidi.h" -#include "pmutil.h" -#include "pminternal.h" -#include "pmwinmm.h" -#ifdef DEBUG -#include "stdio.h" -#endif -#include - -/* pm_exit is called when the program exits. - It calls pm_term to make sure PortMidi is properly closed. - If DEBUG is on, we prompt for input to avoid losing error messages. - */ -static void pm_exit(void) { - pm_term(); -#ifdef DEBUG -#define STRING_MAX 80 - { - char line[STRING_MAX]; - printf("Type ENTER...\n"); - /* note, w/o this prompting, client console application can not see one - of its errors before closing. */ - fgets(line, STRING_MAX, stdin); - } -#endif -} - - -/* pm_init is the windows-dependent initialization.*/ -void pm_init(void) -{ - atexit(pm_exit); -#ifdef DEBUG - printf("registered pm_exit with atexit()\n"); -#endif - pm_winmm_init(); - /* initialize other APIs (DirectX?) here */ -} - - -void pm_term(void) { - pm_winmm_term(); -} - - -static PmDeviceID pm_get_default_device_id(int is_input, char *key) { - HKEY hkey; -#define PATTERN_MAX 256 - char pattern[PATTERN_MAX]; - long pattern_max = PATTERN_MAX; - DWORD dwType; - /* Find first input or device -- this is the default. */ - PmDeviceID id = pmNoDevice; - int i, j; - Pm_Initialize(); /* make sure descriptors exist! */ - for (i = 0; i < pm_descriptor_index; i++) { - if (descriptors[i].pub.input == is_input) { - id = i; - break; - } - } - /* Look in registry for a default device name pattern. */ - if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey) != - ERROR_SUCCESS) { - return id; - } - if (RegOpenKeyEx(hkey, "JavaSoft", 0, KEY_READ, &hkey) != - ERROR_SUCCESS) { - return id; - } - if (RegOpenKeyEx(hkey, "Prefs", 0, KEY_READ, &hkey) != - ERROR_SUCCESS) { - return id; - } - if (RegOpenKeyEx(hkey, "/Port/Midi", 0, KEY_READ, &hkey) != - ERROR_SUCCESS) { - return id; - } - if (RegQueryValueEx(hkey, key, NULL, &dwType, (LPBYTE)pattern, (LPDWORD)&pattern_max) != - ERROR_SUCCESS) { - return id; - } - - /* decode pattern: upper case encoded with "/" prefix */ - i = j = 0; - while (pattern[i]) { - if (pattern[i] == '/' && pattern[i + 1]) { - pattern[j++] = toupper(pattern[++i]); - } else { - pattern[j++] = tolower(pattern[i]); - } - i++; - } - pattern[j] = 0; /* end of string */ - - /* now pattern is the string from the registry; search for match */ - i = pm_find_default_device(pattern, is_input); - if (i != pmNoDevice) { - id = i; - } - return id; -} - - -PmDeviceID Pm_GetDefaultInputDeviceID() { - return pm_get_default_device_id(TRUE, - "/P/M_/R/E/C/O/M/M/E/N/D/E/D_/I/N/P/U/T_/D/E/V/I/C/E"); -} - - -PmDeviceID Pm_GetDefaultOutputDeviceID() { - return pm_get_default_device_id(FALSE, - "/P/M_/R/E/C/O/M/M/E/N/D/E/D_/O/U/T/P/U/T_/D/E/V/I/C/E"); -} - - -#include "stdio.h" - -void *pm_alloc(size_t s) { - return malloc(s); -} - - -void pm_free(void *ptr) { - free(ptr); -} - diff --git a/libs/backends/wavesaudio/portmidi/src/pm_win/pmwinmm.c b/libs/backends/wavesaudio/portmidi/src/pm_win/pmwinmm.c deleted file mode 100644 index d709ff5c8f..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_win/pmwinmm.c +++ /dev/null @@ -1,1466 +0,0 @@ -/* pmwinmm.c -- system specific definitions */ - -#ifdef _MSC_VER - #pragma warning(disable: 4133) // stop warnings about implicit typecasts - -#define max(a,b) __max(a,b) -#endif - -#ifndef _WIN32_WINNT - /* without this define, InitializeCriticalSectionAndSpinCount is - * undefined. This version level means "Windows 2000 and higher" - */ - #define _WIN32_WINNT 0x0500 -#endif - -#include "windows.h" -#include "mmsystem.h" -#include "portmidi.h" -#include "pmutil.h" -#include "pminternal.h" -#include "pmwinmm.h" -#include -#include "porttime.h" - -/* asserts used to verify portMidi code logic is sound; later may want - something more graceful */ -#include -#ifdef DEBUG -/* this printf stuff really important for debugging client app w/host errors. - probably want to do something else besides read/write from/to console - for portability, however */ -#define STRING_MAX 80 -#include "stdio.h" -#endif - -#define streql(x, y) (strcmp(x, y) == 0) - -#define MIDI_SYSEX 0xf0 -#define MIDI_EOX 0xf7 - -/* callback routines */ -static void CALLBACK winmm_in_callback(HMIDIIN hMidiIn, - WORD wMsg, DWORD dwInstance, - DWORD dwParam1, DWORD dwParam2); -static void CALLBACK winmm_streamout_callback(HMIDIOUT hmo, UINT wMsg, - DWORD dwInstance, DWORD dwParam1, - DWORD dwParam2); -#ifdef USE_SYSEX_BUFFERS -static void CALLBACK winmm_out_callback(HMIDIOUT hmo, UINT wMsg, - DWORD dwInstance, DWORD dwParam1, - DWORD dwParam2); -#endif - -extern pm_fns_node pm_winmm_in_dictionary; -extern pm_fns_node pm_winmm_out_dictionary; - -static void winmm_out_delete(PmInternal *midi); /* forward reference */ - -/* -A note about buffers: WinMM seems to hold onto buffers longer than -one would expect, e.g. when I tried using 2 small buffers to send -long sysex messages, at some point WinMM held both buffers. This problem -was fixed by making buffers bigger. Therefore, it seems that there should -be enough buffer space to hold a whole sysex message. - -The bufferSize passed into Pm_OpenInput (passed into here as buffer_len) -will be used to estimate the largest sysex message (= buffer_len * 4 bytes). -Call that the max_sysex_len = buffer_len * 4. - -For simple midi output (latency == 0), allocate 3 buffers, each with half -the size of max_sysex_len, but each at least 256 bytes. - -For stream output, there will already be enough space in very short -buffers, so use them, but make sure there are at least 16. - -For input, use many small buffers rather than 2 large ones so that when -there are short sysex messages arriving frequently (as in control surfaces) -there will be more free buffers to fill. Use max_sysex_len / 64 buffers, -but at least 16, of size 64 bytes each. - -The following constants help to represent these design parameters: -*/ -#define NUM_SIMPLE_SYSEX_BUFFERS 3 -#define MIN_SIMPLE_SYSEX_LEN 256 - -#define MIN_STREAM_BUFFERS 16 -#define STREAM_BUFFER_LEN 24 - -#define INPUT_SYSEX_LEN 64 -#define MIN_INPUT_BUFFERS 16 - -/* if we run out of space for output (assume this is due to a sysex msg, - expand by up to NUM_EXPANSION_BUFFERS in increments of EXPANSION_BUFFER_LEN - */ -#define NUM_EXPANSION_BUFFERS 128 -#define EXPANSION_BUFFER_LEN 1024 - -/* A sysex buffer has 3 DWORDS as a header plus the actual message size */ -#define MIDIHDR_SYSEX_BUFFER_LENGTH(x) ((x) + sizeof(long)*3) -/* A MIDIHDR with a sysex message is the buffer length plus the header size */ -#define MIDIHDR_SYSEX_SIZE(x) (MIDIHDR_SYSEX_BUFFER_LENGTH(x) + sizeof(MIDIHDR)) -#ifdef USE_SYSEX_BUFFERS -/* Size of a MIDIHDR with a buffer contaning multiple MIDIEVENT structures */ -#define MIDIHDR_SIZE(x) ((x) + sizeof(MIDIHDR)) -#endif - -/* -============================================================================== -win32 mmedia system specific structure passed to midi callbacks -============================================================================== -*/ - -/* global winmm device info */ -MIDIINCAPS *midi_in_caps = NULL; -MIDIINCAPS midi_in_mapper_caps; -UINT midi_num_inputs = 0; -MIDIOUTCAPS *midi_out_caps = NULL; -MIDIOUTCAPS midi_out_mapper_caps; -UINT midi_num_outputs = 0; - -/* per device info */ -typedef struct midiwinmm_struct { - union { - HMIDISTRM stream; /* windows handle for stream */ - HMIDIOUT out; /* windows handle for out calls */ - HMIDIIN in; /* windows handle for in calls */ - } handle; - - /* midi output messages are sent in these buffers, which are allocated - * in a round-robin fashion, using next_buffer as an index - */ - LPMIDIHDR *buffers; /* pool of buffers for midi in or out data */ - int max_buffers; /* length of buffers array */ - int buffers_expanded; /* buffers array expanded for extra msgs? */ - int num_buffers; /* how many buffers allocated in buffers array */ - int next_buffer; /* index of next buffer to send */ - HANDLE buffer_signal; /* used to wait for buffer to become free */ -#ifdef USE_SYSEX_BUFFERS - /* sysex buffers will be allocated only when - * a sysex message is sent. The size of the buffer is fixed. - */ - LPMIDIHDR sysex_buffers[NUM_SYSEX_BUFFERS]; /* pool of buffers for sysex data */ - int next_sysex_buffer; /* index of next sysexbuffer to send */ -#endif - unsigned long last_time; /* last output time */ - int first_message; /* flag: treat first message differently */ - int sysex_mode; /* middle of sending sysex */ - unsigned long sysex_word; /* accumulate data when receiving sysex */ - unsigned int sysex_byte_count; /* count how many received */ - LPMIDIHDR hdr; /* the message accumulating sysex to send */ - unsigned long sync_time; /* when did we last determine delta? */ - long delta; /* difference between stream time and - real time */ - int error; /* host error from doing port midi call */ - CRITICAL_SECTION lock; /* prevents reentrant callbacks (input only) */ -} midiwinmm_node, *midiwinmm_type; - - -/* -============================================================================= -general MIDI device queries -============================================================================= -*/ -static void pm_winmm_general_inputs() -{ - UINT i; - WORD wRtn; - midi_num_inputs = midiInGetNumDevs(); - midi_in_caps = (MIDIINCAPS *) pm_alloc(sizeof(MIDIINCAPS) * - midi_num_inputs); - if (midi_in_caps == NULL) { - /* if you can't open a particular system-level midi interface - * (such as winmm), we just consider that system or API to be - * unavailable and move on without reporting an error. - */ - return; - } - - for (i = 0; i < midi_num_inputs; i++) { - wRtn = midiInGetDevCaps(i, (LPMIDIINCAPS) & midi_in_caps[i], - sizeof(MIDIINCAPS)); - if (wRtn == MMSYSERR_NOERROR) { - /* ignore errors here -- if pm_descriptor_max is exceeded, some - devices will not be accessible. */ - pm_add_device("MMSystem", midi_in_caps[i].szPname, TRUE, - (void *) i, &pm_winmm_in_dictionary); - } - } -} - - -static void pm_winmm_mapper_input() -{ - WORD wRtn; - /* Note: if MIDIMAPPER opened as input (documentation implies you - can, but current system fails to retrieve input mapper - capabilities) then you still should retrieve some formof - setup info. */ - wRtn = midiInGetDevCaps((UINT) MIDIMAPPER, - (LPMIDIINCAPS) & midi_in_mapper_caps, - sizeof(MIDIINCAPS)); - if (wRtn == MMSYSERR_NOERROR) { - pm_add_device("MMSystem", midi_in_mapper_caps.szPname, TRUE, - (void *) MIDIMAPPER, &pm_winmm_in_dictionary); - } -} - - -static void pm_winmm_general_outputs() -{ - UINT i; - DWORD wRtn; - midi_num_outputs = midiOutGetNumDevs(); - midi_out_caps = (MIDIOUTCAPS*)pm_alloc( sizeof(MIDIOUTCAPS) * midi_num_outputs ); - - if (midi_out_caps == NULL) { - /* no error is reported -- see pm_winmm_general_inputs */ - return ; - } - - for (i = 0; i < midi_num_outputs; i++) { - wRtn = midiOutGetDevCaps(i, (LPMIDIOUTCAPS) & midi_out_caps[i], - sizeof(MIDIOUTCAPS)); - if (wRtn == MMSYSERR_NOERROR) { - pm_add_device("MMSystem", midi_out_caps[i].szPname, FALSE, - (void *) i, &pm_winmm_out_dictionary); - } - } -} - - -static void pm_winmm_mapper_output() -{ - WORD wRtn; - /* Note: if MIDIMAPPER opened as output (pseudo MIDI device - maps device independent messages into device dependant ones, - via NT midimapper program) you still should get some setup info */ - wRtn = midiOutGetDevCaps((UINT) MIDIMAPPER, (LPMIDIOUTCAPS) - & midi_out_mapper_caps, sizeof(MIDIOUTCAPS)); - if (wRtn == MMSYSERR_NOERROR) { - pm_add_device("MMSystem", midi_out_mapper_caps.szPname, FALSE, - (void *) MIDIMAPPER, &pm_winmm_out_dictionary); - } -} - - -/* -========================================================================================= -host error handling -========================================================================================= -*/ -static unsigned int winmm_has_host_error(PmInternal * midi) -{ - midiwinmm_type m = (midiwinmm_type)midi->descriptor; - return m->error; -} - - -/* str_copy_len -- like strcat, but won't overrun the destination string */ -/* - * returns length of resulting string - */ -static int str_copy_len(char *dst, char *src, int len) -{ - strncpy(dst, src, len); - /* just in case suffex is greater then len, terminate with zero */ - dst[len - 1] = 0; - return strlen(dst); -} - - -static void winmm_get_host_error(PmInternal * midi, char * msg, UINT len) -{ - /* precondition: midi != NULL */ - midiwinmm_node * m = (midiwinmm_node *) midi->descriptor; - char *hdr1 = "Host error: "; - char *hdr2 = "Host callback error: "; - - msg[0] = 0; /* initialize result string to empty */ - - if (descriptors[midi->device_id].pub.input) { - /* input and output use different winmm API calls */ - if (m) { /* make sure there is an open device to examine */ - if (m->error != MMSYSERR_NOERROR) { - int n = str_copy_len(msg, hdr1, len); - /* read and record host error */ - int err = midiInGetErrorText(m->error, msg + n, len - n); - assert(err == MMSYSERR_NOERROR); - m->error = MMSYSERR_NOERROR; - } - } - } else { /* output port */ - if (m) { - if (m->error != MMSYSERR_NOERROR) { - int n = str_copy_len(msg, hdr1, len); - int err = midiOutGetErrorText(m->error, msg + n, len - n); - assert(err == MMSYSERR_NOERROR); - m->error = MMSYSERR_NOERROR; - } - } - } -} - - -/* -============================================================================= -buffer handling -============================================================================= -*/ -static MIDIHDR *allocate_buffer(long data_size) -{ - LPMIDIHDR hdr = (LPMIDIHDR) pm_alloc(MIDIHDR_SYSEX_SIZE(data_size)); - MIDIEVENT *evt; - if (!hdr) return NULL; - evt = (MIDIEVENT *) (hdr + 1); /* place MIDIEVENT after header */ - hdr->lpData = (LPSTR) evt; - hdr->dwBufferLength = MIDIHDR_SYSEX_BUFFER_LENGTH(data_size); - hdr->dwBytesRecorded = 0; - hdr->dwFlags = 0; - hdr->dwUser = hdr->dwBufferLength; - return hdr; -} - -#ifdef USE_SYSEX_BUFFERS -static MIDIHDR *allocate_sysex_buffer(long data_size) -{ - /* we're actually allocating more than data_size because the buffer - * will include the MIDIEVENT header in addition to the data - */ - LPMIDIHDR hdr = (LPMIDIHDR) pm_alloc(MIDIHDR_SYSEX_SIZE(data_size)); - MIDIEVENT *evt; - if (!hdr) return NULL; - evt = (MIDIEVENT *) (hdr + 1); /* place MIDIEVENT after header */ - hdr->lpData = (LPSTR) evt; - hdr->dwFlags = 0; - hdr->dwUser = 0; - return hdr; -} -#endif - -static PmError allocate_buffers(midiwinmm_type m, long data_size, long count) -{ - int i; - /* buffers is an array of count pointers to MIDIHDR/MIDIEVENT struct */ - m->num_buffers = 0; /* in case no memory can be allocated */ - m->buffers = (LPMIDIHDR *) pm_alloc(sizeof(LPMIDIHDR) * count); - if (!m->buffers) return pmInsufficientMemory; - m->max_buffers = count; - for (i = 0; i < count; i++) { - LPMIDIHDR hdr = allocate_buffer(data_size); - if (!hdr) { /* free everything allocated so far and return */ - for (i = i - 1; i >= 0; i--) pm_free(m->buffers[i]); - pm_free(m->buffers); - m->max_buffers = 0; - return pmInsufficientMemory; - } - m->buffers[i] = hdr; /* this may be NULL if allocation fails */ - } - m->num_buffers = count; - return pmNoError; -} - -#ifdef USE_SYSEX_BUFFERS -static PmError allocate_sysex_buffers(midiwinmm_type m, long data_size) -{ - PmError rslt = pmNoError; - /* sysex_buffers is an array of count pointers to MIDIHDR/MIDIEVENT struct */ - int i; - for (i = 0; i < NUM_SYSEX_BUFFERS; i++) { - LPMIDIHDR hdr = allocate_sysex_buffer(data_size); - - if (!hdr) rslt = pmInsufficientMemory; - m->sysex_buffers[i] = hdr; /* this may be NULL if allocation fails */ - hdr->dwFlags = 0; /* mark as free */ - } - return rslt; -} -#endif - -#ifdef USE_SYSEX_BUFFERS -static LPMIDIHDR get_free_sysex_buffer(PmInternal *midi) -{ - LPMIDIHDR r = NULL; - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - if (!m->sysex_buffers[0]) { - if (allocate_sysex_buffers(m, SYSEX_BYTES_PER_BUFFER)) { - return NULL; - } - } - /* busy wait until we find a free buffer */ - while (TRUE) { - int i; - for (i = 0; i < NUM_SYSEX_BUFFERS; i++) { - /* cycle through buffers, modulo NUM_SYSEX_BUFFERS */ - m->next_sysex_buffer++; - if (m->next_sysex_buffer >= NUM_SYSEX_BUFFERS) m->next_sysex_buffer = 0; - r = m->sysex_buffers[m->next_sysex_buffer]; - if ((r->dwFlags & MHDR_PREPARED) == 0) goto found_sysex_buffer; - } - /* after scanning every buffer and not finding anything, block */ - if (WaitForSingleObject(m->buffer_signal, 1000) == WAIT_TIMEOUT) { -#ifdef DEBUG - printf("PortMidi warning: get_free_sysex_buffer() wait timed out after 1000ms\n"); -#endif - } - } -found_sysex_buffer: - r->dwBytesRecorded = 0; - r->dwBufferLength = 0; /* changed to correct value later */ - return r; -} -#endif - -static LPMIDIHDR get_free_output_buffer(PmInternal *midi) -{ - LPMIDIHDR r = NULL; - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - while (TRUE) { - int i; - for (i = 0; i < m->num_buffers; i++) { - /* cycle through buffers, modulo m->num_buffers */ - m->next_buffer++; - if (m->next_buffer >= m->num_buffers) m->next_buffer = 0; - r = m->buffers[m->next_buffer]; - if ((r->dwFlags & MHDR_PREPARED) == 0) goto found_buffer; - } - /* after scanning every buffer and not finding anything, block */ - if (WaitForSingleObject(m->buffer_signal, 1000) == WAIT_TIMEOUT) { -#ifdef DEBUG - printf("PortMidi warning: get_free_output_buffer() wait timed out after 1000ms\n"); -#endif - /* if we're trying to send a sysex message, maybe the - * message is too big and we need more message buffers. - * Expand the buffer pool by 128KB using 1024-byte buffers. - */ - /* first, expand the buffers array if necessary */ - if (!m->buffers_expanded) { - LPMIDIHDR *new_buffers = (LPMIDIHDR *) pm_alloc( - (m->num_buffers + NUM_EXPANSION_BUFFERS) * - sizeof(LPMIDIHDR)); - /* if no memory, we could return a no-memory error, but user - * probably will be unprepared to deal with it. Maybe the - * MIDI driver is temporarily hung so we should just wait. - * I don't know the right answer, but waiting is easier. - */ - if (!new_buffers) continue; - /* copy buffers to new_buffers and replace buffers */ - memcpy(new_buffers, m->buffers, - m->num_buffers * sizeof(LPMIDIHDR)); - pm_free(m->buffers); - m->buffers = new_buffers; - m->max_buffers = m->num_buffers + NUM_EXPANSION_BUFFERS; - m->buffers_expanded = TRUE; - } - /* next, add one buffer and return it */ - if (m->num_buffers < m->max_buffers) { - r = allocate_buffer(EXPANSION_BUFFER_LEN); - /* again, if there's no memory, we may not really be - * dead -- maybe the system is temporarily hung and - * we can just wait longer for a message buffer */ - if (!r) continue; - m->buffers[m->num_buffers++] = r; - goto found_buffer; /* break out of 2 loops */ - } - /* else, we've allocated all NUM_EXPANSION_BUFFERS buffers, - * and we have no free buffers to send. We'll just keep - * polling to see if any buffers show up. - */ - } - } -found_buffer: - r->dwBytesRecorded = 0; - /* actual buffer length is saved in dwUser field */ - r->dwBufferLength = (DWORD) r->dwUser; - return r; -} - -#ifdef EXPANDING_SYSEX_BUFFERS -note: this is not working code, but might be useful if you want - to grow sysex buffers. -static PmError resize_sysex_buffer(PmInternal *midi, long old_size, long new_size) -{ - LPMIDIHDR big; - int i; - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - /* buffer must be smaller than 64k, but be also a multiple of 4 */ - if (new_size > 65520) { - if (old_size >= 65520) - return pmBufferMaxSize; - else - new_size = 65520; - } - /* allocate a bigger message */ - big = allocate_sysex_buffer(new_size); - /* printf("expand to %d bytes\n", new_size);*/ - if (!big) return pmInsufficientMemory; - m->error = midiOutPrepareHeader(m->handle.out, big, sizeof(MIDIHDR)); - if (m->error) { - pm_free(big); - return pmHostError; - } - /* make sure we're not going to overwrite any memory */ - assert(old_size <= new_size); - memcpy(big->lpData, m->hdr->lpData, old_size); - /* keep track of how many sysex bytes are in message so far */ - big->dwBytesRecorded = m->hdr->dwBytesRecorded; - big->dwBufferLength = new_size; - /* find which buffer this was, and replace it */ - for (i = 0; i < NUM_SYSEX_BUFFERS; i++) { - if (m->sysex_buffers[i] == m->hdr) { - m->sysex_buffers[i] = big; - m->sysex_buffer_size[i] = new_size; - pm_free(m->hdr); - m->hdr = big; - break; - } - } - assert(i != NUM_SYSEX_BUFFERS); - - return pmNoError; -} -#endif - -/* -========================================================================================= -begin midi input implementation -========================================================================================= -*/ - - -static PmError allocate_input_buffer(HMIDIIN h, long buffer_len) -{ - LPMIDIHDR hdr = allocate_buffer(buffer_len); - if (!hdr) return pmInsufficientMemory; - pm_hosterror = midiInPrepareHeader(h, hdr, sizeof(MIDIHDR)); - if (pm_hosterror) { - pm_free(hdr); - return (PmError) pm_hosterror; - } - pm_hosterror = midiInAddBuffer(h, hdr, sizeof(MIDIHDR)); - return (PmError) pm_hosterror; -} - - -static PmError winmm_in_open(PmInternal *midi, void *driverInfo) -{ - DWORD dwDevice; - int i = midi->device_id; - int max_sysex_len = midi->buffer_len * 4; - int num_input_buffers = max_sysex_len / INPUT_SYSEX_LEN; - midiwinmm_type m; - - dwDevice = (DWORD) descriptors[i].descriptor; - - /* create system dependent device data */ - m = (midiwinmm_type) pm_alloc(sizeof(midiwinmm_node)); /* create */ - midi->descriptor = m; - if (!m) goto no_memory; - m->handle.in = NULL; - m->buffers = NULL; /* not used for input */ - m->num_buffers = 0; /* not used for input */ - m->max_buffers = FALSE; /* not used for input */ - m->buffers_expanded = 0; /* not used for input */ - m->next_buffer = 0; /* not used for input */ - m->buffer_signal = 0; /* not used for input */ -#ifdef USE_SYSEX_BUFFERS - for (i = 0; i < NUM_SYSEX_BUFFERS; i++) - m->sysex_buffers[i] = NULL; /* not used for input */ - m->next_sysex_buffer = 0; /* not used for input */ -#endif - m->last_time = 0; - m->first_message = TRUE; /* not used for input */ - m->sysex_mode = FALSE; - m->sysex_word = 0; - m->sysex_byte_count = 0; - m->hdr = NULL; /* not used for input */ - m->sync_time = 0; - m->delta = 0; - m->error = MMSYSERR_NOERROR; - /* 4000 is based on Windows documentation -- that's the value used in the - memory manager. It's small enough that it should not hurt performance even - if it's not optimal. - */ - InitializeCriticalSectionAndSpinCount(&m->lock, 4000); - /* open device */ - pm_hosterror = midiInOpen( - &(m->handle.in), /* input device handle */ - dwDevice, /* device ID */ - (DWORD_PTR) winmm_in_callback, /* callback address */ - (DWORD_PTR) midi, /* callback instance data */ - CALLBACK_FUNCTION); /* callback is a procedure */ - if (pm_hosterror) goto free_descriptor; - - if (num_input_buffers < MIN_INPUT_BUFFERS) - num_input_buffers = MIN_INPUT_BUFFERS; - for (i = 0; i < num_input_buffers; i++) { - if (allocate_input_buffer(m->handle.in, INPUT_SYSEX_LEN)) { - /* either pm_hosterror was set, or the proper return code - is pmInsufficientMemory */ - goto close_device; - } - } - /* start device */ - pm_hosterror = midiInStart(m->handle.in); - if (pm_hosterror) goto reset_device; - return pmNoError; - - /* undo steps leading up to the detected error */ -reset_device: - /* ignore return code (we already have an error to report) */ - midiInReset(m->handle.in); -close_device: - midiInClose(m->handle.in); /* ignore return code */ -free_descriptor: - midi->descriptor = NULL; - pm_free(m); -no_memory: - if (pm_hosterror) { - int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - assert(err == MMSYSERR_NOERROR); - return pmHostError; - } - /* if !pm_hosterror, then the error must be pmInsufficientMemory */ - return pmInsufficientMemory; - /* note: if we return an error code, the device will be - closed and memory will be freed. It's up to the caller - to free the parameter midi */ -} - -static PmError winmm_in_poll(PmInternal *midi) { - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - return (PmError) m->error; -} - - - -/* winmm_in_close -- close an open midi input device */ -/* - * assume midi is non-null (checked by caller) - */ -static PmError winmm_in_close(PmInternal *midi) -{ - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - if (!m) return pmBadPtr; - /* device to close */ - if (pm_hosterror = midiInStop(m->handle.in)) { - midiInReset(m->handle.in); /* try to reset and close port */ - midiInClose(m->handle.in); - } else if (pm_hosterror = midiInReset(m->handle.in)) { - midiInClose(m->handle.in); /* best effort to close midi port */ - } else { - pm_hosterror = midiInClose(m->handle.in); - } - midi->descriptor = NULL; - DeleteCriticalSection(&m->lock); - pm_free(m); /* delete */ - if (pm_hosterror) { - int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - assert(err == MMSYSERR_NOERROR); - return pmHostError; - } - return pmNoError; -} - - -/* Callback function executed via midiInput SW interrupt (via midiInOpen). */ -static void FAR PASCAL winmm_in_callback( - HMIDIIN hMidiIn, /* midiInput device Handle */ - WORD wMsg, /* midi msg */ - DWORD dwInstance, /* application data */ - DWORD dwParam1, /* MIDI data */ - DWORD dwParam2) /* device timestamp (wrt most recent midiInStart) */ -{ - static int entry = 0; - PmInternal *midi = (PmInternal *) dwInstance; - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - - /* NOTE: we do not just EnterCriticalSection() here because an - * MIM_CLOSE message arrives when the port is closed, but then - * the m->lock has been destroyed. - */ - - switch (wMsg) { - case MIM_DATA: { - /* if this callback is reentered with data, we're in trouble. - * It's hard to imagine that Microsoft would allow callbacks - * to be reentrant -- isn't the model that this is like a - * hardware interrupt? -- but I've seen reentrant behavior - * using a debugger, so it happens. - */ - long new_driver_time; - EnterCriticalSection(&m->lock); - - /* dwParam1 is MIDI data received, packed into DWORD w/ 1st byte of - message LOB; - dwParam2 is time message received by input device driver, specified - in [ms] from when midiInStart called. - each message is expanded to include the status byte */ - - new_driver_time = dwParam2; - - if ((dwParam1 & 0x80) == 0) { - /* not a status byte -- ignore it. This happened running the - sysex.c test under Win2K with MidiMan USB 1x1 interface, - but I can't reproduce it. -RBD - */ - /* printf("non-status byte found\n"); */ - } else { /* data to process */ - PmEvent event; - if (midi->time_proc) - dwParam2 = (*midi->time_proc)(midi->time_info); - event.timestamp = dwParam2; - event.message = dwParam1; - pm_read_short(midi, &event); - } - LeaveCriticalSection(&m->lock); - break; - } - case MIM_LONGDATA: { - MIDIHDR *lpMidiHdr = (MIDIHDR *) dwParam1; - unsigned char *data = (unsigned char *) lpMidiHdr->lpData; - unsigned int processed = 0; - int remaining = lpMidiHdr->dwBytesRecorded; - - EnterCriticalSection(&m->lock); - /* printf("midi_in_callback -- lpMidiHdr %x, %d bytes, %2x...\n", - lpMidiHdr, lpMidiHdr->dwBytesRecorded, *data); */ - if (midi->time_proc) - dwParam2 = (*midi->time_proc)(midi->time_info); - /* can there be more than one message in one buffer? */ - /* assume yes and iterate through them */ - while (remaining > 0) { - unsigned int amt = pm_read_bytes(midi, data + processed, - remaining, dwParam2); - remaining -= amt; - processed += amt; - } - - /* when a device is closed, the pending MIM_LONGDATA buffers are - returned to this callback with dwBytesRecorded == 0. In this - case, we do not want to send them back to the interface (if - we do, the interface will not close, and Windows OS may hang). */ - if (lpMidiHdr->dwBytesRecorded > 0) { - MMRESULT rslt; - lpMidiHdr->dwBytesRecorded = 0; - lpMidiHdr->dwFlags = 0; - - /* note: no error checking -- can this actually fail? */ - rslt = midiInPrepareHeader(hMidiIn, lpMidiHdr, sizeof(MIDIHDR)); - assert(rslt == MMSYSERR_NOERROR); - /* note: I don't think this can fail except possibly for - * MMSYSERR_NOMEM, but the pain of reporting this - * unlikely but probably catastrophic error does not seem - * worth it. - */ - rslt = midiInAddBuffer(hMidiIn, lpMidiHdr, sizeof(MIDIHDR)); - assert(rslt == MMSYSERR_NOERROR); - LeaveCriticalSection(&m->lock); - } else { - midiInUnprepareHeader(hMidiIn,lpMidiHdr,sizeof(MIDIHDR)); - LeaveCriticalSection(&m->lock); - pm_free(lpMidiHdr); - } - break; - } - case MIM_OPEN: - break; - case MIM_CLOSE: - break; - case MIM_ERROR: - /* printf("MIM_ERROR\n"); */ - break; - case MIM_LONGERROR: - /* printf("MIM_LONGERROR\n"); */ - break; - default: - break; - } -} - -/* -========================================================================================= -begin midi output implementation -========================================================================================= -*/ - -/* begin helper routines used by midiOutStream interface */ - -/* add_to_buffer -- adds timestamped short msg to buffer, returns fullp */ -static int add_to_buffer(midiwinmm_type m, LPMIDIHDR hdr, - unsigned long delta, unsigned long msg) -{ - unsigned long *ptr = (unsigned long *) - (hdr->lpData + hdr->dwBytesRecorded); - *ptr++ = delta; /* dwDeltaTime */ - *ptr++ = 0; /* dwStream */ - *ptr++ = msg; /* dwEvent */ - hdr->dwBytesRecorded += 3 * sizeof(long); - /* if the addition of three more words (a message) would extend beyond - the buffer length, then return TRUE (full) - */ - return hdr->dwBytesRecorded + 3 * sizeof(long) > hdr->dwBufferLength; -} - - -static PmTimestamp pm_time_get(midiwinmm_type m) -{ - MMTIME mmtime; - MMRESULT wRtn; - mmtime.wType = TIME_TICKS; - mmtime.u.ticks = 0; - wRtn = midiStreamPosition(m->handle.stream, &mmtime, sizeof(mmtime)); - assert(wRtn == MMSYSERR_NOERROR); - return mmtime.u.ticks; -} - - -/* end helper routines used by midiOutStream interface */ - - -static PmError winmm_out_open(PmInternal *midi, void *driverInfo) -{ - DWORD dwDevice; - int i = midi->device_id; - midiwinmm_type m; - MIDIPROPTEMPO propdata; - MIDIPROPTIMEDIV divdata; - int max_sysex_len = midi->buffer_len * 4; - int output_buffer_len; - int num_buffers; - dwDevice = (DWORD) descriptors[i].descriptor; - - /* create system dependent device data */ - m = (midiwinmm_type) pm_alloc(sizeof(midiwinmm_node)); /* create */ - midi->descriptor = m; - if (!m) goto no_memory; - m->handle.out = NULL; - m->buffers = NULL; - m->num_buffers = 0; - m->max_buffers = 0; - m->buffers_expanded = FALSE; - m->next_buffer = 0; -#ifdef USE_SYSEX_BUFFERS - m->sysex_buffers[0] = NULL; - m->sysex_buffers[1] = NULL; - m->next_sysex_buffer = 0; -#endif - m->last_time = 0; - m->first_message = TRUE; /* we treat first message as special case */ - m->sysex_mode = FALSE; - m->sysex_word = 0; - m->sysex_byte_count = 0; - m->hdr = NULL; - m->sync_time = 0; - m->delta = 0; - m->error = MMSYSERR_NOERROR; - - /* create a signal */ - m->buffer_signal = CreateEvent(NULL, FALSE, FALSE, NULL); - - /* this should only fail when there are very serious problems */ - assert(m->buffer_signal); - - /* open device */ - if (midi->latency == 0) { - /* use simple midi out calls */ - pm_hosterror = midiOutOpen( - (LPHMIDIOUT) & m->handle.out, /* device Handle */ - dwDevice, /* device ID */ - /* note: same callback fn as for StreamOpen: */ - (DWORD_PTR) winmm_streamout_callback, /* callback fn */ - (DWORD_PTR) midi, /* callback instance data */ - CALLBACK_FUNCTION); /* callback type */ - } else { - /* use stream-based midi output (schedulable in future) */ - pm_hosterror = midiStreamOpen( - &m->handle.stream, /* device Handle */ - (LPUINT) & dwDevice, /* device ID pointer */ - 1, /* reserved, must be 1 */ - (DWORD_PTR) winmm_streamout_callback, - (DWORD_PTR) midi, /* callback instance data */ - CALLBACK_FUNCTION); - } - if (pm_hosterror != MMSYSERR_NOERROR) { - goto free_descriptor; - } - - if (midi->latency == 0) { - num_buffers = NUM_SIMPLE_SYSEX_BUFFERS; - output_buffer_len = max_sysex_len / num_buffers; - if (output_buffer_len < MIN_SIMPLE_SYSEX_LEN) - output_buffer_len = MIN_SIMPLE_SYSEX_LEN; - } else { - long dur = 0; - num_buffers = max(midi->buffer_len, midi->latency / 2); - if (num_buffers < MIN_STREAM_BUFFERS) - num_buffers = MIN_STREAM_BUFFERS; - output_buffer_len = STREAM_BUFFER_LEN; - - propdata.cbStruct = sizeof(MIDIPROPTEMPO); - propdata.dwTempo = 480000; /* microseconds per quarter */ - pm_hosterror = midiStreamProperty(m->handle.stream, - (LPBYTE) & propdata, - MIDIPROP_SET | MIDIPROP_TEMPO); - if (pm_hosterror) goto close_device; - - divdata.cbStruct = sizeof(MIDIPROPTEMPO); - divdata.dwTimeDiv = 480; /* divisions per quarter */ - pm_hosterror = midiStreamProperty(m->handle.stream, - (LPBYTE) & divdata, - MIDIPROP_SET | MIDIPROP_TIMEDIV); - if (pm_hosterror) goto close_device; - } - /* allocate buffers */ - if (allocate_buffers(m, output_buffer_len, num_buffers)) - goto free_buffers; - /* start device */ - if (midi->latency != 0) { - pm_hosterror = midiStreamRestart(m->handle.stream); - if (pm_hosterror != MMSYSERR_NOERROR) goto free_buffers; - } - return pmNoError; - -free_buffers: - /* buffers are freed below by winmm_out_delete */ -close_device: - midiOutClose(m->handle.out); -free_descriptor: - midi->descriptor = NULL; - winmm_out_delete(midi); /* frees buffers and m */ -no_memory: - if (pm_hosterror) { - int err = midiOutGetErrorText(pm_hosterror, (char *) pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - assert(err == MMSYSERR_NOERROR); - return pmHostError; - } - return pmInsufficientMemory; -} - - -/* winmm_out_delete -- carefully free data associated with midi */ -/**/ -static void winmm_out_delete(PmInternal *midi) -{ - int i; - /* delete system dependent device data */ - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - if (m) { - if (m->buffer_signal) { - /* don't report errors -- better not to stop cleanup */ - CloseHandle(m->buffer_signal); - } - /* if using stream output, free buffers */ - for (i = 0; i < m->num_buffers; i++) { - if (m->buffers[i]) pm_free(m->buffers[i]); - } - m->num_buffers = 0; - pm_free(m->buffers); - m->max_buffers = 0; -#ifdef USE_SYSEX_BUFFERS - /* free sysex buffers */ - for (i = 0; i < NUM_SYSEX_BUFFERS; i++) { - if (m->sysex_buffers[i]) pm_free(m->sysex_buffers[i]); - } -#endif - } - midi->descriptor = NULL; - pm_free(m); /* delete */ -} - - -/* see comments for winmm_in_close */ -static PmError winmm_out_close(PmInternal *midi) -{ - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - if (m->handle.out) { - /* device to close */ - if (midi->latency == 0) { - pm_hosterror = midiOutClose(m->handle.out); - } else { - pm_hosterror = midiStreamClose(m->handle.stream); - } - /* regardless of outcome, free memory */ - winmm_out_delete(midi); - } - if (pm_hosterror) { - int err = midiOutGetErrorText(pm_hosterror, - (char *) pm_hosterror_text, - PM_HOST_ERROR_MSG_LEN); - assert(err == MMSYSERR_NOERROR); - return pmHostError; - } - return pmNoError; -} - - -static PmError winmm_out_abort(PmInternal *midi) -{ - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - m->error = MMSYSERR_NOERROR; - - /* only stop output streams */ - if (midi->latency > 0) { - m->error = midiStreamStop(m->handle.stream); - } - return m->error ? pmHostError : pmNoError; -} - - -static PmError winmm_write_flush(PmInternal *midi, PmTimestamp timestamp) -{ - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - assert(m); - if (m->hdr) { - m->error = midiOutPrepareHeader(m->handle.out, m->hdr, - sizeof(MIDIHDR)); - if (m->error) { - /* do not send message */ - } else if (midi->latency == 0) { - /* As pointed out by Nigel Brown, 20Sep06, dwBytesRecorded - * should be zero. This is set in get_free_sysex_buffer(). - * The msg length goes in dwBufferLength in spite of what - * Microsoft documentation says (or doesn't say). */ - m->hdr->dwBufferLength = m->hdr->dwBytesRecorded; - m->hdr->dwBytesRecorded = 0; - m->error = midiOutLongMsg(m->handle.out, m->hdr, sizeof(MIDIHDR)); - } else { - m->error = midiStreamOut(m->handle.stream, m->hdr, - sizeof(MIDIHDR)); - } - midi->fill_base = NULL; - m->hdr = NULL; - if (m->error) { - m->hdr->dwFlags = 0; /* release the buffer */ - return pmHostError; - } - } - return pmNoError; -} - - - -#ifdef GARBAGE -static PmError winmm_write_sysex_byte(PmInternal *midi, unsigned char byte) -{ - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - unsigned char *msg_buffer; - - /* at the beginning of sysex, m->hdr is NULL */ - if (!m->hdr) { /* allocate a buffer if none allocated yet */ - m->hdr = get_free_output_buffer(midi); - if (!m->hdr) return pmInsufficientMemory; - m->sysex_byte_count = 0; - } - /* figure out where to write byte */ - msg_buffer = (unsigned char *) (m->hdr->lpData); - assert(m->hdr->lpData == (char *) (m->hdr + 1)); - - /* check for overflow */ - if (m->sysex_byte_count >= m->hdr->dwBufferLength) { - /* allocate a bigger message -- double it every time */ - LPMIDIHDR big = allocate_buffer(m->sysex_byte_count * 2); - /* printf("expand to %d bytes\n", m->sysex_byte_count * 2); */ - if (!big) return pmInsufficientMemory; - m->error = midiOutPrepareHeader(m->handle.out, big, - sizeof(MIDIHDR)); - if (m->error) { - m->hdr = NULL; - return pmHostError; - } - memcpy(big->lpData, msg_buffer, m->sysex_byte_count); - msg_buffer = (unsigned char *) (big->lpData); - if (m->buffers[0] == m->hdr) { - m->buffers[0] = big; - pm_free(m->hdr); - /* printf("freed m->hdr\n"); */ - } else if (m->buffers[1] == m->hdr) { - m->buffers[1] = big; - pm_free(m->hdr); - /* printf("freed m->hdr\n"); */ - } - m->hdr = big; - } - - /* append byte to message */ - msg_buffer[m->sysex_byte_count++] = byte; - - /* see if we have a complete message */ - if (byte == MIDI_EOX) { - m->hdr->dwBytesRecorded = m->sysex_byte_count; - /* - { int i; int len = m->hdr->dwBytesRecorded; - printf("OutLongMsg %d ", len); - for (i = 0; i < len; i++) { - printf("%2x ", msg_buffer[i]); - } - } - */ - m->error = midiOutLongMsg(m->handle.out, m->hdr, sizeof(MIDIHDR)); - m->hdr = NULL; /* stop using this message buffer */ - if (m->error) return pmHostError; - } - return pmNoError; -} -#endif - - -static PmError winmm_write_short(PmInternal *midi, PmEvent *event) -{ - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - PmError rslt = pmNoError; - assert(m); - - if (midi->latency == 0) { /* use midiOut interface, ignore timestamps */ - m->error = midiOutShortMsg(m->handle.out, event->message); - if (m->error) rslt = pmHostError; - } else { /* use midiStream interface -- pass data through buffers */ - unsigned long when = event->timestamp; - unsigned long delta; - int full; - if (when == 0) when = midi->now; - /* when is in real_time; translate to intended stream time */ - when = when + m->delta + midi->latency; - /* make sure we don't go backward in time */ - if (when < m->last_time) when = m->last_time; - delta = when - m->last_time; - m->last_time = when; - /* before we insert any data, we must have a buffer */ - if (m->hdr == NULL) { - /* stream interface: buffers allocated when stream is opened */ - m->hdr = get_free_output_buffer(midi); - } - full = add_to_buffer(m, m->hdr, delta, event->message); - if (full) rslt = winmm_write_flush(midi, when); - } - return rslt; -} - -#define winmm_begin_sysex winmm_write_flush -#ifndef winmm_begin_sysex -static PmError winmm_begin_sysex(PmInternal *midi, PmTimestamp timestamp) -{ - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - PmError rslt = pmNoError; - - if (midi->latency == 0) { - /* do nothing -- it's handled in winmm_write_byte */ - } else { - /* sysex expects an empty sysex buffer, so send whatever is here */ - rslt = winmm_write_flush(midi); - } - return rslt; -} -#endif - -static PmError winmm_end_sysex(PmInternal *midi, PmTimestamp timestamp) -{ - /* could check for callback_error here, but I haven't checked - * what happens if we exit early and don't finish the sysex msg - * and clean up - */ - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - PmError rslt = pmNoError; - LPMIDIHDR hdr = m->hdr; - if (!hdr) return rslt; /* something bad happened earlier, - do not report an error because it would have been - reported (at least) once already */ - /* a(n old) version of MIDI YOKE requires a zero byte after - * the sysex message, but do not increment dwBytesRecorded: */ - hdr->lpData[hdr->dwBytesRecorded] = 0; - if (midi->latency == 0) { -#ifdef DEBUG_PRINT_BEFORE_SENDING_SYSEX - /* DEBUG CODE: */ - { int i; int len = m->hdr->dwBufferLength; - printf("OutLongMsg %d ", len); - for (i = 0; i < len; i++) { - printf("%2x ", (unsigned char) (m->hdr->lpData[i])); - } - } -#endif - } else { - /* Using stream interface. There are accumulated bytes in m->hdr - to send using midiStreamOut - */ - /* add bytes recorded to MIDIEVENT length, but don't - count the MIDIEVENT data (3 longs) */ - MIDIEVENT *evt = (MIDIEVENT *) (hdr->lpData); - evt->dwEvent += hdr->dwBytesRecorded - 3 * sizeof(long); - /* round up BytesRecorded to multiple of 4 */ - hdr->dwBytesRecorded = (hdr->dwBytesRecorded + 3) & ~3; - } - rslt = winmm_write_flush(midi, timestamp); - return rslt; -} - - -static PmError winmm_write_byte(PmInternal *midi, unsigned char byte, - PmTimestamp timestamp) -{ - /* write a sysex byte */ - PmError rslt = pmNoError; - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - LPMIDIHDR hdr = m->hdr; - unsigned char *msg_buffer; - assert(m); - if (!hdr) { - m->hdr = hdr = get_free_output_buffer(midi); - assert(hdr); - midi->fill_base = (unsigned char *) m->hdr->lpData; - midi->fill_offset_ptr = (uint32_t*) &(hdr->dwBytesRecorded); - /* when buffer fills, Pm_WriteSysEx will revert to calling - * pmwin_write_byte, which expect to have space, so leave - * one byte free for pmwin_write_byte. Leave another byte - * of space for zero after message to make early version of - * MIDI YOKE driver happy -- therefore dwBufferLength - 2 */ - midi->fill_length = hdr->dwBufferLength - 2; - if (midi->latency != 0) { - unsigned long when = (unsigned long) timestamp; - unsigned long delta; - unsigned long *ptr; - if (when == 0) when = midi->now; - /* when is in real_time; translate to intended stream time */ - when = when + m->delta + midi->latency; - /* make sure we don't go backward in time */ - if (when < m->last_time) when = m->last_time; - delta = when - m->last_time; - m->last_time = when; - - ptr = (unsigned long *) hdr->lpData; - *ptr++ = delta; - *ptr++ = 0; - *ptr = MEVT_F_LONG; - hdr->dwBytesRecorded = 3 * sizeof(long); - /* data will be added at an offset of dwBytesRecorded ... */ - } - } - /* add the data byte */ - msg_buffer = (unsigned char *) (hdr->lpData); - msg_buffer[hdr->dwBytesRecorded++] = byte; - - /* see if buffer is full, leave one byte extra for pad */ - if (hdr->dwBytesRecorded >= hdr->dwBufferLength - 1) { - /* write what we've got and continue */ - rslt = winmm_end_sysex(midi, timestamp); - } - return rslt; -} - -#ifdef EXPANDING_SYSEX_BUFFERS -note: this code is here as an aid in case you want sysex buffers - to expand to hold large messages completely. If so, you - will want to change SYSEX_BYTES_PER_BUFFER above to some - variable that remembers the buffer size. A good place to - put this value would be in the hdr->dwUser field. - - rslt = resize_sysex_buffer(midi, m->sysex_byte_count, - m->sysex_byte_count * 2); - - if (rslt == pmBufferMaxSize) /* if the buffer can't be resized */ -#endif -#ifdef EXPANDING_SYSEX_BUFFERS - int bytesRecorded = hdr->dwBytesRecorded; /* this field gets wiped out, so we'll save it */ - rslt = resize_sysex_buffer(midi, bytesRecorded, 2 * bytesRecorded); - hdr->dwBytesRecorded = bytesRecorded; - - if (rslt == pmBufferMaxSize) /* if buffer can't be resized */ -#endif - - - -static PmTimestamp winmm_synchronize(PmInternal *midi) -{ - midiwinmm_type m; - unsigned long pm_stream_time_2; - unsigned long real_time; - unsigned long pm_stream_time; - - /* only synchronize if we are using stream interface */ - if (midi->latency == 0) return 0; - - /* figure out the time */ - m = (midiwinmm_type) midi->descriptor; - pm_stream_time_2 = pm_time_get(m); - - do { - /* read real_time between two reads of stream time */ - pm_stream_time = pm_stream_time_2; - real_time = (*midi->time_proc)(midi->time_info); - pm_stream_time_2 = pm_time_get(m); - /* repeat if more than 1ms elapsed */ - } while (pm_stream_time_2 > pm_stream_time + 1); - m->delta = pm_stream_time - real_time; - m->sync_time = real_time; - return real_time; -} - -#ifdef USE_SYSEX_BUFFERS -/* winmm_out_callback -- recycle sysex buffers */ -static void CALLBACK winmm_out_callback(HMIDIOUT hmo, UINT wMsg, - DWORD dwInstance, DWORD dwParam1, - DWORD dwParam2) -{ - PmInternal *midi = (PmInternal *) dwInstance; - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - LPMIDIHDR hdr = (LPMIDIHDR) dwParam1; - int err = 0; /* set to 0 so that no buffer match will also be an error */ - - /* Future optimization: eliminate UnprepareHeader calls -- they aren't - necessary; however, this code uses the prepared-flag to indicate which - buffers are free, so we need to do something to flag empty buffers if - we leave them prepared - */ - /* - printf("out_callback: hdr %x, wMsg %x, MOM_DONE %x\n", - hdr, wMsg, MOM_DONE); - */ - if (wMsg == MOM_DONE) { - MMRESULT ret = midiOutUnprepareHeader(m->handle.out, hdr, - sizeof(MIDIHDR)); - assert(ret == MMSYSERR_NOERROR); - } - /* notify waiting sender that a buffer is available */ - err = SetEvent(m->buffer_signal); - assert(err); /* false -> error */ -} -#endif - -/* winmm_streamout_callback -- unprepare (free) buffer header */ -static void CALLBACK winmm_streamout_callback(HMIDIOUT hmo, UINT wMsg, - DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) -{ - PmInternal *midi = (PmInternal *) dwInstance; - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - LPMIDIHDR hdr = (LPMIDIHDR) dwParam1; - int err; - - /* Even if an error is pending, I think we should unprepare msgs and - signal their arrival - */ - /* printf("streamout_callback: hdr %x, wMsg %x, MOM_DONE %x\n", - hdr, wMsg, MOM_DONE); */ - if (wMsg == MOM_DONE) { - MMRESULT ret = midiOutUnprepareHeader(m->handle.out, hdr, - sizeof(MIDIHDR)); - assert(ret == MMSYSERR_NOERROR); - } - /* signal client in case it is blocked waiting for buffer */ - err = SetEvent(m->buffer_signal); - assert(err); /* false -> error */ -} - - -/* -========================================================================================= -begin exported functions -========================================================================================= -*/ - -#define winmm_in_abort pm_fail_fn -pm_fns_node pm_winmm_in_dictionary = { - none_write_short, - none_sysex, - none_sysex, - none_write_byte, - none_write_short, - none_write_flush, - winmm_synchronize, - winmm_in_open, - winmm_in_abort, - winmm_in_close, - winmm_in_poll, - winmm_has_host_error, - winmm_get_host_error - }; - -pm_fns_node pm_winmm_out_dictionary = { - winmm_write_short, - winmm_begin_sysex, - winmm_end_sysex, - winmm_write_byte, - winmm_write_short, /* short realtime message */ - winmm_write_flush, - winmm_synchronize, - winmm_out_open, - winmm_out_abort, - winmm_out_close, - none_poll, - winmm_has_host_error, - winmm_get_host_error - }; - - -/* initialize winmm interface. Note that if there is something wrong - with winmm (e.g. it is not supported or installed), it is not an - error. We should simply return without having added any devices to - the table. Hence, no error code is returned. Furthermore, this init - code is called along with every other supported interface, so the - user would have a very hard time figuring out what hardware and API - generated the error. Finally, it would add complexity to pmwin.c to - remember where the error code came from in order to convert to text. - */ -void pm_winmm_init( void ) -{ - pm_winmm_mapper_input(); - pm_winmm_mapper_output(); - pm_winmm_general_inputs(); - pm_winmm_general_outputs(); -} - - -/* no error codes are returned, even if errors are encountered, because - there is probably nothing the user could do (e.g. it would be an error - to retry. - */ -void pm_winmm_term( void ) -{ - int i; -#ifdef DEBUG - char msg[PM_HOST_ERROR_MSG_LEN]; -#endif - int doneAny = 0; -#ifdef DEBUG - printf("pm_winmm_term called\n"); -#endif - for (i = 0; i < pm_descriptor_index; i++) { - PmInternal * midi = (PmInternal*) descriptors[i].internalDescriptor; - if (midi) { - midiwinmm_type m = (midiwinmm_type) midi->descriptor; - if (m->handle.out) { - /* close next open device*/ -#ifdef DEBUG - if (doneAny == 0) { - printf("begin closing open devices...\n"); - doneAny = 1; - } - /* report any host errors; this EXTEREMELY useful when - trying to debug client app */ - if (winmm_has_host_error(midi)) { - winmm_get_host_error(midi, msg, PM_HOST_ERROR_MSG_LEN); - printf("%s\n", msg); - } -#endif - /* close all open ports */ - (*midi->dictionary->close)(midi); - } - } - } - if (midi_in_caps) { - pm_free(midi_in_caps); - midi_in_caps = NULL; - } - if (midi_out_caps) { - pm_free(midi_out_caps); - midi_out_caps = NULL; - } -#ifdef DEBUG - if (doneAny) { - printf("warning: devices were left open. They have been closed.\n"); - } - printf("pm_winmm_term exiting\n"); -#endif - pm_descriptor_index = 0; -} diff --git a/libs/backends/wavesaudio/portmidi/src/pm_win/pmwinmm.h b/libs/backends/wavesaudio/portmidi/src/pm_win/pmwinmm.h deleted file mode 100644 index 94742001bc..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/pm_win/pmwinmm.h +++ /dev/null @@ -1,5 +0,0 @@ -/* midiwin32.h -- system-specific definitions */ - -void pm_winmm_init( void ); -void pm_winmm_term( void ); - diff --git a/libs/backends/wavesaudio/portmidi/src/porttime/ptmacosx_mach.c b/libs/backends/wavesaudio/portmidi/src/porttime/ptmacosx_mach.c deleted file mode 100644 index 873a78f59d..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/porttime/ptmacosx_mach.c +++ /dev/null @@ -1,131 +0,0 @@ -/* ptmacosx.c -- portable timer implementation for mac os x */ - -#include -#include -#include - -#import -#import -#import -#import -#include - -#include "porttime.h" -#include "sys/time.h" -#include "pthread.h" - -#define NSEC_PER_MSEC 1000000 -#define THREAD_IMPORTANCE 30 - -static int time_started_flag = FALSE; -static UInt64 start_time; -static pthread_t pt_thread_pid; - -/* note that this is static data -- we only need one copy */ -typedef struct { - int id; - int resolution; - PtCallback *callback; - void *userData; -} pt_callback_parameters; - -static int pt_callback_proc_id = 0; - -static void *Pt_CallbackProc(void *p) -{ - pt_callback_parameters *parameters = (pt_callback_parameters *) p; - int mytime = 1; - - kern_return_t error; - thread_extended_policy_data_t extendedPolicy; - thread_precedence_policy_data_t precedencePolicy; - - extendedPolicy.timeshare = 0; - error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY, - (thread_policy_t)&extendedPolicy, - THREAD_EXTENDED_POLICY_COUNT); - if (error != KERN_SUCCESS) { - mach_error("Couldn't set thread timeshare policy", error); - } - - precedencePolicy.importance = THREAD_IMPORTANCE; - error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY, - (thread_policy_t)&precedencePolicy, - THREAD_PRECEDENCE_POLICY_COUNT); - if (error != KERN_SUCCESS) { - mach_error("Couldn't set thread precedence policy", error); - } - - - /* to kill a process, just increment the pt_callback_proc_id */ - /* printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id, parameters->id); */ - while (pt_callback_proc_id == parameters->id) { - /* wait for a multiple of resolution ms */ - UInt64 wait_time; - int delay = mytime++ * parameters->resolution - Pt_Time(); - PtTimestamp timestamp; - if (delay < 0) delay = 0; - wait_time = AudioConvertNanosToHostTime((UInt64)delay * NSEC_PER_MSEC); - wait_time += AudioGetCurrentHostTime(); - error = mach_wait_until(wait_time); - timestamp = Pt_Time(); - (*(parameters->callback))(timestamp, parameters->userData); - } - free(parameters); - return NULL; -} - - -PtError Pt_Start(int resolution, PtCallback *callback, void *userData) -{ - if (time_started_flag) return ptAlreadyStarted; - start_time = AudioGetCurrentHostTime(); - - if (callback) { - int res; - pt_callback_parameters *parms; - - parms = (pt_callback_parameters *) malloc(sizeof(pt_callback_parameters)); - if (!parms) return ptInsufficientMemory; - parms->id = pt_callback_proc_id; - parms->resolution = resolution; - parms->callback = callback; - parms->userData = userData; - res = pthread_create(&pt_thread_pid, NULL, Pt_CallbackProc, parms); - if (res != 0) return ptHostError; - } - - time_started_flag = TRUE; - return ptNoError; -} - - -PtError Pt_Stop() -{ - /* printf("Pt_Stop called\n"); */ - pt_callback_proc_id++; - pthread_join(pt_thread_pid, NULL); - time_started_flag = FALSE; - return ptNoError; -} - - -int Pt_Started() -{ - return time_started_flag; -} - - -PtTimestamp Pt_Time() -{ - UInt64 clock_time, nsec_time; - clock_time = AudioGetCurrentHostTime() - start_time; - nsec_time = AudioConvertHostTimeToNanos(clock_time); - return (PtTimestamp)(nsec_time / NSEC_PER_MSEC); -} - - -void Pt_Sleep(int32_t duration) -{ - usleep(duration * 1000); -} diff --git a/libs/backends/wavesaudio/portmidi/src/porttime/ptwinmm.c b/libs/backends/wavesaudio/portmidi/src/porttime/ptwinmm.c deleted file mode 100644 index 060920f8d0..0000000000 --- a/libs/backends/wavesaudio/portmidi/src/porttime/ptwinmm.c +++ /dev/null @@ -1,71 +0,0 @@ -/* ptwinmm.c -- portable timer implementation for win32 */ - - -#include "porttime.h" - -#include -#include -#include - -TIMECAPS caps; - -static long time_offset = 0; -static int time_started_flag = FALSE; -static long time_resolution; -static MMRESULT timer_id; -static PtCallback *time_callback; - -void CALLBACK winmm_time_callback(UINT uID, UINT uMsg, DWORD_PTR dwUser, - DWORD_PTR dw1, DWORD_PTR dw2) -{ - (*time_callback)(Pt_Time(), (void *) dwUser); -} - - -PMEXPORT PtError Pt_Start(int resolution, PtCallback *callback, void *userData) -{ - if (time_started_flag) return ptAlreadyStarted; - timeBeginPeriod(resolution); - time_resolution = resolution; - time_offset = timeGetTime(); - time_started_flag = TRUE; - time_callback = callback; - if (callback) { - timer_id = timeSetEvent(resolution, 1, winmm_time_callback, - (DWORD_PTR) userData, TIME_PERIODIC | TIME_CALLBACK_FUNCTION); - if (!timer_id) return ptHostError; - } - return ptNoError; -} - - -PMEXPORT PtError Pt_Stop() -{ - if (!time_started_flag) return ptAlreadyStopped; - if (time_callback && timer_id) { - timeKillEvent(timer_id); - time_callback = NULL; - timer_id = 0; - } - time_started_flag = FALSE; - timeEndPeriod(time_resolution); - return ptNoError; -} - - -PMEXPORT int Pt_Started() -{ - return time_started_flag; -} - - -PMEXPORT PtTimestamp Pt_Time() -{ - return timeGetTime() - time_offset; -} - - -PMEXPORT void Pt_Sleep(int32_t duration) -{ - Sleep(duration); -} diff --git a/libs/backends/wavesaudio/waves_audiobackend.cc b/libs/backends/wavesaudio/waves_audiobackend.cc deleted file mode 100644 index 2c6824e4b2..0000000000 --- a/libs/backends/wavesaudio/waves_audiobackend.cc +++ /dev/null @@ -1,1355 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "waves_audiobackend.h" -#include "waves_audioport.h" -#include "waves_midiport.h" - -#include "ardour/runtime_functions.h" - -#ifdef COMPILER_MSVC -#include -#define sleep(X) Sleep((X) * 1000) -// JE - Perhaps we should be using Glib::usleep() here, rather than sleep()?? But -// that would make the Waves backend dependent on Glib (which is isn't, currently). -#endif - -using namespace ARDOUR; - -#if defined __MINGW64__ || defined __MINGW32__ - extern "C" __declspec(dllexport) ARDOUR::AudioBackendInfo* descriptor () -#else - extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor () -#endif -{ - // COMMENTED DBG LOGS */ std::cout << "waves_backend.dll : ARDOUR::AudioBackendInfo* descriptor (): " << std::endl; - return &WavesAudioBackend::backend_info (); -} - -void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reason, void* parameter) -{ - switch (reason) { - case WCMRAudioDeviceManagerClient::DeviceDebugInfo: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceDebugInfo -- " << (char*)parameter << std::endl; - break; - case WCMRAudioDeviceManagerClient::BufferSizeChanged: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::BufferSizeChanged: " << *(int*)parameter << std::endl; - _buffer_size_change(*(int*)parameter); - break; - case WCMRAudioDeviceManagerClient::RequestReset: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestReset" << std::endl; - engine.request_backend_reset(); - break; - case WCMRAudioDeviceManagerClient::RequestResync: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestResync" << std::endl; - break; - case WCMRAudioDeviceManagerClient::SamplingRateChanged: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::SamplingRateChanged: " << *(float*)parameter << std::endl; - _sample_rate_change(*(float*)parameter); - break; - case WCMRAudioDeviceManagerClient::Dropout: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::Dropout: " << std::endl; - break; - case WCMRAudioDeviceManagerClient::DeviceDroppedSamples: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceDroppedSamples" << std::endl; - break; - case WCMRAudioDeviceManagerClient::DeviceStoppedStreaming: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceStoppedStreaming" << std::endl; - break; - case WCMRAudioDeviceManagerClient::DeviceStartsStreaming: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceStartsStreaming" << std::endl; - _call_thread_init_callback = true; // streaming will be started from device side, just set thread init flag - break; - case WCMRAudioDeviceManagerClient::DeviceConnectionLost: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceConnectionLost" << std::endl; - break; - case WCMRAudioDeviceManagerClient::DeviceListChanged: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceListChanged" << std::endl; - engine.request_device_list_update(); - break; - case WCMRAudioDeviceManagerClient::IODeviceDisconnected: - std::cout << "------------------------------- WCMRAudioDeviceManagerClient::IODeviceDisconnected" << std::endl; - engine.request_device_list_update(); - break; - case WCMRAudioDeviceManagerClient::AudioCallback: - if (parameter) { - const AudioCallbackData* audio_callback_data = (AudioCallbackData*)parameter; - _audio_device_callback ( - audio_callback_data->acdInputBuffer, - audio_callback_data->acdOutputBuffer, - audio_callback_data->acdFrames, - audio_callback_data->acdSampleTime, - audio_callback_data->acdCycleStartTimeNanos - ); - } - break; - - default: - break; - }; -} - - -WavesAudioBackend::WavesAudioBackend (AudioEngine& e) - : AudioBackend (e, __backend_info) - , _audio_device_manager (this) - , _midi_device_manager (*this) - , _device (NULL) - , _sample_format (FormatFloat) - , _interleaved (true) - , _input_channels (0) - , _max_input_channels (0) - , _output_channels (0) - , _max_output_channels (0) - , _sample_rate (0) - , _buffer_size (0) - , _systemic_input_latency (0) - , _systemic_output_latency (0) - , _call_thread_init_callback (false) - , _use_midi (true) - , _sample_time_at_cycle_start (0) - , _freewheeling (false) - , _freewheel_thread_active (false) - , _dsp_load_accumulator (0) - , _audio_cycle_period_nanos (0) - , _dsp_load_history_length(0) -{ -} - - -WavesAudioBackend::~WavesAudioBackend () -{ - -} - -std::string -WavesAudioBackend::name () const -{ -#ifdef __APPLE__ - return std::string ("CoreAudio"); -#elif PLATFORM_WINDOWS - return std::string ("ASIO"); -#endif -} - - -bool -WavesAudioBackend::is_realtime () const -{ - return true; -} - - -bool -WavesAudioBackend::requires_driver_selection () const -{ - return false; -} - - -std::vector -WavesAudioBackend::enumerate_drivers () const -{ - // this backend does not suppose driver selection - assert (false); - - return std::vector (); -} - - -int -WavesAudioBackend::set_driver (const std::string& /*drivername*/) -{ - //Waves audio backend does not suppose driver selection - assert (false); - - return -1; -} - - -std::vector -WavesAudioBackend::enumerate_devices () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::enumerate_devices (): " << std::endl; - - std::vector devicesStatus; - const DeviceInfoVec& deviceInfoList = _audio_device_manager.DeviceInfoList(); - - for (DeviceInfoVecConstIter deviceInfoIter = deviceInfoList.begin (); deviceInfoIter != deviceInfoList.end (); ++deviceInfoIter) { - // COMMENTED DBG LOGS */ std::cout << "\t Device found: " << (*deviceInfoIter)->m_DeviceName << std::endl; - devicesStatus.push_back (DeviceStatus ((*deviceInfoIter)->m_DeviceName, true)); - } - - return devicesStatus; -} - - -std::vector -WavesAudioBackend::available_sample_rates (const std::string& device_name) const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_sample_rates (): [" << device_name << "]" << std::endl; - - std::vector sr; - - WTErr retVal = _audio_device_manager.GetDeviceSampleRates(device_name, sr); - - if (eNoErr != retVal) { - std::cerr << "WavesAudioBackend::available_sample_rates (): Failed to find device [" << device_name << "]" << std::endl; - return std::vector (); - } - - // COMMENTED DBG LOGS */ std::cout << "\tFound " << devInfo.m_AvailableSampleRates.size () << " sample rates for " << device_name << ":"; - - std::vector sample_rates (sr.begin (), sr.end ()); - - // COMMENTED DBG LOGS */ for (std::vector::iterator i = sample_rates.begin (); i != sample_rates.end (); ++i) std::cout << " " << *i; std::cout << std::endl; - - return sample_rates; -} - - -float WavesAudioBackend::default_sample_rate () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::default_sample_rate (): " << AudioBackend::default_sample_rate () << std::endl; - return AudioBackend::default_sample_rate (); -} - - -std::vector -WavesAudioBackend::available_buffer_sizes (const std::string& device_name) const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_buffer_sizes (): [" << device_name << "]" << std::endl; - - std::vector bs; - - WTErr retVal = _audio_device_manager.GetDeviceBufferSizes(device_name, bs); - - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::available_buffer_sizes (): Failed to get buffer size for device [" << device_name << "]" << std::endl; - return std::vector (); - } - - std::vector buffer_sizes (bs.begin (), bs.end ()); - - // COMMENTED DBG LOGS */ std::cout << "\tFound " << buffer_sizes.size () << " buffer sizes for " << device_name << ":"; - // COMMENTED DBG LOGS */ for (std::vector::const_iterator i = buffer_sizes.begin (); i != buffer_sizes.end (); ++i) std::cout << " " << *i; std::cout << std::endl; - - return buffer_sizes; -} - - -uint32_t -WavesAudioBackend::available_input_channel_count (const std::string& device_name) const -{ - DeviceInfo devInfo; - WTErr err = _audio_device_manager.GetDeviceInfoByName(device_name, devInfo); - - if (eNoErr != err) { - std::cerr << "WavesAudioBackend::available_input_channel_count (): Failed to find device [" << device_name << "]" << std::endl; - return 0; - } - - uint32_t num_of_input_channels = devInfo.m_MaxInputChannels; - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_input_channel_count (): " << num_of_input_channels << std::endl; - return num_of_input_channels; -} - - -uint32_t -WavesAudioBackend::available_output_channel_count (const std::string& device_name) const -{ - DeviceInfo devInfo; - WTErr err = _audio_device_manager.GetDeviceInfoByName(device_name, devInfo); - - if (eNoErr != err) { - std::cerr << "WavesAudioBackend::available_output_channel_count (): Failed to find device [" << device_name << "]" << std::endl; - return 0; - } - - uint32_t num_of_output_channels = devInfo.m_MaxOutputChannels; - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_output_channel_count (): " << num_of_output_channels << std::endl; - - return num_of_output_channels; -} - - -bool -WavesAudioBackend::can_change_sample_rate_when_running () const -{ - // VERIFY IT CAREFULLY - return true; -} - - -bool -WavesAudioBackend::can_change_buffer_size_when_running () const -{ - // VERIFY IT CAREFULLY - return true; -} - - -int -WavesAudioBackend::set_device_name (const std::string& device_name) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_device_name (): " << device_name << std::endl; - - if (_ports.size ()) { - std::cerr << "WavesAudioBackend::set_device_name (): There are unregistered ports left after [" << (_device ? _device->DeviceName () : std::string ("")) << "]!" << std::endl; - for (size_t i = 0; i < _ports.size (); ++i) { - std::cerr << "\t[" << _ports[i]->name () << "]!" << std::endl; - } - return -1; - } - - if (_device && _device->Streaming () ) { - std::cerr << "WavesAudioBackend::set_device_name (): [" << _device->DeviceName () << "] is streaming! Current device must be stopped before setting another device as current" << std::endl; - } - - // we must have only one device initialized at a time - // stop current device first - WTErr retVal; - if (_device) { - retVal = _device->SetActive (false); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_device_name (): [" << _device->DeviceName () << "]->SetActive (false) failed!" << std::endl; - return -1; - } - } - - // deinitialize it - _audio_device_manager.DestroyCurrentDevice(); - _device = 0; - - WCMRAudioDevice * device = _audio_device_manager.InitNewCurrentDevice(device_name); - - if (!device) { - std::cerr << "WavesAudioBackend::set_device_name (): Failed to initialize device [" << device_name << "]!" << std::endl; - return -1; - } - - - retVal = device->SetActive (true); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_device_name (): [" << device->DeviceName () << "]->SetActive () failed!" << std::endl; - return -1; - } - - _device = device; - return 0; -} - - -int -WavesAudioBackend::drop_device() -{ - WTErr wtErr = 0; - - if (_device) - { - wtErr = _device->SetActive (false); - if (wtErr != eNoErr) { - std::cerr << "WavesAudioBackend::drop_device (): [" << _device->DeviceName () << "]->SetActive () failed!" << std::endl; - return -1; - } - } - - _audio_device_manager.DestroyCurrentDevice(); - _device = 0; - - return 0; -} - - -int -WavesAudioBackend::set_sample_rate (float sample_rate) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_sample_rate (): " << sample_rate << std::endl; - - WTErr retVal = eNoErr; - - if (!_device) { - std::cerr << "WavesAudioBackend::set_sample_rate (): No device is set!" << std::endl; - return -1; - } - - - bool device_needs_restart = _device->Streaming (); - - if (device_needs_restart) { - retVal = _device->SetStreaming (false); - // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->_device->SetStreaming (false);"<< std::endl; - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName () << "]->SetStreaming (false) failed (" << retVal << ") !" << std::endl; - return -1; - } - } - - retVal = _device->SetCurrentSamplingRate ((int)sample_rate); - - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName() << "]->SetCurrentSamplingRate ((int)" << sample_rate << ") failed (" << retVal << ") !" << std::endl; - return -1; - } - - // if call to set sample rate is successful - // but device sample rate differs from the value we tried to set - // this means we are driven by device for buffer size - sample_rate = _device->CurrentSamplingRate (); - _sample_rate_change(sample_rate); - - if (device_needs_restart) { - // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl; - retVal = _device->SetStreaming (true); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName () << "]->SetStreaming (true) failed (" << retVal << ") !" << std::endl; - return -1; - } - } - return 0; -} - - -int -WavesAudioBackend::set_buffer_size (uint32_t buffer_size) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_buffer_size (" << buffer_size << "):"<< std::endl; - - WTErr retVal = eNoErr; - - if (!_device) { - std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl; - return -1; - } - - bool device_needs_restart = _device->Streaming (); - - if (device_needs_restart) { - retVal = _device->SetStreaming (false); - // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (false);"<< std::endl; - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName () << "]->SetStreaming (false) failed (" << retVal << ") !" << std::endl; - return -1; - } - } - - retVal = _device->SetCurrentBufferSize (buffer_size); - - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName() << "]->SetCurrentBufferSize (" << buffer_size << ") failed (" << retVal << ") !" << std::endl; - return -1; - } - - // if call to set buffer is successful but device buffer size differs from the value we tried to set - // this means we are driven by device for buffer size - buffer_size = _device->CurrentBufferSize (); - - _buffer_size_change(buffer_size); - - if (device_needs_restart) { - // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl; - retVal = _device->SetStreaming (true); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName () << "]->SetStreaming (true) failed (" << retVal << ") !" << std::endl; - return -1; - } - } - - return 0; -} - - -int -WavesAudioBackend::set_sample_format (SampleFormat sample_format) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_sample_format (): " << sample_format << std::endl; - - _sample_format = sample_format; - return 0; -} - -int -WavesAudioBackend::reset_device () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_reset_device ():" << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl; - return -1; - } - - return _device->ResetDevice(); -} - - -int -WavesAudioBackend::_buffer_size_change (uint32_t new_buffer_size) -{ - _buffer_size = new_buffer_size; - _init_dsp_load_history(); - return engine.buffer_size_change (new_buffer_size); -} - - -int -WavesAudioBackend::_sample_rate_change (float new_sample_rate) -{ - _sample_rate = new_sample_rate; - _init_dsp_load_history(); - return engine.sample_rate_change (new_sample_rate); -} - - -int -WavesAudioBackend::set_interleaved (bool yn) -{ - /*you can ignore them totally*/ - _interleaved = yn; - return 0; -} - - -int -WavesAudioBackend::set_input_channels (uint32_t input_channels) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_input_channels (): " << input_channels << std::endl; - - _input_channels = input_channels; - return 0; -} - - -int -WavesAudioBackend::set_output_channels (uint32_t output_channels) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_output_channels (): " << output_channels << std::endl; - - _output_channels = output_channels; - return 0; -} - - -std::string -WavesAudioBackend::device_name () const -{ - if (!_device) { - return ""; - } - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::device_name (): " << _device->DeviceName () << std::endl; - - return _device->DeviceName (); -} - - -float -WavesAudioBackend::sample_rate () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::sample_rate (): " << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::sample_rate (): No device is set!" << std::endl; - return -1; - } - - int sample_rate = _device->CurrentSamplingRate (); - - // COMMENTED DBG LOGS */ std::cout << "\t[" << _device->DeviceName () << "]->CurrentSamplingRate () returned " << sample_rate << std::endl; - - return (float)sample_rate; -} - - -uint32_t -WavesAudioBackend::buffer_size () const -{ - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::buffer_size (): " << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::buffer_size (): No device is set!" << std::endl; - return 0; - } - - int size = _device->CurrentBufferSize (); - - // COMMENTED DBG LOGS */ std::cout << "\t[" << _device->DeviceName () << "]->CurrentBufferSize () returned " << size << std::endl; - - return (uint32_t)size; -} - - -SampleFormat -WavesAudioBackend::sample_format () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::sample_format ()" << std::endl; - return _sample_format; -} - - -bool -WavesAudioBackend::interleaved () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::interleaved ()" << std::endl; - - return _interleaved; -} - - -uint32_t -WavesAudioBackend::input_channels () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::input_channels ()" << std::endl; - - return _input_channels; -} - - -uint32_t -WavesAudioBackend::output_channels () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::output_channels ()" << std::endl; - - return _output_channels; -} - - -std::string -WavesAudioBackend::control_app_name () const -{ - std::string app_name = ""; - - if (_device && !dynamic_cast (_device)) { - app_name = "PortAudioMayKnowIt"; - } - - return app_name; -} - - -void -WavesAudioBackend::launch_control_app () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::launch_control_app ()" << std::endl; - if (!_device) { - std::cerr << "WavesAudioBackend::launch_control_app (): No device is set!" << std::endl; - return; - } - - WTErr err = _device->ShowConfigPanel (NULL); - - if (eNoErr != err) { - std::cerr << "WavesAudioBackend::launch_control_app (): [" << _device->DeviceName () << "]->ShowConfigPanel () failed (" << err << ")!" << std::endl; - } - - // COMMENTED DBG LOGS */ else std::cout << "WavesAudioBackend::launch_control_app (): [" << _device->DeviceName () << "]->ShowConfigPanel () successfully launched!" << std::endl; -} - - -int -WavesAudioBackend::_start (bool for_latency_measurement) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_start ()" << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::_start (): No device is set!" << std::endl; - stop(); - return -1; - } - - if (_register_system_audio_ports () != 0) { - std::cerr << "WavesAudioBackend::_start (): _register_system_audio_ports () failed!" << std::endl; - stop(); - return -1; - } - - if (_use_midi) { - if (_midi_device_manager.start () != 0) { - std::cerr << "WavesAudioBackend::_start (): _midi_device_manager.start () failed!" << std::endl; - stop(); - return -1; - } - if (_register_system_midi_ports () != 0) { - std::cerr << "WavesAudioBackend::_start (): _register_system_midi_ports () failed!" << std::endl; - stop(); - return -1; - } - } - - if (engine.reestablish_ports () != 0) { - std::cerr << "WavesAudioBackend::_start (): engine.reestablish_ports () failed!" << std::endl; - } - - manager.registration_callback (); - - WTErr retVal = _device->SetStreaming (true); - if (retVal != eNoErr) { - std::cerr << "WavesAudioBackend::_start (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl; - stop(); - return -1; - } - - if (_use_midi) { - if (_midi_device_manager.stream (true)) { - std::cerr << "WavesAudioBackend::_start (): _midi_device_manager.stream (true) failed!" << std::endl; - stop(); - return -1; - } - } - - return 0; -} - - -void -WavesAudioBackend::_audio_device_callback (const float* input_buffer, - float* output_buffer, - unsigned long nframes, - framepos_t sample_time, - uint64_t cycle_start_time_nanos) -{ - uint64_t dsp_start_time_nanos = __get_time_nanos(); - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::_audio_device_callback ():" << _device->DeviceName () << std::endl; - _sample_time_at_cycle_start = sample_time; - _cycle_start_time_nanos = cycle_start_time_nanos; - - if (_buffer_size != nframes) { - // COMMENTED DBG LOGS */ std::cout << "\tAudioEngine::thread_init_callback() buffer size and nframes are not equal: " << _buffer_size << "!=" << nframes << std::endl; - return; - } - - _read_audio_data_from_device (input_buffer, nframes); - _read_midi_data_from_devices (); - - if (_call_thread_init_callback) { - _call_thread_init_callback = false; - // COMMENTED DBG LOGS */ std::cout << "\tAudioEngine::thread_init_callback() invoked for " << std::hex << pthread_self() << std::dec << " !" << std::endl; - - /* There is the possibility that the thread this runs in may change from - * callback to callback, so do it every time. - */ - _main_thread = pthread_self (); - - AudioEngine::thread_init_callback (this); - } - - if ( !engine.thread_initialised_for_audio_processing () ) { - std::cerr << "\tWavesAudioBackend::_audio_device_callback (): It's an attempt to call process callback from the thread which didn't initialize it " << std::endl; - - AudioEngine::thread_init_callback (this); - } - - if (pthread_equal (_main_thread, pthread_self()) == 0) { -#ifdef PTW32_VERSION - std::cerr << "Process thread ID has changed. Expected thread: " << _main_thread.p << " current thread: " << pthread_self().p << std::dec << " !" << std::endl; -#else - std::cerr << "Process thread ID has changed. Expected thread: " << _main_thread << " current thread: " << pthread_self() << std::dec << " !" << std::endl; -#endif - _main_thread = pthread_self(); - } - - engine.process_callback (nframes); - - _write_audio_data_to_device (output_buffer, nframes); - _write_midi_data_to_devices (nframes); - - uint64_t dsp_end_time_nanos = __get_time_nanos(); - - _dsp_load_accumulator -= *_dsp_load_history.begin(); - _dsp_load_history.pop_front(); - uint64_t dsp_load_nanos = dsp_end_time_nanos - dsp_start_time_nanos; - _dsp_load_accumulator += dsp_load_nanos; - _dsp_load_history.push_back(dsp_load_nanos); - - return; -} - - -int -WavesAudioBackend::stop () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::stop ()" << std::endl; - - WTErr wtErr = eNoErr; - int retVal = 0; - - // COMMENTED DBG LOGS */ std::cout << "\t[" << _device->DeviceName () << "]" << std::endl; - - if (_device) { - wtErr = _device->SetStreaming (false); - if (wtErr != eNoErr) { - std::cerr << "WavesAudioBackend::stop (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl; - retVal = -1; - } - } - - _midi_device_manager.stop (); - _unregister_system_audio_ports (); - _unregister_system_midi_ports (); - - return retVal; -} - - -int -WavesAudioBackend::freewheel (bool start_stop) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::freewheel (" << start_stop << "):" << std::endl; - - if (start_stop != _freewheeling) { - if (start_stop == true) { - WTErr retval = _device->SetStreaming (false); - if (retval != eNoErr) { - std::cerr << "WavesAudioBackend::freewheel (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl; - return -1; - } - _call_thread_init_callback = true; - _freewheel_thread (); - - while (!engine.freewheeling()) { - sleep(0); - } - - // freewheel thread was not activated successfully - if (_freewheel_thread_active == false) { - engine.freewheel_callback(false); - } - } - else { - _freewheel_thread_active = false; // stop _freewheel_thread () - - while (engine.freewheeling()) { - sleep(0); - } - - _call_thread_init_callback = true; - WTErr retval = _device->SetStreaming (true); - if (retval != eNoErr) { - std::cerr << "WavesAudioBackend::freewheel (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl; - return -1; - } - } - _freewheeling = start_stop; - } - // already doing what has been asked for - return 0; -} - - -void -WavesAudioBackend::_freewheel_thread () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_freewheel_thread ():" << std::endl; - if (!_freewheel_thread_active) { // Lets create it - - // COMMENTED DBG LOGS */ std::cout << "\tCreating the thread _freewheel_thread () . . ." << std::endl; - pthread_attr_t attributes; - pthread_t thread_id; - - ThreadData* thread_data = new ThreadData (this, boost::bind (&WavesAudioBackend::_freewheel_thread, this), __thread_stack_size ()); - - if (pthread_attr_init (&attributes)) { - std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_attr_init () failed!" << std::endl; - return; - } - - if (pthread_attr_setstacksize (&attributes, __thread_stack_size ())) { - std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_attr_setstacksize () failed!" << std::endl; - return; - } - - _freewheel_thread_active = true; - if ((pthread_create (&thread_id, &attributes, __start_process_thread, thread_data))) { - _freewheel_thread_active = false; - - // release invoking thread - engine.freewheel_callback(true); - - std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_create () failed!" << std::endl; - return; - } - - // COMMENTED DBG LOGS */ std::cout << "\t. . . _freewheel_thread () complete." << std::endl; - return; - } - - // notify angine that freewheeling is started - engine.freewheel_callback(true); - - if (_call_thread_init_callback) { - _call_thread_init_callback = false; - AudioEngine::thread_init_callback (this); - } - - while (_freewheel_thread_active) { - engine.process_callback (_buffer_size); - } - - // notify angine that freewheeling is stopped - engine.freewheel_callback(false); - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_freewheel_thread (): FINISHED" << std::endl; - return; -} - - -float -WavesAudioBackend::dsp_load () const -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::dsp_load (): " << std::endl; - - if (!_device) { - std::cerr << "WavesAudioBackend::cpu_load (): No device is set!" << std::endl; - return 0; - } - - float average_dsp_load = (float)_dsp_load_accumulator/_dsp_load_history_length; - - return ( average_dsp_load / _audio_cycle_period_nanos)*100.0; -} - - -void -WavesAudioBackend::_init_dsp_load_history() -{ - if((_sample_rate <= 0.0) || (_buffer_size <= 0.0)) { - return; - } - - _audio_cycle_period_nanos = ((uint64_t)1000000000L * _buffer_size) / _sample_rate; - - _dsp_load_accumulator = 0; - - _dsp_load_history_length = (_sample_rate + _buffer_size - 1) / _buffer_size; - // COMMENTED DBG LOGS */ std::cout << "\t\t_dsp_load_history_length = " << _dsp_load_history_length << std::endl; - _dsp_load_history = std::list(_dsp_load_history_length, 0); -} - - -void -WavesAudioBackend::transport_start () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_start (): " << std::endl; -} - - -void -WavesAudioBackend::transport_stop () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_stop (): " << std::endl; -} - - -TransportState -WavesAudioBackend::transport_state () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_state (): " << std::endl; - return TransportStopped; -} - - -void -WavesAudioBackend::transport_locate (framepos_t pos) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_locate (" << pos << "): " << std::endl; -} - - -framepos_t -WavesAudioBackend::transport_frame () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_frame (): " << std::endl; - return 0; -} - - -int -WavesAudioBackend::set_time_master (bool yn) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_time_master (): " << yn << std::endl; - return 0; -} - - -int -WavesAudioBackend::usecs_per_cycle () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::usecs_per_cycle (): " << std::endl; - return (1000000 * _sample_rate) / _buffer_size; -} - - -size_t -WavesAudioBackend::raw_buffer_size (DataType data_type) -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::raw_buffer_size (" << data_type.to_string () << "): " << std::endl; - switch (data_type) { - case DataType::AUDIO: - return WavesAudioPort::MAX_BUFFER_SIZE_BYTES; - break; - - case DataType::MIDI: - return WavesMidiPort::MAX_BUFFER_SIZE_BYTES; - break; - - default: - std::cerr << "WavesAudioBackend::raw_buffer_size (): unexpected data type (" << (uint32_t)data_type <<")!" << std::endl; - break; - } - return 0; -} - - -framepos_t -WavesAudioBackend::sample_time () -{ - // WARNING: This is approximate calculation. Implementation of accurate calculation is pending. - // http://kokkinizita.linuxaudio.org/papers/usingdll.pdf - - return _sample_time_at_cycle_start + ((__get_time_nanos () - _cycle_start_time_nanos)*_sample_rate)/1000000000L; -} - - -uint64_t -WavesAudioBackend::__get_time_nanos () -{ -#ifdef __APPLE__ - // here we exploit the time counting API which is used by the WCMRCoreAudioDeviceManager. However, - // the API should be a part of WCMRCoreAudioDeviceManager to give a chance of being tied to the - // audio device transport timeß. - return AudioConvertHostTimeToNanos (AudioGetCurrentHostTime ()); - -#elif PLATFORM_WINDOWS - LARGE_INTEGER Count; - QueryPerformanceCounter (&Count); - return uint64_t ((Count.QuadPart * 1000000000L / __performance_counter_frequency)); -#endif -} - - -framepos_t -WavesAudioBackend::sample_time_at_cycle_start () -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::sample_time_at_cycle_start (): " << _sample_time_at_cycle_start << std::endl; - return _sample_time_at_cycle_start; -} - - -pframes_t -WavesAudioBackend::samples_since_cycle_start () -{ - pframes_t diff_sample_time; - diff_sample_time = sample_time () - _sample_time_at_cycle_start; - // COMMENTED DBG LOGS */ std::cout << "samples_since_cycle_start: " << diff_sample_time << std::endl; - - return diff_sample_time; -} - - -bool -WavesAudioBackend::get_sync_offset (pframes_t& /*offset*/) const -{ - // COMMENTED DBG LOGS */ std::cout << "get_sync_offset: false" << std::endl; - - return false; -} - - -int -WavesAudioBackend::create_process_thread (boost::function func) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::create_process_thread ():" << std::endl; - int retVal; - pthread_attr_t attributes; - size_t stacksize_aligned; - pthread_t thread_id; - - // Align stacksize to PTHREAD_STACK_MIN. - stacksize_aligned = __thread_stack_size (); - - ThreadData* td = new ThreadData (this, func, stacksize_aligned); - - if ((retVal = pthread_attr_init (&attributes))) { - std::cerr << "Cannot set thread attr init res = " << retVal << endmsg; - return -1; - } - - if ((retVal = pthread_attr_setstacksize (&attributes, stacksize_aligned))) { - std::cerr << "Cannot set thread stack size (" << stacksize_aligned << ") res = " << retVal << endmsg; - return -1; - } - - if ((retVal = pthread_create (&thread_id, &attributes, __start_process_thread, td))) { - std::cerr << "Cannot create thread res = " << retVal << endmsg; - return -1; - } - - _backend_threads.push_back (thread_id); - // COMMENTED DBG LOGS */ std::cout << "\t\t\t. . . thread " << std::hex << thread_id << std::dec << " has been created" << std::endl; - - return 0; -} - - -void* -WavesAudioBackend::__start_process_thread (void* arg) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__start_process_thread ():" << std::endl; - ThreadData* td = reinterpret_cast (arg); - boost::function f = td->f; - delete td; - f (); - return 0; -} - - -int -WavesAudioBackend::join_process_threads () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::join_process_thread ()" << std::endl; - int ret = 0; - - for (std::vector::const_iterator i = _backend_threads.begin (); - i != _backend_threads.end (); - ++i) { - // COMMENTED DBG LOGS */ std::cout << "\t\t\tstopping thread " << std::hex << *i << std::dec << "...\n"; - - void* status; - if (pthread_join (*i, &status) != 0) { - std::cerr << "AudioEngine: cannot stop process thread !" << std::endl; - ret += -1; - } - // COMMENTED DBG LOGS */ std::cout << "\t\t\t\t...done" << std::endl; - } - // COMMENTED DBG LOGS */ std::cout << "\t\t\tall threads finished..." << std::endl; - _backend_threads.clear (); - // COMMENTED DBG LOGS */ std::cout << "\t\t\tthread list cleared..." << std::endl; - - return ret; -} - - -bool -WavesAudioBackend::in_process_thread () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::in_process_thread ()" << std::endl; - if (pthread_equal (_main_thread, pthread_self()) != 0) { - return true; - } - for (std::vector::const_iterator i = _backend_threads.begin (); - i != _backend_threads.end (); i++) { - if (pthread_equal (*i, pthread_self ()) != 0) { - return true; - } - } - return false; -} - - -size_t -WavesAudioBackend::__thread_stack_size () -{ - // Align stacksize to PTHREAD_STACK_MIN. -#if defined (__APPLE__) - return (((thread_stack_size () - 1) / PTHREAD_STACK_MIN) + 1) * PTHREAD_STACK_MIN; -#elif defined (PLATFORM_WINDOWS) - return thread_stack_size (); -#endif -} - - -uint32_t -WavesAudioBackend::process_thread_count () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::process_thread_count (): returns " << _backend_threads.size () << std::endl; - return _backend_threads.size (); -} - - -void -WavesAudioBackend::_read_audio_data_from_device (const float* input_buffer, pframes_t nframes) -{ -#if defined(PLATFORM_WINDOWS) - const float **buffer = (const float**)input_buffer; - - for(std::vector::iterator it = _physical_audio_inputs.begin (); - it != _physical_audio_inputs.end(); - ++it) - { - ARDOUR::copy_vector ((*it)->buffer(), *buffer, nframes); - ++buffer; - } -#else - std::vector::iterator it = _physical_audio_inputs.begin (); - - // Well, let's de-interleave here: - const Sample* source = input_buffer; - - for (uint32_t chann_cnt = 0; (chann_cnt < _max_input_channels) && (it != _physical_audio_inputs.end ()); ++chann_cnt, ++source, ++it) { - const Sample* src = source; - Sample* tgt = (*it)->buffer (); - - for (uint32_t frame = 0; frame < nframes; ++frame, src += _max_input_channels, ++tgt) { - *tgt = *src; - } - } -#endif -} - -void -WavesAudioBackend::_write_audio_data_to_device (float* output_buffer, pframes_t nframes) -{ -#if defined(_WnonononoINDOWS) - float **buffer = (float**)output_buffer; - size_t copied_bytes = nframes*sizeof(float); - int i = 0; - for(std::vector::iterator it = _physical_audio_outputs.begin (); - it != _physical_audio_outputs.end(); - ++it) - { - memcpy(*buffer, (*it)->buffer(), copied_bytes); - //*buffer = (*it)->buffer(); - buffer++; - } -#else - // Well, let's interleave here: - std::vector::iterator it = _physical_audio_outputs.begin (); - Sample* target = output_buffer; - - for (uint32_t chann_cnt = 0; - (chann_cnt < _max_output_channels) && (it != _physical_audio_outputs.end ()); - ++chann_cnt, ++target, ++it) { - const Sample* src = (Sample*) ((*it)->get_buffer (nframes)); - Sample* tgt = target; - for (uint32_t frame = 0; frame < nframes; ++frame, tgt += _max_output_channels, ++src) { - *tgt = *src; - } - } -#endif -} - - -static boost::shared_ptr __instance; - - -boost::shared_ptr -WavesAudioBackend::__waves_backend_factory (AudioEngine& e) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__waves_backend_factory ():" << std::endl; - if (!__instance) { - __instance.reset (new WavesAudioBackend (e)); - } - return __instance; -} - - -#if defined(PLATFORM_WINDOWS) - -uint64_t WavesAudioBackend::__performance_counter_frequency; - -#endif - -int -WavesAudioBackend::__instantiate (const std::string& arg1, const std::string& arg2) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__instantiate ():" << "[" << arg1 << "], [" << arg2 << "]" << std::endl; - __instantiated_name = arg1; -#if defined(PLATFORM_WINDOWS) - - LARGE_INTEGER Frequency; - QueryPerformanceFrequency(&Frequency); - __performance_counter_frequency = Frequency.QuadPart; - -#endif - return 0; -} - - -int -WavesAudioBackend::__deinstantiate () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__deinstantiate ():" << std::endl; - __instance.reset (); - return 0; -} - - -bool -WavesAudioBackend::__already_configured () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__already_configured ():" << std::endl; - return false; -} - -bool -WavesAudioBackend::__available () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__available ():" << std::endl; - return true; -} - - -void* -WavesAudioBackend::private_handle () const -{ - // COMMENTED DBG LOGS */ std::cout << "WHY DO CALL IT: WavesAudioBackend::private_handle: " << std::endl; - return NULL; -} - - -bool -WavesAudioBackend::available () const -{ - // COMMENTED SECONDARY DBG LOGS */// std::cout << "WavesAudioBackend::available: " << std::endl; - return true; -} - - -const std::string& -WavesAudioBackend::my_name () const -{ - // COMMENTED SECONDARY DBG LOGS */// std::cout << "WavesAudioBackend::my_name: " << _port_prefix_name << std::endl; - return __instantiated_name; -} - - -bool -WavesAudioBackend::can_monitor_input () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::can_monitor_input: " << std::endl; - return false; -} - -std::string WavesAudioBackend::__instantiated_name; - -AudioBackendInfo WavesAudioBackend::__backend_info = { -#ifdef __APPLE__ - "CoreAudio", -#elif PLATFORM_WINDOWS - "ASIO", -#endif - __instantiate, - WavesAudioBackend::__deinstantiate, - WavesAudioBackend::__waves_backend_factory, - WavesAudioBackend::__already_configured, - WavesAudioBackend::__available, -}; - - diff --git a/libs/backends/wavesaudio/waves_audiobackend.h b/libs/backends/wavesaudio/waves_audiobackend.h deleted file mode 100644 index 5ad952ad82..0000000000 --- a/libs/backends/wavesaudio/waves_audiobackend.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __libardour_waves_audiobackend_h__ -#define __libardour_waves_audiobackend_h__ - -#include -#include -#include - -#include -#include - -#include - -#include "ardour/types.h" -#include "ardour/audio_backend.h" - -#include "waves_midi_device_manager.h" - -#ifdef __APPLE__ - -#include - -class ArdourAudioDeviceManager : public WCMRCoreAudioDeviceManager -{ - public: - ArdourAudioDeviceManager (WCMRAudioDeviceManagerClient *client) : WCMRCoreAudioDeviceManager (client, eAllDevices) {}; -}; - -#elif defined (PLATFORM_WINDOWS) - -#include - -class ArdourAudioDeviceManager : public WCMRPortAudioDeviceManager -{ - public: - ArdourAudioDeviceManager (WCMRAudioDeviceManagerClient *client) : WCMRPortAudioDeviceManager (client, eAllDevices) {}; -}; - -#endif - -namespace ARDOUR { - -class AudioEngine; -class PortEngine; -class PortManager; -class WavesAudioBackend; -class WavesDataPort; -class WavesAudioPort; -class WavesMidiPort; - - - class WavesAudioBackend : public AudioBackend, WCMRAudioDeviceManagerClient -{ - public: - WavesAudioBackend (AudioEngine& e); - virtual ~WavesAudioBackend (); - - /* AUDIOBACKEND API */ - - virtual std::string name () const; - - virtual bool is_realtime () const; - - virtual bool requires_driver_selection () const; - - virtual std::vector enumerate_drivers () const; - - virtual int set_driver (const std::string& /*drivername*/); - - virtual std::vector enumerate_devices () const; - - virtual std::vector available_sample_rates (const std::string& device) const; - - virtual float default_sample_rate () const; - - virtual std::vector available_buffer_sizes (const std::string& device) const; - - virtual uint32_t available_input_channel_count (const std::string& device) const; - - virtual uint32_t available_output_channel_count (const std::string& device) const; - - virtual bool can_change_sample_rate_when_running () const; - - virtual bool can_change_buffer_size_when_running () const; - - virtual int set_device_name (const std::string& name); - - virtual int drop_device(); - - virtual int set_sample_rate (float); - - virtual int set_buffer_size (uint32_t); - - virtual int set_sample_format (SampleFormat); - - virtual int set_interleaved (bool yn); - - virtual int set_input_channels (uint32_t); - - virtual int set_output_channels (uint32_t); - - virtual int set_systemic_input_latency (uint32_t); - - virtual int set_systemic_output_latency (uint32_t); - - int set_systemic_midi_input_latency (std::string const, uint32_t) { return 0; } - int set_systemic_midi_output_latency (std::string const, uint32_t) { return 0; } - - virtual int reset_device (); - - virtual std::string device_name () const; - - virtual float sample_rate () const; - - virtual uint32_t buffer_size () const; - - virtual SampleFormat sample_format () const; - - virtual bool interleaved () const; - - virtual uint32_t input_channels () const; - - virtual uint32_t output_channels () const; - - virtual uint32_t systemic_input_latency () const; - - virtual uint32_t systemic_output_latency () const; - - uint32_t systemic_midi_input_latency (std::string const) const { return 0; } - - uint32_t systemic_midi_output_latency (std::string const) const { return 0; } - - virtual std::string control_app_name () const; - - virtual void launch_control_app (); - - virtual std::vector enumerate_midi_options () const; - - virtual int set_midi_option (const std::string& option); - - virtual std::string midi_option () const; - - std::vector enumerate_midi_devices () const { - return std::vector (); - } - int set_midi_device_enabled (std::string const, bool) { - return 0; - } - bool midi_device_enabled (std::string const) const { - return true; - } - bool can_set_systemic_midi_latencies () const { - return false; - } - - virtual int _start (bool for_latency_measurement); - - virtual int stop (); - - virtual int freewheel (bool start_stop); - - virtual float dsp_load () const ; - - virtual void transport_start (); - - virtual void transport_stop (); - - virtual TransportState transport_state () const; - - virtual void transport_locate (framepos_t pos); - - virtual framepos_t transport_frame () const; - - virtual int set_time_master (bool yn); - - virtual int usecs_per_cycle () const; - - virtual size_t raw_buffer_size (DataType data_type); - - virtual framepos_t sample_time (); - - virtual framepos_t sample_time_at_cycle_start (); - - virtual pframes_t samples_since_cycle_start (); - - virtual bool get_sync_offset (pframes_t& offset) const; - - virtual int create_process_thread (boost::function func); - - virtual int join_process_threads (); - - virtual bool in_process_thread (); - - virtual uint32_t process_thread_count (); - - virtual void update_latencies (); - - virtual bool speed_and_position (double& speed, framepos_t& position) { - speed = 0.0; - position = 0; - return false; - } - - /* PORTENGINE API */ - - virtual void* private_handle () const; - - virtual const std::string& my_name () const; - - virtual bool available () const; - - virtual uint32_t port_name_size () const; - - virtual int set_port_name (PortHandle port_handle, const std::string& port_name); - - virtual std::string get_port_name (PortHandle port_handle ) const; - - virtual PortHandle get_port_by_name (const std::string& port_name) const; - - virtual int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector& port_handles) const; - - virtual DataType port_data_type (PortHandle port_handle) const; - - virtual PortHandle register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags); - - virtual void unregister_port (PortHandle port_handle); - - virtual int connect (const std::string& src, const std::string& dst); - - virtual int disconnect (const std::string& src, const std::string& dst); - - virtual int connect (PortHandle port_handle, const std::string& port_name); - - virtual int disconnect (PortHandle port_handle, const std::string& port_name); - - virtual int disconnect_all (PortHandle port_handle); - - virtual bool connected (PortHandle port_handle, bool process_callback_safe); - - virtual bool connected_to (PortHandle port_handle, const std::string& port_name, bool process_callback_safe); - - virtual bool physically_connected (PortHandle port_handle, bool process_callback_safe); - - virtual int get_connections (PortHandle port_handle, std::vector&, bool process_callback_safe); - - virtual int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index); - - virtual int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size); - - virtual uint32_t get_midi_event_count (void* port_buffer); - - virtual void midi_clear (void* port_buffer); - - virtual bool can_monitor_input () const; - - virtual int request_input_monitoring (PortHandle port_handle, bool); - - virtual int ensure_input_monitoring (PortHandle port_handle, bool); - - virtual bool monitoring_input (PortHandle port_handle); - - virtual void set_latency_range (PortHandle port_handle, bool for_playback, LatencyRange); - - virtual LatencyRange get_latency_range (PortHandle port_handle, bool for_playback); - - virtual bool port_is_physical (PortHandle port_handle) const; - - virtual void get_physical_outputs (DataType type, std::vector& port_names); - - virtual void get_physical_inputs (DataType type, std::vector& port_names); - - virtual ChanCount n_physical_outputs () const; - - virtual ChanCount n_physical_inputs () const; - - virtual void* get_buffer (PortHandle port_handle, pframes_t frames); - - static AudioBackendInfo& backend_info () { return __backend_info; } - - virtual void AudioDeviceManagerNotification (NotificationReason reason, void* pParam); - - private: - //ArdourAudioDeviceManagerClient _audio_device_manager_client; - ArdourAudioDeviceManager _audio_device_manager; - WavesMidiDeviceManager _midi_device_manager; - - WCMRAudioDevice *_device; - SampleFormat _sample_format; - bool _interleaved; - static std::string __instantiated_name; - uint32_t _input_channels; - uint32_t _max_input_channels; - uint32_t _output_channels; - uint32_t _max_output_channels; - float _sample_rate; - uint32_t _buffer_size; - uint32_t _systemic_input_latency; - uint32_t _systemic_output_latency; - bool _call_thread_init_callback; - std::vector _backend_threads; - pthread_t _main_thread; - static const size_t __max_raw_midi_buffer_size; - - static const std::vector __available_midi_options; - bool _use_midi; - - struct ThreadData { - WavesAudioBackend* engine; - boost::function f; - size_t stacksize; - - ThreadData (WavesAudioBackend* e, boost::function fp, size_t stacksz) - : engine (e) , f (fp) , stacksize (stacksz) {} - }; - - static boost::shared_ptr __waves_backend_factory (AudioEngine& e); - static int __instantiate (const std::string& arg1, const std::string& arg2); - static int __deinstantiate (); - static bool __already_configured (); - static bool __available (); - - static void* __start_process_thread (void*); - static uint64_t __get_time_nanos (); - - static size_t __thread_stack_size (); - - void _audio_device_callback (const float* input_audio_buffer, - float* output_buffer, - unsigned long nframes, - framepos_t sample_time, - uint64_t cycle_start_time_nanos); - - void _changed_midi_devices (); - - // DO change sample rate and buffer size - int _buffer_size_change(uint32_t new_buffer_size); - int _sample_rate_change(float new_sample_rate); - - int _register_system_audio_ports (); - int _register_system_midi_ports (); - - int _read_midi_data_from_devices (); - int _write_midi_data_to_devices (pframes_t); - - pframes_t _ms_to_sample_time (int32_t time_ms) const; - int32_t _sample_time_to_ms (pframes_t sample_time) const ; - - void _read_audio_data_from_device (const float* input_buffer, pframes_t nframes); - void _write_audio_data_to_device (float* output_buffer, pframes_t nframes); - - void _unregister_system_audio_ports (); - void _unregister_system_midi_ports (); - - WavesDataPort* _register_port (const std::string& port_name, ARDOUR::DataType type, ARDOUR::PortFlags flags); - inline bool _registered (PortHandle port_handle) const - { - return std::find (_ports.begin (), _ports.end (), (WavesDataPort*)port_handle) != _ports.end (); - } - - WavesDataPort* _find_port (const std::string& port_name) const; - void _freewheel_thread (); - - std::vector _physical_audio_inputs; - std::vector _physical_audio_outputs; - std::vector _physical_midi_inputs; - std::vector _physical_midi_outputs; - std::vector _ports; - static AudioBackendInfo __backend_info; - -#if defined (PLATFORM_WINDOWS) - static uint64_t __performance_counter_frequency; -#endif - uint64_t _cycle_start_time_nanos; - framepos_t _sample_time_at_cycle_start; - - bool _freewheeling; - bool _freewheel_thread_active; - - friend class WavesMidiDeviceManager; - - std::list _dsp_load_history; - size_t _dsp_load_history_length; - uint64_t _dsp_load_accumulator; - float _audio_cycle_period_nanos; - void _init_dsp_load_history(); -}; - -} // namespace - -#endif /* __libardour_waves_audiobackend_h__ */ - diff --git a/libs/backends/wavesaudio/waves_audiobackend.latency.cc b/libs/backends/wavesaudio/waves_audiobackend.latency.cc deleted file mode 100644 index fd00912fae..0000000000 --- a/libs/backends/wavesaudio/waves_audiobackend.latency.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "waves_dataport.h" -#include "waves_audiobackend.h" - -using namespace ARDOUR; - - -int -WavesAudioBackend::set_systemic_input_latency (uint32_t systemic_input_latency) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_systemic_input_latency (): " << systemic_input_latency << std::endl; - - _systemic_input_latency = systemic_input_latency; - return 0; -} - - -int -WavesAudioBackend::set_systemic_output_latency (uint32_t systemic_output_latency) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_systemic_output_latency (): " << systemic_output_latency << std::endl; - - _systemic_output_latency = systemic_output_latency; - return 0; -} - -uint32_t -WavesAudioBackend::systemic_input_latency () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::systemic_input_latency ()" << std::endl; - - return _systemic_input_latency; -} - - -uint32_t -WavesAudioBackend::systemic_output_latency () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::systemic_output_latency ()" << std::endl; - - return _systemic_output_latency; -} - - -void -WavesAudioBackend::update_latencies () -{ - // COMMENTED DBG LOGS */ std::cout << "update_latencies:" << std::endl; -} - - -void -WavesAudioBackend::set_latency_range (PortHandle port_handle, bool for_playback, LatencyRange latency_range) -{ - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::set_latency_range (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return; - } - ((WavesDataPort*)port_handle)->set_latency_range (latency_range, for_playback); -} - - -LatencyRange -WavesAudioBackend::get_latency_range (PortHandle port_handle, bool for_playback) -{ - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::get_latency_range (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - LatencyRange lr = {0,0}; - return lr; - } - return ((WavesDataPort*)port_handle)->latency_range (for_playback); -} diff --git a/libs/backends/wavesaudio/waves_audiobackend.midi.cc b/libs/backends/wavesaudio/waves_audiobackend.midi.cc deleted file mode 100644 index 334fefd1b6..0000000000 --- a/libs/backends/wavesaudio/waves_audiobackend.midi.cc +++ /dev/null @@ -1,353 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -#include - -#include "waves_audiobackend.h" -#include "waves_midiport.h" -#include "waves_midi_event.h" -#include "waves_midi_buffer.h" - -using namespace ARDOUR; - -#ifdef __APPLE__ - -const std::vector WavesAudioBackend::__available_midi_options = boost::assign::list_of ("CoreMIDI") ("None"); - -#elif PLATFORM_WINDOWS - -const std::vector WavesAudioBackend::__available_midi_options = boost::assign::list_of ("System MIDI (MME)") ("None"); - -#endif - - -std::vector -WavesAudioBackend::enumerate_midi_options () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::enumerate_midi_options ()" << std::endl; - return __available_midi_options; -} - - -int -WavesAudioBackend::set_midi_option (const std::string& option) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_midi_option ( " << option << " )" << std::endl; - if (option == __available_midi_options[1]) { - _use_midi = false; - // COMMENTED DBG LOGS */ std::cout << "\tNO MIDI system used)" << std::endl; - } - else if (option == __available_midi_options[0]) { - _use_midi = true; - // COMMENTED DBG LOGS */ std::cout << "\tNO MIDI system used)" << std::endl; - } - else { - std::cerr << "WavesAudioBackend::set_midi_option (): Invalid MIDI option!" << std::endl; - return -1; - } - - return 0; -} - - -std::string -WavesAudioBackend::midi_option () const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::midi_option ():" << std::endl; - return * (__available_midi_options.begin () + (_use_midi?0:1)); -} - - -int -WavesAudioBackend::midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buffer, void* port_buffer, uint32_t event_index) -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::midi_event_get ():" << std::endl; - - if (buffer == NULL) { - std::cerr << "WavesAudioBackend::midi_event_get () : NULL in the 'buffer' argument!\n"; - return -1; - } - - if (port_buffer == NULL) { - std::cerr << "WavesAudioBackend::midi_event_get () : NULL in the 'port_buffer' argument!\n"; - return -1; - } - - WavesMidiBuffer& source = * (WavesMidiBuffer*)port_buffer; - - if (event_index >= source.size ()) { - std::cerr << "WavesAudioBackend::midi_event_get () : 'event_index' is out of the number of events stored in 'port_buffer'!\n"; - return -1; - } - - WavesMidiEvent* waves_midi_event = source[event_index]; - - timestamp = waves_midi_event->timestamp (); - size = waves_midi_event->size (); - *buffer = waves_midi_event->data (); - - return 0; -} - - -int -WavesAudioBackend::midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size) -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::midi_event_put ():" << std::endl; - if (buffer == NULL) { - std::cerr << "WavesAudioBackend::midi_event_put () : NULL in the 'buffer' argument!\n"; - return -1; - } - - if (port_buffer == NULL) { - std::cerr << "WavesAudioBackend::midi_event_put () : NULL in the 'port_buffer' argument!\n"; - return -1; - } - - WavesMidiBuffer& target = * (WavesMidiBuffer*)port_buffer; - // COMMENTED FREQUENT DBG LOGS */ std::cout << "\t [" << target.name () << "]"<< std::endl; - - if (target.size () && (pframes_t)target.back ()->timestamp () > timestamp) { - std::cerr << "WavesAudioBackend::midi_event_put (): The MIDI Event to put is a bit late!" << std::endl; - std::cerr << "\tprev timestamp is " << (pframes_t)target.back ()->timestamp () << " as the current one is " << timestamp << std::endl; - return -1; - } - - target.push_back (new WavesMidiEvent (timestamp, buffer, size)); - return 0; -} - - -uint32_t -WavesAudioBackend::get_midi_event_count (void* port_buffer) -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::get_midi_event_count (): " << std::endl; - - if (port_buffer == NULL) { - std::cerr << "WavesAudioBackend::get_midi_event_count () : NULL in the 'port_buffer' argument!\n"; - return -1; - } - - // COMMENTED FREQUENT DBG LOGS */ std::cout << "\tcount = " << (* (WavesMidiBuffer*)port_buffer).size () << std::endl; - - return (* (WavesMidiBuffer*)port_buffer).size (); -} - - -void -WavesAudioBackend::midi_clear (void* port_buffer) -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::midi_clear (): " << std::endl; - if (port_buffer == NULL) { - std::cerr << "WavesAudioBackend::midi_clear () : NULL in the 'port_buffer' argument!\n"; - return; - } - - (* (WavesMidiBuffer*)port_buffer).clear (); -} - - -void -WavesAudioBackend::_changed_midi_devices () -{ - if (_midi_device_manager.stream (false)) { - std::cerr << "WavesAudioBackend::_changed_midi_devices (): _midi_device_manager.stream (false) failed!" << std::endl; - return; - } - - _unregister_system_midi_ports (); - _midi_device_manager.stop (); - - if (_midi_device_manager.start () != 0) { - std::cerr << "WavesAudioBackend::_changed_midi_devices (): _midi_device_manager.start () failed!" << std::endl; - return; - } - - if (_register_system_midi_ports () != 0) { - std::cerr << "WavesAudioBackend::_changed_midi_devices (): _register_system_midi_ports () failed!" << std::endl; - return; - } - - manager.registration_callback (); - - if (_midi_device_manager.stream (true)) { - std::cerr << "WavesAudioBackend::_changed_midi_devices (): _midi_device_manager.stream (true) failed!" << std::endl; - return; - } -} - - -void -WavesAudioBackend::_unregister_system_midi_ports () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_unregister_system_midi_ports ()" << std::endl; - std::vector physical_midi_ports = _physical_midi_inputs; - physical_midi_ports.insert (physical_midi_ports.begin (), _physical_midi_outputs.begin (), _physical_midi_outputs.end ()); - - for (std::vector::const_iterator it = physical_midi_ports.begin (); it != physical_midi_ports.end (); ++it) { - std::vector::iterator port_iterator = std::find (_ports.begin (), _ports.end (), *it); - if (port_iterator == _ports.end ()) { - std::cerr << "WavesAudioBackend::_unregister_system_midi_ports (): Failed to find port [" << (*it)->name () << "]!" << std::endl; - } - else - _ports.erase (port_iterator); - delete *it; - } - _physical_midi_inputs.clear (); - _physical_midi_outputs.clear (); -} - - -int -WavesAudioBackend::_register_system_midi_ports () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_register_system_midi_ports ()" << std::endl; - - LatencyRange lr = {0,0}; - lr.min = lr.max = _buffer_size; - - for (size_t i = 0; i<_ports.size ();) { - WavesMidiPort* midi_port = dynamic_cast (_ports[i]); - if (!midi_port || !midi_port->is_physical () || !midi_port->is_terminal ()) { - ++i; - continue; - } - - if ((midi_port->is_input () && !midi_port->midi_device ()->is_output ()) || - (midi_port->is_output () && !midi_port->midi_device ()->is_input ())) { - disconnect_all (midi_port); - unregister_port (midi_port); - continue; // to be here for further additions in the end of this loop - } - - ++i; - } - - const std::vector& devices = _midi_device_manager.devices (); - - for (std::vector::const_iterator it = devices.begin (); it != devices.end (); ++it) { - if ((*it)->is_input ()) { - std::string port_name = "system_midi:" + (*it)->name () + " capture"; - WavesDataPort* port = _find_port (port_name); - WavesMidiPort* midi_port = dynamic_cast (port); - if (midi_port && (midi_port->type () != DataType::MIDI || - midi_port->midi_device () != *it || - !midi_port->is_output () || - !midi_port->is_physical () || - !midi_port->is_terminal ())) { - std::cerr << "WavesAudioBackend::_register_system_midi_ports (): the port [" << midi_port->name () << "] is inconsystently constructed!" << std::endl; - disconnect_all (midi_port); - unregister_port (midi_port); - port = NULL; - } - - if (port == NULL) { - port = _register_port ( port_name, DataType::MIDI , static_cast (IsOutput | IsPhysical | IsTerminal)); - if (port == NULL) { - return -1; - } - ((WavesMidiPort*)port)->set_midi_device (*it); - } - port->set_latency_range (lr, false); - } - - if ((*it)->is_output ()) { - std::string port_name = "system_midi:" + (*it)->name () + " playback"; - WavesDataPort* port = _find_port (port_name); - WavesMidiPort* midi_port = dynamic_cast (port); - if (midi_port && (midi_port->type () != DataType::MIDI || - midi_port->midi_device () != *it || - !midi_port->is_input () || - !midi_port->is_physical () || - !midi_port->is_terminal ())) { - std::cerr << "WavesAudioBackend::_register_system_midi_ports (): the port [" << midi_port->name () << "] is inconsystently constructed!" << std::endl; - disconnect_all (midi_port); - unregister_port (midi_port); - } - - if (port == NULL) { - port = _register_port (port_name, - DataType::MIDI, - static_cast (IsInput | IsPhysical | IsTerminal)); - if (port == NULL) { - return -1; - } - } - - ((WavesMidiPort*)port)->set_midi_device ((*it)); - port->set_latency_range (lr, true); - } - } - - return 0; -} - - -int -WavesAudioBackend::_read_midi_data_from_devices () -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::_read_midi_data_from_devices ():" << std::endl; - if (!_midi_device_manager.is_streaming ()) - return 0; - - _midi_device_manager.do_read (); - - for (std::vector::iterator it = _physical_midi_inputs.begin (); it != _physical_midi_inputs.end (); ++it) { - WavesMidiDevice* midi_device = (*it)->midi_device (); - - WavesMidiBuffer& waves_midi_buffer = (*it)->buffer (); - waves_midi_buffer.clear (); - - while (WavesMidiEvent *waves_midi_event = midi_device->dequeue_input_waves_midi_event ()) { - int32_t timestamp_st = _buffer_size - (_sample_time_at_cycle_start - waves_midi_event->timestamp ()); - - if (timestamp_st < 0) { - timestamp_st = 0; - } else if (timestamp_st >= (int32_t)_buffer_size) { - timestamp_st = _buffer_size - 1; - } - waves_midi_event->set_timestamp (timestamp_st); - waves_midi_buffer.push_back (waves_midi_event); - } - } - return 0; -} - - -int -WavesAudioBackend::_write_midi_data_to_devices (pframes_t nframes) -{ - if (!_midi_device_manager.is_streaming ()) - return 0; - - for (std::vector::iterator it = _physical_midi_outputs.begin (); it != _physical_midi_outputs.end (); ++it) { - WavesMidiDevice* midi_device = (*it)->midi_device (); - WavesMidiBuffer &waves_midi_buffer = * (WavesMidiBuffer*) (*it)->get_buffer (nframes); - - for (WavesMidiBufferIterator it = waves_midi_buffer.begin (); it != waves_midi_buffer.end ();) { - WavesMidiEvent* waves_midi_event = *it; - - waves_midi_buffer.erase (it); - - waves_midi_event->set_timestamp (_sample_time_at_cycle_start + waves_midi_event->timestamp () + nframes); - midi_device->enqueue_output_waves_midi_event (waves_midi_event); - } - } - _midi_device_manager.do_write (); - return 0; -} diff --git a/libs/backends/wavesaudio/waves_audiobackend.port_engine.cc b/libs/backends/wavesaudio/waves_audiobackend.port_engine.cc deleted file mode 100644 index 203aa1f35d..0000000000 --- a/libs/backends/wavesaudio/waves_audiobackend.port_engine.cc +++ /dev/null @@ -1,661 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "waves_audiobackend.h" -#include "waves_audioport.h" -#include "waves_midiport.h" -#include "waves_midi_event.h" - -using namespace ARDOUR; - -uint32_t -WavesAudioBackend::port_name_size () const -{ - return 256+64; -} - -int -WavesAudioBackend::set_port_name (PortHandle port_handle, const std::string& port_name) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_port_name (): [" << std::hex << port_handle << std::dec << "], [" << port_name << "]" << std::endl; - - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::set_port_name (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return -1; - } - - return ((WavesAudioPort*)port_handle)->set_name (__instantiated_name + ":" + port_name); -} - - -std::string -WavesAudioBackend::get_port_name (PortHandle port_handle) const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::get_port_name (): [" << std::hex << port_handle << std::dec << "]" << std::endl; - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::get_port_name (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return std::string (); - } - // COMMENTED DBG LOGS */ else std::cout << "\t[" << ((WavesAudioPort*)port_handle)->name () << "]" << std::endl; - - return ((WavesAudioPort*)port_handle)->name (); -} - - -PortEngine::PortHandle -WavesAudioBackend::get_port_by_name (const std::string& port_name) const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::get_port_by_name (): [" << port_name << "]" << std::endl; - - PortHandle port_handle = (PortHandle)_find_port (port_name); - if (!port_handle) { - std::cerr << "WavesAudioBackend::get_port_by_name (): Failed to find port [" << port_name << "]!" << std::endl; - } - - return port_handle; -} - - -WavesDataPort* -WavesAudioBackend::_find_port (const std::string& port_name) const -{ - for (std::vector::const_iterator it = _ports.begin (); it != _ports.end (); ++it) { - if ((*it)->name () == port_name) { - return *it; - } - } - - return NULL; -} - - -int -WavesAudioBackend::get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector& port_names) const -{ - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::get_ports (): \n\tPattern: [" << port_name_pattern << "]\n\tType: " << type << "\n\tFlags: " << flags << endl; - - unsigned found_ports =0; - - for (size_t i = 0; i < _ports.size (); ++i) { - WavesDataPort* port = _ports[i]; - - if ((port->type () == type) && flags == (port->flags () & flags)) { - port_names.push_back (port->name ()); - found_ports++; - } - } - return found_ports; -} - - -DataType -WavesAudioBackend::port_data_type (PortHandle port_handle) const -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::port_data_type" << std::endl; - - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::port_data_type (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return DataType::NIL; - } - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::port_data_type: " << endl; - - return ((WavesAudioPort*)port_handle)->type (); -} - - -PortEngine::PortHandle -WavesAudioBackend::register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::register_port (): " << type.to_string () << " [" << shortname << "]" << std::endl; - - if (shortname.size () == 0) { - std::cerr << "WavesAudioBackend::register_port (): Invalid (empty) port name!" << std::endl; - return NULL; - } - - if (flags & IsPhysical) { - std::cerr << "WavesAudioBackend::register_port (): Unexpected attribute for port [" << shortname << "]! The port must not be physical!"; - return NULL; - } - - return (PortEngine::PortHandle)_register_port (__instantiated_name + ":" + shortname, type, flags); -} - - -WavesDataPort* -WavesAudioBackend::_register_port (const std::string& port_name, ARDOUR::DataType type, ARDOUR::PortFlags flags) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_register_port (): [" << port_name << "]" << std::endl; - - if (_find_port (port_name) != NULL) { - std::cerr << "WavesAudioBackend::register_port () : Port [" << port_name << "] is already registered!" << std::endl; - return NULL; - } - - WavesDataPort* port = NULL; - switch (type) { - case ARDOUR::DataType::AUDIO: { - WavesAudioPort* audio_port = new WavesAudioPort (port_name, flags); - if (flags & IsPhysical) - { - if (flags & IsOutput) - { - _physical_audio_inputs.push_back (audio_port); - // COMMENTED DBG LOGS */ std::cout << "\t\t" << port_name << " added to physical AUDIO Inputs !" << std::endl; - } - else if (flags & IsInput) - { - _physical_audio_outputs.push_back (audio_port); - // COMMENTED DBG LOGS */ std::cout << "\t\t" << port_name << " added to physical AUDIO Outputs !" << std::endl; - } - } - port = audio_port; - } break; - case ARDOUR::DataType::MIDI: { - WavesMidiPort* midi_port = new WavesMidiPort (port_name, flags); - if (flags & IsPhysical) - { - if (flags & IsOutput) - { - _physical_midi_inputs.push_back (midi_port); - // COMMENTED DBG LOGS */ std::cout << "\t\t" << port_name << " added to physical MIDI Inputs !" << std::endl; - } - else if (flags & IsInput) - { - _physical_midi_outputs.push_back (midi_port); - // COMMENTED DBG LOGS */ std::cout << "\t\t" << port_name << " added to physical MIDI Outputs !" << std::endl; - } - } - port = midi_port; - } break; - default: - std::cerr << "WavesAudioBackend::register_port () : Invalid data type (" << (uint32_t)type << ") applied to port [" << port_name << "]!" << std::endl; - return NULL; - } - - _ports.push_back (port); - - return port; -} - - -void -WavesAudioBackend::unregister_port (PortHandle port_handle) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::unregister_port ():" << std::hex << port_handle << std::dec << std::endl; - - // so far we suppose all disconnections will be done prior to unregistering. - WavesDataPort* port = (WavesDataPort*)port_handle; - std::vector::iterator port_iterator = std::find (_ports.begin (), _ports.end (), (WavesDataPort*)port_handle); - if (port_iterator == _ports.end ()) { - std::cerr << "WavesAudioBackend::unregister_port (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return; - } - // COMMENTED DBG LOGS */ std::cout << "\t[" << ((WavesDataPort*)port_handle)->name () << "]" << std::endl; - - _ports.erase (port_iterator); - - if (port->is_physical ()) { - if (port->is_output ()) { - switch (port->type ()) { - case ARDOUR::DataType::AUDIO: { - std::vector::iterator audio_port_iterator = std::find (_physical_audio_inputs.begin (), _physical_audio_inputs.end (), port); - if (audio_port_iterator == _physical_audio_inputs.end ()) { - std::cerr << "WavesAudioBackend::unregister_port (): Failed to find port [" << port->name () << "] in the list of registered physical audio inputs!" << std::endl; - return; - } - _physical_audio_inputs.erase (audio_port_iterator); - } - break; - case ARDOUR::DataType::MIDI: { - std::vector::iterator midi_port_iterator = std::find (_physical_midi_inputs.begin (), _physical_midi_inputs.end (), port); - if (midi_port_iterator == _physical_midi_inputs.end ()) { - std::cerr << "WavesAudioBackend::unregister_port (): Failed to find port [" << port->name () << "] in the list of registered physical midi inputs!" << std::endl; - return; - } - _physical_midi_inputs.erase (midi_port_iterator); - } - break; - default: - std::cerr << "WavesAudioBackend::unregister_port (): Invalid type (" << port->type () << " applied to [" << port->name () << "]!" << std::endl; - break; - } - } - else if (port->flags () & IsInput) { - switch (port->type ()) { - case ARDOUR::DataType::AUDIO: { - std::vector::iterator audio_port_iterator = std::find (_physical_audio_outputs.begin (), _physical_audio_outputs.end (), port); - if (audio_port_iterator == _physical_audio_outputs.end ()) - { - std::cerr << "WavesAudioBackend::unregister_port: Failed to find port [" << port->name () << std::dec << "] in the list of registered physical audio outputs!\n"; - return; - } - _physical_audio_outputs.erase (audio_port_iterator); - } - break; - case ARDOUR::DataType::MIDI: { - - std::vector::iterator midi_port_iterator = std::find (_physical_midi_outputs.begin (), _physical_midi_outputs.end (), port); - if (midi_port_iterator == _physical_midi_outputs.end ()) - { - std::cerr << "WavesAudioBackend::unregister_port: Failed to find port [" << port->name () << std::dec << "] in the list of registered physical midi outputs!\n"; - return; - } - _physical_midi_outputs.erase (midi_port_iterator); - } - break; - default: - std::cerr << "WavesAudioBackend::unregister_port (): Invalid type (" << port->type () << " applied to [" << port->name () << "]!" << std::endl; - break; - } - } - } - - delete port; -} - - -int -WavesAudioBackend::connect (const std::string& src_port_name, const std::string& dst_port_name) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::connect (" << src_port_name << ", " << dst_port_name << "):" << std::endl; - - WavesDataPort* src_port = _find_port (src_port_name); - if (src_port == NULL) { - std::cerr << "WavesAudioBackend::connect: Failed to find source port " << src_port_name << " !" << std::endl; - return -1; - } - - WavesDataPort* dst_port = _find_port (dst_port_name); - if (dst_port == NULL) { - std::cerr << "WavesAudioBackend::connect: Failed to find destination port " << dst_port_name << " !" << std::endl; - return -1; - } - - // COMMENTED DBG LOGS */ std::cout << "\t\t (" << src_port << ", " << dst_port << "):" << std::endl; - return src_port->connect (dst_port); -} - - -int -WavesAudioBackend::connect (PortHandle src_port_handle, const std::string& dst_port_name) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::connect ():" << std::endl; - if (!_registered (src_port_handle)) { - std::cerr << "WavesAudioBackend::connect: Failed to find source port [" << std::hex << src_port_handle << std::dec << "]!" << std::endl; - return -1; - } - - // COMMENTED DBG LOGS */ std::cout << "\t[" << std::hex << src_port_handle << std::dec << "]" << std::endl; - // COMMENTED DBG LOGS */ std::cout << "\t[" << dst_port_name << "]" << std::endl; - - WavesDataPort* dst_port = _find_port (dst_port_name); - if (dst_port == NULL) { - std::cerr << "WavesAudioBackend::connect (): Failed to find destination port [" << dst_port_name << "]!" << std::endl; - return -1; - } - - return ((WavesDataPort*)src_port_handle)->connect (dst_port); -} - - -int -WavesAudioBackend::disconnect (PortHandle src_port_handle, const std::string& dst_port_name) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::disconnect (" << src_port_handle << ", " << dst_port_name << "):" << std::endl; - if (!_registered (src_port_handle)) { - std::cerr << "WavesAudioBackend::disconnect (): Failed to find source port [" << std::hex << src_port_handle << std::dec << "]!" << std::endl; - return -1; - } - - // COMMENTED DBG LOGS */ std::cout << "\t[" << std::hex << src_port_handle << std::dec << "]" << std::endl; - // COMMENTED DBG LOGS */ std::cout << "\t[" << dst_port_name << "]" << std::endl; - - WavesDataPort* dst_port = _find_port (dst_port_name); - if (dst_port == NULL) { - std::cerr << "WavesAudioBackend::disconnect (): Failed to find destination port [" << dst_port_name << "]!" << std::endl; - return -1; - } - - return ((WavesDataPort*)src_port_handle)->disconnect (dst_port); -} - - -int -WavesAudioBackend::disconnect_all (PortHandle port_handle) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::disconnect_all ():" << std::endl; - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::disconnect_all : Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return -1; - } - - ((WavesDataPort*)port_handle)->disconnect_all (); - - return 0; -} - - -int -WavesAudioBackend::disconnect (const std::string& src_port_name, const std::string& dst_port_name) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::disconnect (" << src_port_name << ", " << dst_port_name << "):" << std::endl; - - WavesDataPort* src_port = _find_port (src_port_name); - if (src_port == NULL) { - std::cerr << "WavesAudioBackend::disconnect : Failed to find source port!\n"; - return -1; - } - - WavesDataPort* dst_port = _find_port (dst_port_name); - if (dst_port == NULL) { - std::cerr << "WavesAudioBackend::disconnect : Failed to find destination port!\n"; - return -1; - } - - return dst_port->disconnect (src_port); -} - - -bool -WavesAudioBackend::connected (PortHandle port_handle, bool process_callback_safe) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::connected ():" << std::endl; - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::connected (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return false; - } - - return ((WavesDataPort*)port_handle)->is_connected (); -} - - -bool -WavesAudioBackend::connected_to (PortHandle src_port_handle, const std::string& dst_port_name, bool process_callback_safe) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::connected_to (" << src_port_handle << ", " << dst_port_name << ")" << std::endl; - - if (!_registered (src_port_handle)) { - std::cerr << "WavesAudioBackend::connected_to : Failed to find source port!" << std::endl; - return false; - } - - WavesDataPort* dst_port = _find_port (dst_port_name); - if (dst_port == NULL) { - std::cerr << "WavesAudioBackend::connected_to : Failed to find destination port!" << std::endl; - return -1; - } - // COMMENTED DBG LOGS */ std::cout << "\t return " << ((((WavesDataPort*)src_port_handle)->is_connected (dst_port)) ? "YES":"NO") << ", " << dst_port_name << ")" << std::endl; - return ((WavesDataPort*)src_port_handle)->is_connected (dst_port); -} - - -bool -WavesAudioBackend::physically_connected (PortHandle port_handle, bool process_callback_safe) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::physically_connected ():" << std::endl; - - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::physically_connected (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return false; - } - - return ((WavesDataPort*)port_handle)->is_physically_connected (); -} - - -int -WavesAudioBackend::get_connections (PortHandle port_handle, std::vector& names, bool process_callback_safe) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::get_connections ()" << std::endl; - - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::get_connections (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return -1; - } - - if (names.size ()) { - std::cerr << "WavesAudioBackend::get_connections () : Parameter 'names' is not empty!\n"; - return -1; - } - - const std::vector& connected_ports = ((WavesDataPort*)port_handle)->get_connections (); - - for (std::vector::const_iterator it = connected_ports.begin (); it != connected_ports.end (); ++it) { - names.push_back ((*it)->name ()); - } - - return (int)names.size (); -} - - -int -WavesAudioBackend::request_input_monitoring (PortHandle, bool) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::request_input_monitoring: " << std::endl; - return 0; -} - - -int -WavesAudioBackend::ensure_input_monitoring (PortHandle, bool) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::ensure_input_monitoring: " << std::endl; - return 0; -} - - -bool -WavesAudioBackend::monitoring_input (PortHandle) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::monitoring_input: " << std::endl; - return false; -} - - -bool -WavesAudioBackend::port_is_physical (PortHandle port_handle) const -{ - - if (!_registered (port_handle)) { - std::cerr << "WavesAudioBackend::port_is_physical (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl; - return -1; - } - - return (((WavesAudioPort*)port_handle)->flags () & IsPhysical) != 0; -} - - -void -WavesAudioBackend::get_physical_outputs (DataType type, std::vector& names) -{ - names.clear(); - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::get_physical_outputs ():" << std::endl << "\tdatatype = " << type << std::endl; - - switch (type) { - case ARDOUR::DataType::AUDIO: { - for (std::vector::iterator it = _physical_audio_outputs.begin (); it != _physical_audio_outputs.end (); ++it) { - // COMMENTED DBG LOGS */ std::cout << "\t" << (*it)->name () << std::endl; - names.push_back ((*it)->name ()); - } - } break; - case ARDOUR::DataType::MIDI: { - for (std::vector::iterator it = _physical_midi_outputs.begin (); it != _physical_midi_outputs.end (); ++it) { - // COMMENTED DBG LOGS */ std::cout << "\t" << (*it)->name () << std::endl; - names.push_back ((*it)->name ()); - } - } break; - default: - break; - } -} - - -void -WavesAudioBackend::get_physical_inputs (DataType type, std::vector& names) -{ - names.clear(); - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::get_physical_inputs ():" << std::endl << "\tdatatype = " << type << std::endl; - switch (type) { - case ARDOUR::DataType::AUDIO: { - for (std::vector::iterator it = _physical_audio_inputs.begin (); it != _physical_audio_inputs.end (); ++it) { - // COMMENTED DBG LOGS */ std::cout << "\t" << (*it)->name () << std::endl; - names.push_back ((*it)->name ()); - } - } break; - case ARDOUR::DataType::MIDI: { - for (std::vector::iterator it = _physical_midi_inputs.begin (); it != _physical_midi_inputs.end (); ++it) { - // COMMENTED DBG LOGS */ std::cout << "\t" << (*it)->name () << std::endl; - names.push_back ((*it)->name ()); - } - } break; - default: - break; - } -} - - -ChanCount -WavesAudioBackend::n_physical_outputs () const -{ - ChanCount chan_count; - chan_count.set (DataType::AUDIO, _physical_audio_outputs.size ()); - chan_count.set (DataType::MIDI, _physical_midi_outputs.size ()); - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::n_physical_outputs ():" << std::endl << "\ttotal = " << chan_count.n_total () << std::endl; - - return chan_count; -} - - -ChanCount -WavesAudioBackend::n_physical_inputs () const -{ - ChanCount chan_count; - chan_count.set (DataType::AUDIO, _physical_audio_inputs.size ()); - chan_count.set (DataType::MIDI, _physical_midi_inputs.size ()); - - // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::n_physical_outputs ():" << std::endl << "\ttotal = " << chan_count.n_total () << std::endl; - - return chan_count; -} - - -void* -WavesAudioBackend::get_buffer (PortHandle port_handle, pframes_t nframes) -{ - // Here we would check if the port is registered. However, we will not do it as - // it's relatively VERY SLOW operation. So let's count on consistency - // of the caller as get_buffer normally is called hundreds of "kilotimes" per second. - - if (port_handle == NULL) { - std::cerr << "WavesAudioBackend::get_buffer : Invalid port handler !" << std::endl; - return NULL; - } - - return ((WavesAudioPort*)port_handle)->get_buffer (nframes); -} - - -int -WavesAudioBackend::_register_system_audio_ports () -{ - if (!_device) { - std::cerr << "WavesAudioBackend::_register_system_audio_ports (): No device is set!" << std::endl; - return -1; - } - - std::vector input_channels = _device->InputChannels (); - _max_input_channels = input_channels.size (); - - uint32_t channels = (_input_channels ? _input_channels : input_channels.size ()); - uint32_t port_number = 0; - - LatencyRange lr = {0,0}; - - // Get latency for capture - lr.min = lr.max = _device->GetLatency (false) + _device->CurrentBufferSize () + _systemic_input_latency; - for (std::vector::iterator it = input_channels.begin (); - (port_number < channels) && (it != input_channels.end ()); - ++it) { - - std::ostringstream port_name(*it); - WavesDataPort* port = _register_port ("system:capture:" + port_name.str (), DataType::AUDIO , - static_cast (IsOutput | IsPhysical | IsTerminal)); - - if (port == NULL) { - std::cerr << "WavesAudioBackend::_create_system_audio_ports (): Failed registering port [" << port_name << "] for [" << _device->DeviceName () << "]" << std::endl; - return-1; - } - set_latency_range (port, false, lr); - } - - std::vector output_channels = _device->OutputChannels (); - _max_output_channels = output_channels.size (); - channels = (_output_channels ? _output_channels : _max_output_channels); - port_number = 0; - - // Get latency for playback - lr.min = lr.max = _device->GetLatency (true) + _device->CurrentBufferSize () + _systemic_output_latency; - - for (std::vector::iterator it = output_channels.begin (); - (port_number < channels) && (it != output_channels.end ()); - ++it) { - - std::ostringstream port_name(*it); - WavesDataPort* port = _register_port ("system:playback:" + port_name.str (), DataType::AUDIO , - static_cast (IsInput| IsPhysical | IsTerminal)); - - if (port == NULL) { - std::cerr << "WavesAudioBackend::_create_system_audio_ports (): Failed registering port ]" << port_name << "] for [" << _device->DeviceName () << "]" << std::endl; - return-1; - } - set_latency_range (port, true, lr); - } - - return 0; -} - - -void -WavesAudioBackend::_unregister_system_audio_ports () -{ - std::vector physical_audio_ports = _physical_audio_inputs; - physical_audio_ports.insert (physical_audio_ports.begin (), _physical_audio_outputs.begin (), _physical_audio_outputs.end ()); - - for (std::vector::const_iterator it = physical_audio_ports.begin (); it != physical_audio_ports.end (); ++it) { - std::vector::iterator port_iterator = std::find (_ports.begin (), _ports.end (), *it); - if (port_iterator == _ports.end ()) { - std::cerr << "WavesAudioBackend::_unregister_system_audio_ports (): Failed to find port [" << (*it)->name () << "]!" << std::endl; - } - else { - _ports.erase (port_iterator); - } - delete *it; - } - - _physical_audio_inputs.clear (); - _physical_audio_outputs.clear (); -} - - diff --git a/libs/backends/wavesaudio/waves_audioport.cc b/libs/backends/wavesaudio/waves_audioport.cc deleted file mode 100644 index b8dac73137..0000000000 --- a/libs/backends/wavesaudio/waves_audioport.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "waves_audioport.h" -#include "ardour/runtime_functions.h" -#include "pbd/malign.h" - -using namespace ARDOUR; - -WavesAudioPort::WavesAudioPort (const std::string& port_name, PortFlags flags) - : WavesDataPort (port_name, flags) -{ - aligned_malloc ((void**)&_buffer, MAX_BUFFER_SIZE_BYTES, 32 /*32 byte alignment*/); - memset (_buffer, 0, MAX_BUFFER_SIZE_BYTES); -} - -WavesAudioPort::~WavesAudioPort () -{ - aligned_free (_buffer); -} - - -void* WavesAudioPort::get_buffer (pframes_t nframes) -{ - if (is_input ()) { - - std::vector::const_iterator it = get_connections ().begin (); - - if (it != get_connections ().end ()) { - /* In fact, the static casting to (const WavesAudioPort*) is not that safe. - * However, mixing the buffers is assumed in the time critical conditions. - * Base class WavesDataPort takes is supposed to provide enough consistentcy - * of the connections. - */ - - // get first buffer data - // use optimized function to fill the buffer intialy - ARDOUR::copy_vector (_buffer, ((const WavesAudioPort*)*it)->const_buffer (), nframes); - ++it; - - // mix the rest - for (; it != get_connections ().end (); ++it) { - Sample* tgt = buffer (); - const Sample* src = ((const WavesAudioPort*)*it)->const_buffer (); - - // use otimized function to mix the buffers - ARDOUR::mix_buffers_no_gain (tgt, src, nframes); - } - } - } - return _buffer; -} - - -void -WavesAudioPort::_wipe_buffer() -{ - memset (_buffer, 0, sizeof (_buffer)); -} diff --git a/libs/backends/wavesaudio/waves_audioport.h b/libs/backends/wavesaudio/waves_audioport.h deleted file mode 100644 index aebcaf6ce5..0000000000 --- a/libs/backends/wavesaudio/waves_audioport.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __libardour_waves_audioport_h__ -#define __libardour_waves_audioport_h__ - -#include "memory.h" -#include "waves_dataport.h" - -namespace ARDOUR { - -class WavesAudioPort : public WavesDataPort { - -public: - enum BufferSize { - MAX_BUFFER_SIZE_SAMPLES = 8192, - MAX_BUFFER_SIZE_BYTES = sizeof (Sample) * MAX_BUFFER_SIZE_SAMPLES - }; - - WavesAudioPort (const std::string& port_name, PortFlags flags); - - virtual ~WavesAudioPort (); - - virtual DataType type () const { return DataType::AUDIO; }; - - inline Sample* buffer () { return _buffer; } - inline const Sample* const_buffer () const { return _buffer; } - - virtual void* get_buffer (pframes_t nframes); - -protected: - virtual void _wipe_buffer(); - -private: - - Sample *_buffer; -}; - -} // namespace - -#endif /* __libardour_waves_audioport_h__ */ - diff --git a/libs/backends/wavesaudio/waves_dataport.cc b/libs/backends/wavesaudio/waves_dataport.cc deleted file mode 100644 index 5e958279f9..0000000000 --- a/libs/backends/wavesaudio/waves_dataport.cc +++ /dev/null @@ -1,150 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include "waves_dataport.h" - -using namespace ARDOUR; - -WavesDataPort::WavesDataPort (const std::string& inport_name, PortFlags inflags) - : _name (inport_name) - , _flags (inflags) -{ - _capture_latency_range.min = - _capture_latency_range.max = - _playback_latency_range.min = - _playback_latency_range.max = 0; -} - - -WavesDataPort::~WavesDataPort () -{ - _disconnect_all (); -} - - -int WavesDataPort::connect (WavesDataPort *port) -{ - if (!port) { - std::cerr << "WavesDataPort::connect (): invalid (null) port to connect to!" << std::endl; - return -1; - } - - if (type () != port->type ()) { - std::cerr << "WavesDataPort::connect (): wrong type of the port to connect to!" << std::endl; - return -1; - } - - if (is_output () && port->is_output ()) { - std::cerr << "WavesDataPort::connect (): attempt to connect output port to output port!" << std::endl; - return -1; - } - - if (is_input () && port->is_input ()) { - std::cerr << "WavesDataPort::connect (): attempt to connect input port to input port!" << std::endl; - return -1; - } - - if (this == port) { - std::cerr << "WavesDataPort::connect (): attempt to connect port to itself!" << std::endl; - return -1; - } - - if (is_connected (port)) { - // std::cerr << "WavesDataPort::connect (): the ports are already connected!" << std::endl; - return -1; - } - - _connect (port, true); - return 0; -} - - -void WavesDataPort::_connect (WavesDataPort *port, bool api_call) -{ - _connections.push_back (port); - if (api_call) { - port->_connect (this, false); - } -} - - -int WavesDataPort::disconnect (WavesDataPort *port) -{ - if (port == NULL) { - std::cerr << "WavesDataPort::disconnect (): invalid (null) port to disconnect from!" << std::endl; - return -1; - } - - if (!is_connected (port)) { - std::cerr << "WavesDataPort::disconnect (): the ports are not connected!" << std::endl; - return -1; - } - - _disconnect (port, true); - - return 0; -} - - -void WavesDataPort::_disconnect (WavesDataPort *port, bool api_call) -{ - std::vector::iterator it = std::find (_connections.begin (), _connections.end (), port); - - if (it != _connections.end ()) { // actually, it's supposed to be always true. - _connections.erase (it); - } - - if (api_call) { - port->_disconnect (this, false); - } - - if (is_input() && _connections.empty()) { - _wipe_buffer(); - } -} - - -void WavesDataPort::disconnect_all () -{ - _disconnect_all (); - - if (is_input()) { - _wipe_buffer(); - } -} - -void WavesDataPort::_disconnect_all () -{ - while (!_connections.empty ()) { - _connections.back ()->_disconnect (this, false); - _connections.pop_back (); - } -} - -bool WavesDataPort::is_physically_connected () const -{ - for (std::vector::const_iterator it = _connections.begin (); it != _connections.end (); ++it) { - if ((*it)->is_physical ()) { - return true; - } - } - - return false; -} diff --git a/libs/backends/wavesaudio/waves_dataport.h b/libs/backends/wavesaudio/waves_dataport.h deleted file mode 100644 index 7db11056e9..0000000000 --- a/libs/backends/wavesaudio/waves_dataport.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __libardour_waves_dataport_h__ -#define __libardour_waves_dataport_h__ - -#include "ardour/types.h" -#include "memory.h" - -namespace ARDOUR { - -class WavesDataPort { -public: - - virtual ~WavesDataPort (); - - inline const std::string& name () const - { - return _name; - } - - int set_name (const std::string &name) - { - _name = name; - return 0; - } - - virtual DataType type () const = 0; - - inline PortFlags flags () const - { - return _flags; - } - - inline bool is_input () { return flags () & IsInput; } - inline bool is_output () { return flags () & IsOutput; } - inline bool is_physical () { return flags () & IsPhysical; } - inline bool is_terminal () { return flags () & IsTerminal; } - inline operator void* () { return (void*)this; } - - inline const LatencyRange& latency_range (bool for_playback) const - { - return for_playback ? _playback_latency_range : _capture_latency_range; - } - - inline void set_latency_range (const LatencyRange &latency_range, bool for_playback) - { - if (for_playback) - { - _playback_latency_range = latency_range; - } - else - { - _capture_latency_range = latency_range; - } - } - - int connect (WavesDataPort *port); - - int disconnect (WavesDataPort *port); - - void disconnect_all (); - - bool inline is_connected (const WavesDataPort *port) const - { - return std::find (_connections.begin (), _connections.end (), port) != _connections.end (); - } - - bool inline is_connected () const - { - return _connections.size () != 0; - } - - bool is_physically_connected () const; - - inline const std::vector& get_connections () const { return _connections; } - - virtual void* get_buffer (pframes_t nframes) = 0; - -protected: - WavesDataPort (const std::string& inport_name, PortFlags inflags); - virtual void _wipe_buffer() = 0; - -private: - - std::string _name; - const PortFlags _flags; - LatencyRange _capture_latency_range; - LatencyRange _playback_latency_range; - std::vector _connections; - - void _connect (WavesDataPort* port, bool api_call); - void _disconnect_all (); - void _disconnect (WavesDataPort* port, bool api_call); -}; - -} // namespace - -#endif /* __libardour_waves_dataport_h__ */ - diff --git a/libs/backends/wavesaudio/waves_midi_buffer.cc b/libs/backends/wavesaudio/waves_midi_buffer.cc deleted file mode 100644 index 8d1d90b6cd..0000000000 --- a/libs/backends/wavesaudio/waves_midi_buffer.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -#include "waves_midi_buffer.h" -#include "waves_midi_event.h" - -using namespace ARDOUR; - -WavesMidiBuffer::WavesMidiBuffer (std::string name) - : std::vector () - , _name (name) -{ -} - -WavesMidiBuffer::~WavesMidiBuffer () -{ - clear (); -} - -void WavesMidiBuffer::clear () -{ - for (WavesMidiBufferIterator it = begin (); it != end (); ++it) - delete *it; - - std::vector::clear (); -} - -WavesMidiBuffer& WavesMidiBuffer::operator += (const WavesMidiBuffer& source) -{ - for (WavesMidiBufferConstIterator it = source.begin (); it != source.end (); ++it) { - push_back (new WavesMidiEvent (**it)); - } - return *this; -} diff --git a/libs/backends/wavesaudio/waves_midi_buffer.h b/libs/backends/wavesaudio/waves_midi_buffer.h deleted file mode 100644 index de5fc2cdb2..0000000000 --- a/libs/backends/wavesaudio/waves_midi_buffer.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __libardour_waves_midi_buffer_h__ -#define __libardour_waves_midi_buffer_h__ - -#include "ardour/types.h" - -namespace ARDOUR { - -class WavesMidiEvent; - -class WavesMidiBuffer : public std::vector -{ -public: - WavesMidiBuffer (std::string name); - ~WavesMidiBuffer (); - void clear (); - WavesMidiBuffer& operator += (const WavesMidiBuffer& source); - - inline const std::string name () { return _name; } // for DBG purpouses; - -private: - const std::string _name; -}; - -typedef std::vector::iterator WavesMidiBufferIterator; -typedef std::vector::const_iterator WavesMidiBufferConstIterator; - -} // namespace - -#endif /* __libardour_waves_midi_buffer_h__ */ diff --git a/libs/backends/wavesaudio/waves_midi_device.cc b/libs/backends/wavesaudio/waves_midi_device.cc deleted file mode 100644 index e9f0065abf..0000000000 --- a/libs/backends/wavesaudio/waves_midi_device.cc +++ /dev/null @@ -1,329 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include - -#include "pbd/error.h" -#include "pbd/debug.h" -#include "pbd/compose.h" -#include "pbd/stacktrace.h" - -#include "waves_midi_device.h" -#include "waves_midi_event.h" - -// use non-zero latency because we want output to be timestapmed -#define LATENCY 0 - -#define QUEUE_LENGTH 1024 - -using namespace ARDOUR; -using namespace PBD; - -WavesMidiDevice::WavesMidiDevice (const std::string& device_name) - : _pm_input_id (pmNoDevice) - , _pm_output_id (pmNoDevice) - , _name (device_name) - , _input_queue (NULL) - , _output_queue (NULL) - , _input_pm_stream (NULL) - , _output_pm_stream (NULL) - , _incomplete_waves_midi_event (NULL) -{ - _pm_input_id = _pm_output_id = pmNoDevice; - int count = Pm_CountDevices (); - - for (int i = 0; i < count; i++) { - - const PmDeviceInfo* pm_device_info = Pm_GetDeviceInfo (i); - - if (pm_device_info == NULL) { - continue; - } - if (name () == pm_device_info->name) { - if (pm_device_info->input){ - _pm_input_id = i; - } - if (pm_device_info->output){ - _pm_output_id = i; - } - } - } -} - -WavesMidiDevice::~WavesMidiDevice () -{ - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::~WavesMidiDevice (): %1\n", name())); - close (); -} - -int -WavesMidiDevice::open (PmTimeProcPtr time_proc, void* time_info) -{ - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::open (): %1", name ())); - - if (is_input () ) { - // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::open (): INPUT" << _pm_input_id << "-[" << name () << "]" << std::endl; - - if (!_input_pm_stream) { - // create queue - if (!_input_queue) { - // COMMENTED DBG LOGS */ std::cout << " going to Pm_QueueCreate for INPUT: " << std::endl; - _input_queue = Pm_QueueCreate (QUEUE_LENGTH, sizeof (const WavesMidiEvent*)); - // COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl; - if (NULL == _input_queue) { - std::cerr << "WavesMidiDevice::open (): _input_queue = Pm_QueueCreate () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl; - return -1; - } - } - // create stream - // COMMENTED DBG LOGS */ std::cout << " going to Pm_OpenInput : " << std::endl; - if (pmNoError != Pm_OpenInput (&_input_pm_stream, - _pm_input_id, - NULL, - 1024, - time_proc, - time_info)) { - // COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl; - char* err_msg = new char[256]; - Pm_GetHostErrorText(err_msg, 256); - std::cerr << "WavesMidiDevice::open (): Pm_OpenInput () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl; - std::cerr << " Port Midi Host Error: " << err_msg << std::endl; - close (); - return -1; - } - // COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl; - } - } - - if (is_output () ) { - // COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::open (): OUTPUT" << _pm_output_id << "-[" << name () << "]" << std::endl; - - if (!_output_pm_stream) { - // create queue - if (!_output_queue) { - // COMMENTED DBG LOGS */ std::cout << " going to Pm_QueueCreate for OUTPUT : " << std::endl; - _output_queue = Pm_QueueCreate (QUEUE_LENGTH, sizeof (const WavesMidiEvent*)); - // COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl; - if (NULL == _output_queue) { - std::cerr << "WavesMidiDevice::open (): _output_queue = Pm_QueueCreate () failed for " << _pm_output_id << "-[" << name () << "]!" << std::endl; - return -1; - } - } - // create stream - // COMMENTED DBG LOGS */ std::cout << " going to Pm_OpenOutput : " << std::endl; - if (pmNoError != Pm_OpenOutput (&_output_pm_stream, - _pm_output_id, - NULL, - 1024, - time_proc, - time_info, - LATENCY)) { - // COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl; - char* err_msg = new char[256]; - Pm_GetHostErrorText(err_msg, 256); - std::cerr << "WavesMidiDevice::open (): Pm_OpenOutput () failed for " << _pm_output_id << "-[" << name () << "]!" << std::endl; - std::cerr << " Port Midi Host Error: " << err_msg << std::endl; - close (); - return -1; - } - // COMMENTED DBG LOGS */ std::cout << " DONE : " << std::endl; - } - } - return 0; -} - -void -WavesMidiDevice::close () -{ - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::close (): %1\n", name ())); - WavesMidiEvent *waves_midi_event; - - // save _input_pm_stream and _output_pm_stream to local buf - PmStream* input_pm_stream = _input_pm_stream; - PmStream* output_pm_stream = _output_pm_stream; - _input_pm_stream = _output_pm_stream = NULL; - - // input - if (input_pm_stream) { - // close stream - PmError err = Pm_Close (input_pm_stream); - if (err != pmNoError) { - char* err_msg = new char[256]; - Pm_GetHostErrorText(err_msg, 256); - std::cerr << "WavesMidiDevice::close (): Pm_Close (input_pm_stream) failed (" << err << ") for " << input_pm_stream << "-[" << name () << "]!" << std::endl; - std::cerr << " Port Midi Host Error: " << err_msg << std::endl; - } - _pm_input_id = pmNoDevice; - } - - // close queue - if (_input_queue) { - while (1 == Pm_Dequeue (_input_queue, &waves_midi_event)) { - delete waves_midi_event; // XXX possible dup free in ~WavesMidiBuffer() (?) - } - Pm_QueueDestroy (_input_queue); - _input_queue = NULL; - } - - // output - if ( output_pm_stream ) { - // close stream - PmError err = Pm_Close (output_pm_stream); - if (err != pmNoError) { - char* err_msg = new char[256]; - Pm_GetHostErrorText(err_msg, 256); - std::cerr << "WavesMidiDevice::close (): Pm_Close (output_pm_stream) failed (" << err << ") for " << output_pm_stream << "-[" << name () << "]!" << std::endl; - std::cerr << " Port Midi Host Error: " << err_msg << std::endl; - } - _pm_output_id = pmNoDevice; - } - - // close queue - if (_output_queue) { - while (1 == Pm_Dequeue (_output_queue, &waves_midi_event)) { - delete waves_midi_event; // XXX possible dup free in ~WavesMidiBuffer() (?) - } - Pm_QueueDestroy (_output_queue); - _output_queue = NULL; - } -} - -void -WavesMidiDevice::do_io () -{ - read_midi (); - write_midi (); -} - -void -WavesMidiDevice::read_midi () -{ - if (NULL == _input_pm_stream) { - return; - } - - while (Pm_Poll (_input_pm_stream) > 0) { - - PmEvent pm_event; // just one message at a time - int result = Pm_Read (_input_pm_stream, &pm_event, 1); - - if (result < 0) { - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("Pm_Read failed for (): [%1]\n", name())); - break; - } - - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] evt-tm: %2\n", name(), pm_event.timestamp)); - - if (_incomplete_waves_midi_event == NULL ) { - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] new incomplete_waves_midi_event\n", name())); - _incomplete_waves_midi_event = new WavesMidiEvent (pm_event.timestamp); - } - - WavesMidiEvent *nested_pm_event = _incomplete_waves_midi_event->append_data (pm_event); - - if (nested_pm_event) { - Pm_Enqueue (_input_queue, &nested_pm_event); - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] : Pm_Enqueue (_input_queue, nested_pm_event)\n", name())); - } - - switch ( _incomplete_waves_midi_event->state ()) { - case WavesMidiEvent::BROKEN: - delete _incomplete_waves_midi_event; - _incomplete_waves_midi_event = NULL; - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] : case WavesMidiEvent::BROKEN:\n", name())); - break; - case WavesMidiEvent::COMPLETE: - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_read_midi (): [%1] : Pm_Enqueue (_input_queue, _incomplete_waves_midi_event); %3\n", name (), _incomplete_waves_midi_event)); - - if (pmNoError != Pm_Enqueue (_input_queue, &_incomplete_waves_midi_event) ) { - char* err_msg = new char[256]; - Pm_GetHostErrorText(err_msg, 256); - std::cerr << "WavesMidiDevice::read_midi (): Pm_Enqueue () failed for [" << name () << "]!" << std::endl; - std::cerr << "Error: " << err_msg << std::endl; - } - - _incomplete_waves_midi_event = NULL; - break; - default: - break; - } - } -} - -void -WavesMidiDevice::write_midi () -{ - if (NULL == _output_pm_stream) { - return; - } - - PmError err; - WavesMidiEvent *waves_midi_event; - - while (1 == Pm_Dequeue (_output_queue, &waves_midi_event)) { - if (waves_midi_event->sysex ()) { - // LATENCY compensation - err = Pm_WriteSysEx (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, waves_midi_event->data ()); - if (0 > err) { - std::cerr << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteSysEx () failed (" << err << ")!" << std::endl; - }; - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_write_midi (): SYSEX used, ev->tm: %1", waves_midi_event->timestamp () - LATENCY)); - } - else - { - err = Pm_WriteShort (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, * (PmMessage*)waves_midi_event->data ()); - if (0 > err) { - error << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteShort () failed (" << err << ")!" << endmsg; - } - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::_write_midi (): SHORTMSG used, ev->tm: %1\n", waves_midi_event->timestamp () - LATENCY)); - } - } - - return; -} - -int -WavesMidiDevice::enqueue_output_waves_midi_event (const WavesMidiEvent* waves_midi_event) -{ - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ("WavesMidiDevice::enqueue_output_waves_midi_event () [%1]\n", name())); - - if (waves_midi_event == NULL) { - error << "WavesMidiDevice::put_event_to_callback (): 'waves_midi_event' is NULL!" << endmsg; - return -1; - } - - PmError err = Pm_Enqueue (_output_queue, &waves_midi_event); - - if (0 > err) { - error << "WavesMidiDevice::put_event_to_callback (): Pm_Enqueue () failed (" << err << ")!" << endmsg; - return -1; - }; - - return 0; -} - -WavesMidiEvent* -WavesMidiDevice::dequeue_input_waves_midi_event () -{ - WavesMidiEvent* waves_midi_event; - if (Pm_Dequeue (_input_queue, &waves_midi_event) == 1) { - return waves_midi_event; - } - return NULL; -} diff --git a/libs/backends/wavesaudio/waves_midi_device.h b/libs/backends/wavesaudio/waves_midi_device.h deleted file mode 100644 index 430b3eab07..0000000000 --- a/libs/backends/wavesaudio/waves_midi_device.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __libardour_waves_midi_device_h__ -#define __libardour_waves_midi_device_h__ - -#include -#include -#include - -#include "ardour/types.h" - -namespace ARDOUR { - -class WavesMidiEvent; - -class WavesMidiDevice { -public: - WavesMidiDevice (const std::string& name); - ~WavesMidiDevice (); - - inline const std::string& name () const { return _name; } - - int open (PmTimeProcPtr time_proc, void* time_info); - void close (); - void do_io (); - void read_midi (); - void write_midi (); - - int enqueue_output_waves_midi_event (const WavesMidiEvent* waves_midi_event); - WavesMidiEvent* dequeue_input_waves_midi_event (); - - inline bool is_input () const { return _pm_input_id != pmNoDevice; }; - inline bool is_output () const { return _pm_output_id != pmNoDevice; }; - -private: - - - PmDeviceID _pm_input_id; - PmDeviceID _pm_output_id; - const std::string _name; - - /* shared queues */ - PmQueue* _input_queue; - PmQueue* _output_queue; - - PmStream* _input_pm_stream; - PmStream* _output_pm_stream; - WavesMidiEvent *_incomplete_waves_midi_event; -}; - -} // namespace - -#endif /* __libardour_waves_midi_device_h__ */ - diff --git a/libs/backends/wavesaudio/waves_midi_device_manager.cc b/libs/backends/wavesaudio/waves_midi_device_manager.cc deleted file mode 100644 index 45044ea7a7..0000000000 --- a/libs/backends/wavesaudio/waves_midi_device_manager.cc +++ /dev/null @@ -1,245 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "waves_midi_device_manager.h" -#include "waves_audiobackend.h" - -#ifdef PLATFORM_WINDOWS - -#include "windows.h" -#include "mmsystem.h" - -#elif defined(__APPLE__) - -#include - -#define midiInGetNumDevs MIDIGetNumberOfSources -#define midiOutGetNumDevs MIDIGetNumberOfDestinations - -#endif - -using namespace ARDOUR; - -WavesMidiDeviceManager::WavesMidiDeviceManager (WavesAudioBackend& audiobackend) - : _active (false) - , _streaming (false) - , _input_device_count (0) - , _output_device_count (0) - , _audiobackend (audiobackend) -{ -} - - -WavesMidiDeviceManager::~WavesMidiDeviceManager () -{ -} - - -int -WavesMidiDeviceManager::start () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::start ():" << std::endl; - if ( _active == true ) { - return -1; - } - - if (Pm_Initialize () != pmNoError) { - return -1; - } - - _create_devices (); - - _input_device_count = midiInGetNumDevs (); - _output_device_count = midiOutGetNumDevs (); - - _active = true; - - return 0; -} - - -int -WavesMidiDeviceManager::stream (bool yn) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::stream (" << (yn?"true":"false") << "):" << std::endl; - if (!_active) { - std::cerr << "WavesMidiDeviceManager::stream (): the midi device manager is not started up !" << std::endl; - return -1; - } - - if (_streaming == yn) { - return 0; - } - - if (yn) { - // __portmidi_callback will be called once per 50 msec - if ( Pt_Start (50, __portmidi_callback, this) != ptNoError) { - std::cerr << "WavesMidiDeviceManager::stream (): Pt_Start () failed!" << std::endl; - return -1; - } - } - else { - if (Pt_Stop () != ptNoError) { - std::cerr << "WavesMidiDeviceManager::stream (): Pt_Stop () failed!" << std::endl; - return -1; - } - } - - _streaming = yn; - return 0; -} - - -int -WavesMidiDeviceManager::stop () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::stop ():" << std::endl; - - if ( _active == false ) { - return 0; - } - - stream (false); - - _delete_devices (); - _active = false; - - if (Pm_Terminate () != pmNoError) { - std::cerr << "WavesMidiDeviceManager::stop (): Pt_Terminate () failed!" << std::endl; - return -1; - } - - return 0; -} - -void -WavesMidiDeviceManager::__portmidi_callback (PtTimestamp timestamp, void * userData) -{ - // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesMidiDeviceManager::__portmidi_callback ():" << std::endl; - WavesMidiDeviceManager *dm = (WavesMidiDeviceManager *)userData; - - if (dm == NULL) { - return; - } - - dm->_portmidi_callback (timestamp); -} - -void -WavesMidiDeviceManager::_portmidi_callback (PtTimestamp timestamp) -{ - if ((!_active) || (!_streaming)) { - return; - } - - if ((_input_device_count != midiInGetNumDevs ()) || (_output_device_count != midiOutGetNumDevs ())) { - _audiobackend._changed_midi_devices (); - // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::_portmidi_callback ():" << std::endl; - // COMMENTED DBG LOGS */ std::cout << " _input_device_count ?= midiInGetNumDevs () :" << _input_device_count << " ?= " << midiInGetNumDevs () << std::endl; - // COMMENTED DBG LOGS */ std::cout << " _output_device_count ?= midiOutGetNumDevs () :" << _output_device_count << " ?= " << midiOutGetNumDevs () << std::endl; - } -} - -void WavesMidiDeviceManager::do_read () -{ - for (std::vector::const_iterator it = _devices.begin (); it != _devices.end (); ++it) { - (*it)->read_midi (); - } -} - - -void WavesMidiDeviceManager::do_write () -{ - for (std::vector::const_iterator it = _devices.begin (); it != _devices.end (); ++it) { - (*it)->write_midi (); - } -} - - -PmTimestamp -WavesMidiDeviceManager::__get_time_ms (void *time_info) -{ - return ((WavesAudioBackend*)time_info)->sample_time (); -} - - -WavesMidiDevice* WavesMidiDeviceManager::_get_device (const std::string& name) -{ - // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::_get_device ():" << std::endl; - for (size_t i = 0; i < _devices.size (); i++) { - if (name == _devices[i]->name ()) { - return _devices[i]; - } - } - return NULL; -} - - -int -WavesMidiDeviceManager::_create_devices () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::_create_devices () :" << std::endl; - int count = Pm_CountDevices (); - - for (int i = 0; i < count; i++) { - - const PmDeviceInfo* pm_device_info = Pm_GetDeviceInfo (i); - // COMMENTED DBG LOGS */ std::cout << " interf : " << pm_device_info->interf << std::endl; - // COMMENTED DBG LOGS */ std::cout << " name : " << pm_device_info->name << std::endl; - // COMMENTED DBG LOGS */ std::cout << " input : " << pm_device_info->input << std::endl; - // COMMENTED DBG LOGS */ std::cout << " output : " << pm_device_info->output << std::endl; - // COMMENTED DBG LOGS */ std::cout << " opened : " << pm_device_info->opened << std::endl; -#if defined (PLATFORM_WINDOWS) - if (strncmp (pm_device_info->name, "Microsoft", strlen ("Microsoft")) == 0) { - // COMMENTED DBG LOGS */ std::cout << " skipping anything from Microsoft :" << pm_device_info->name << std::endl; - continue; - } -#endif - if (pm_device_info == NULL) { - std::cerr << "WavesMidiDeviceManager::_create_devices (): Pm_GetDeviceInfo (" << i << ") failed!" << std::endl; - continue; - } - - WavesMidiDevice *device = _get_device (pm_device_info->name); - if (!device) { - device = new WavesMidiDevice (pm_device_info->name); - _devices.push_back (device); - if (device->open (__get_time_ms, (void*)&_audiobackend)) { - std::cerr << "WavesMidiDeviceManager::_create_devices (): [" << device->name () << "]->open () failed!" << std::endl; - } - } - } - - return 0; -} - - -int -WavesMidiDeviceManager::_delete_devices () -{ - // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::_delete_devices ():" << std::endl; - while (!_devices.empty ()) { - WavesMidiDevice * device = _devices.back (); - _devices.pop_back (); - device->close (); - delete device; - } - return 0; -} - diff --git a/libs/backends/wavesaudio/waves_midi_device_manager.h b/libs/backends/wavesaudio/waves_midi_device_manager.h deleted file mode 100644 index fde4fc312f..0000000000 --- a/libs/backends/wavesaudio/waves_midi_device_manager.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __libardour_waves_midi_device_manager_h__ -#define __libardour_waves_midi_device_manager_h__ - -#include "waves_midi_device.h" - -namespace ARDOUR { - -class WavesAudioBackend; - -class WavesMidiDeviceManager { -public: - WavesMidiDeviceManager (WavesAudioBackend& audiobackend); - ~WavesMidiDeviceManager (); - - inline const std::vector& devices () const - { - return _devices; - } - - int start (); - int stop (); - int stream (bool yn); - int is_streaming () { return _streaming; } - void do_read (); - void do_write (); - -private: - - int _create_devices (); - int _delete_devices (); - static void __portmidi_callback (PtTimestamp timestamp, void * userData); - void _portmidi_callback (PtTimestamp timestamp); - /** __get_time_ms is given to Pm_Open functions (see WavesMidiDevice.cc) - * to provide the time in milliseconds using the time of audio - * transport. - * time_info is a pointer on the backend instance, which agregates the - * audio and miditransports. It's not checked for correctness to consume - * no time. - */ - static PmTimestamp __get_time_ms (void *time_info); - - WavesMidiDevice* _get_device (const std::string& name); - - std::vector _devices; // Vector for midi devices - bool _active; - bool _streaming; - - size_t _input_device_count; - size_t _output_device_count; - WavesAudioBackend& _audiobackend; -}; - -} // namespace - -#endif /* __libardour_waves_midi_device_manager_h__ */ - diff --git a/libs/backends/wavesaudio/waves_midi_event.cc b/libs/backends/wavesaudio/waves_midi_event.cc deleted file mode 100644 index 70137c537b..0000000000 --- a/libs/backends/wavesaudio/waves_midi_event.cc +++ /dev/null @@ -1,197 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "pbd/debug.h" -#include "pbd/compose.h" - -#include "memory.h" -#include "waves_midi_event.h" - -using namespace ARDOUR; -using namespace PBD; - -WavesMidiEvent::WavesMidiEvent (PmTimestamp timestamp) - : _size (0) - , _timestamp (timestamp) - , _data (NULL) - , _state (INCOMPLETE) -{ - -} - - -WavesMidiEvent::WavesMidiEvent (PmTimestamp timestamp, const uint8_t* data, size_t datalen) - : _size (datalen) - , _timestamp (timestamp) - , _data (data && datalen ? new uint8_t[ (datalen < sizeof (PmMessage)) ? sizeof (PmMessage) : datalen] : NULL) - , _state (data && datalen ? COMPLETE : BROKEN) -{ - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=%1---%2\n", _size, datalen)); - if (_state == COMPLETE) { - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "\t\t\t Allocated Size=%1\n", ((datalen < sizeof (PmMessage)) ? sizeof (PmMessage) : datalen))); - memcpy (_data, data, datalen); - -#ifndef NDEBUG - if (DEBUG_ENABLED (DEBUG::WavesMIDI)) { - DEBUG_STR_DECL(a); - for (size_t i=0; i < datalen; ++i) { - DEBUG_STR_APPEND(a,std::hex); - DEBUG_STR_APPEND(a,"0x"); - DEBUG_STR_APPEND(a,(int)data[i]); - DEBUG_STR_APPEND(a,' '); - } - DEBUG_STR_APPEND(a,'\n'); - DEBUG_TRACE (DEBUG::WavesMIDI, DEBUG_STR(a).str()); - } -#endif - - } -} - -WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) - : _size (source.size ()) - , _timestamp (source.timestamp ()) - , _data ((source.size () && source.const_data ()) ? new uint8_t[ (source.size () < sizeof (PmMessage)) ? sizeof (PmMessage) : source.size ()] : NULL) - , _state (source.state () ) -{ - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::WavesMidiEvent (const WavesMidiEvent& source) : Size=%1---%2\n", _size, source.size ())); - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "\t\t\t Allocated Size=%1\n", ((source.size () < sizeof (PmMessage)) ? sizeof (PmMessage) : source.size ()))); - if (_data && source.const_data ()) { - memcpy (_data, source.const_data (), source.size ()); - -#ifndef NDEBUG - if (DEBUG_ENABLED (DEBUG::WavesMIDI)) { - DEBUG_STR_DECL(a); - for (size_t i=0; i < source.size(); ++i) { - DEBUG_STR_APPEND(a,std::hex); - DEBUG_STR_APPEND(a,"0x"); - DEBUG_STR_APPEND(a,(int)source.const_data()[i]); - DEBUG_STR_APPEND(a,' '); - } - DEBUG_STR_APPEND(a,'\n'); - DEBUG_TRACE (DEBUG::WavesMIDI, DEBUG_STR(a).str()); - } -#endif - } -} - - -WavesMidiEvent::~WavesMidiEvent () -{ - delete _data; -} - - -WavesMidiEvent *WavesMidiEvent::append_data (const PmEvent &midi_event) -{ - switch ( _state ) { - case INCOMPLETE: - break; - default: - DEBUG_TRACE (DEBUG::WavesMIDI, "WavesMidiEvent::append_data (): NO case INCOMPLETE\n"); - _state = BROKEN; - return NULL; - } - - size_t message_size = _midi_message_size (midi_event.message); - uint8_t message_status = Pm_MessageStatus (midi_event.message); - - if (_data == NULL) { // This is a first event to add - bool sysex = (message_status == SYSEX); - _data = new unsigned char [sysex ? PM_DEFAULT_SYSEX_BUFFER_SIZE : sizeof (PmMessage)]; - if (!sysex) - { - DEBUG_TRACE (DEBUG::WavesMIDI, "WavesMidiEvent::append_data (): SHORT MSG\n"); - * (PmMessage*)_data = 0; - switch (message_size) { - case 1: - case 2: - case 3: - _size = message_size; - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::append_data (): size = %1\n", _size)); - break; - default: - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "WavesMidiEvent::append_data (): WRONG MESSAGE SIZE (%1 not %2) %3 [%4 %5 %6 %7] %8\n", - message_size, - std::hex, - (int) ((unsigned char*)&midi_event)[0], - (int) ((unsigned char*)&midi_event)[1], - (int) ((unsigned char*)&midi_event)[2], - (int) ((unsigned char*)&midi_event)[3], - std::dec)); - _state = BROKEN; - return NULL; - } - memcpy (_data, &midi_event.message, _size); - _state = COMPLETE; - DEBUG_TRACE (DEBUG::WavesMIDI, string_compose ( "\t\t\t size = %1\n", _size)); - return NULL; - } - } - - // Now let's parse to sysex msg - if (message_status >= REAL_TIME_FIRST) { // Nested Real Time MIDI event - WavesMidiEvent *waves_midi_message = new WavesMidiEvent (midi_event.timestamp); - waves_midi_message->append_data (midi_event); - return waves_midi_message; - } - - if (message_status >= STATUS_FIRST && (message_status != EOX) && _size) { // Certainly it's a broken SYSEX case - WavesMidiEvent *waves_midi_message = new WavesMidiEvent (midi_event.timestamp); - waves_midi_message->append_data (midi_event); - return waves_midi_message; - } - - const uint8_t* source_data ((uint8_t*)&midi_event.message); - - for (size_t i = 0; i < sizeof (midi_event.message); ++i) { - _data[_size] = source_data[i]; - _size++; - - if (source_data[i] == EOX) { // Ended SYSEX message - _state = COMPLETE; - return NULL; - } - } - return NULL; -} - -size_t WavesMidiEvent::_midi_message_size (PmMessage midi_message) -{ - static int high_lengths[] = { - 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 through 0x70 */ - 3, 3, 3, 3, 2, 2, 3, 1 /* 0x80 through 0xf0 */ - }; - - static int low_lengths[] = { - 1, 2, 3, 2, 1, 1, 1, 1, /* 0xf0 through 0xf7 */ - 1, 1, 1, 1, 1, 1, 1, 1 /* 0xf8 through 0xff */ - }; - - int midi_message_status = Pm_MessageStatus (midi_message); - - if (midi_message_status < STATUS_FIRST) { - return sizeof (midi_message); - } - - int high = midi_message_status >> 4; - int low = midi_message_status & 0xF; - - return (high != 0xF) ? high_lengths[high] : low_lengths[low]; -} diff --git a/libs/backends/wavesaudio/waves_midi_event.h b/libs/backends/wavesaudio/waves_midi_event.h deleted file mode 100644 index 392cce02a4..0000000000 --- a/libs/backends/wavesaudio/waves_midi_event.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __libardour_waves_midi_event_h__ -#define __libardour_waves_midi_event_h__ - -#include -#include -#include "ardour/types.h" - -namespace ARDOUR { - -class WavesMidiEvent -{ -public: - enum State { - INCOMPLETE, - BROKEN, - COMPLETE - }; - - WavesMidiEvent (PmTimestamp timestamp); - WavesMidiEvent (PmTimestamp timestamp, const uint8_t* data, size_t datalen); - WavesMidiEvent (const WavesMidiEvent& source); - ~WavesMidiEvent (); - - WavesMidiEvent *append_data (const PmEvent &midi_event); - - inline State state () const { return _state; }; - inline size_t size () const { return _size; }; - inline PmTimestamp timestamp () const { return _timestamp; }; - inline void set_timestamp (PmTimestamp time_stamp) { _timestamp = time_stamp; }; - inline const unsigned char* const_data () const { return _data; }; - inline unsigned char* data () { return _data; }; - inline bool operator< (const WavesMidiEvent &other) const { return timestamp () < other.timestamp (); }; - inline bool sysex () const { return _data && (*_data == SYSEX); }; - -private: - - enum - { - SYSEX = 0xF0, - EOX = 0xF7, - REAL_TIME_FIRST = 0xF8, - STATUS_FIRST = 0x80 - }; - - size_t _size; - PmTimestamp _timestamp; - uint8_t *_data; - State _state; - - static size_t _midi_message_size (PmMessage midi_message); -}; - - -} // namespace - -#endif /* __libardour_waves_midi_event_h__ */ diff --git a/libs/backends/wavesaudio/waves_midiport.cc b/libs/backends/wavesaudio/waves_midiport.cc deleted file mode 100644 index df9566ea7b..0000000000 --- a/libs/backends/wavesaudio/waves_midiport.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "waves_midiport.h" -#include "waves_midi_event.h" - -using namespace ARDOUR; - -WavesMidiPort::WavesMidiPort (const std::string& port_name, PortFlags flags) - : WavesDataPort (port_name, flags) - , _midi_device (NULL) - , _waves_midi_buffer (port_name) -{ -} - -struct MidiEventSorter { - bool operator() (const WavesMidiEvent* a, const WavesMidiEvent* b) { - return *a < *b; - } -}; - -void* -WavesMidiPort::get_buffer (pframes_t nframes) -{ - if (is_input ()) { - std::vector::const_iterator cit = get_connections ().begin (); - if (cit != get_connections ().end ()) { - _waves_midi_buffer.clear (); - WavesMidiBuffer& target = _waves_midi_buffer; - - do { - /* In fact, the static casting to (const WavesMidiPort*) is not that safe. - * However, mixing the buffers is assumed in the time critical conditions. - * Base class WavesDataPort is supposed to provide enough consistentcy - * of the connections. - */ - target += ((const WavesMidiPort*)*cit)->const_buffer (); - }while((++cit) != get_connections ().end ()); - - std::sort (target.begin (), target.end (), MidiEventSorter()); - } - } - - return &_waves_midi_buffer; -} - -void -WavesMidiPort::_wipe_buffer() -{ - _waves_midi_buffer.clear (); -} diff --git a/libs/backends/wavesaudio/waves_midiport.h b/libs/backends/wavesaudio/waves_midiport.h deleted file mode 100644 index 4445e896a9..0000000000 --- a/libs/backends/wavesaudio/waves_midiport.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2013 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __libardour_waves_midiport_h__ -#define __libardour_waves_midiport_h__ - -#include "waves_dataport.h" -#include "waves_midi_buffer.h" - -namespace ARDOUR { - -class WavesMidiEvent; -class WavesMidiDevice; -class WavesMidiEvent; - -class WavesMidiPort : public WavesDataPort { -public: - enum BufferSize { - // This value has nothing to do with reality as buffer of MIDI Port is not a flat array. - // It's an iterated list. - MAX_BUFFER_SIZE_BYTES = 8192 - }; - - WavesMidiPort (const std::string& port_name, PortFlags flags); - virtual ~WavesMidiPort (){}; - - virtual DataType type () const { return DataType::MIDI; }; - - virtual void* get_buffer (pframes_t nframes); - - inline WavesMidiBuffer& buffer () { return _waves_midi_buffer; } - inline const WavesMidiBuffer& const_buffer () const { return _waves_midi_buffer; } - - inline void set_midi_device (WavesMidiDevice* midi_device) { _midi_device = midi_device; }; - inline WavesMidiDevice* midi_device () const { return _midi_device; }; - -protected: - virtual void _wipe_buffer(); - -private: - WavesMidiDevice * _midi_device; - WavesMidiBuffer _waves_midi_buffer; -}; - -} // namespace - -#endif /* __libardour_waves_midiport_h__ */ - diff --git a/libs/backends/wavesaudio/wavesapi/BasicTypes/WCFourCC.h b/libs/backends/wavesaudio/wavesapi/BasicTypes/WCFourCC.h deleted file mode 100644 index 571a2341be..0000000000 --- a/libs/backends/wavesaudio/wavesapi/BasicTypes/WCFourCC.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __WCFourCC_h__ - #define __WCFourCC_h__ - -/* Copy to include -#include "BasicTypes/WCFourCC.h" -*/ - -//#include "BasicTypes/WTByteOrder.h" -#include "WCFixedString.h" - - -// These are preprocessor macros rather than inline functions because most compilers can't -// resolve functions at compile-time. -#if _BYTEORDER_BIG_ENDIAN==1 - #define FOURCC_BIG(a, b, c, d) ((uint32_t(a)<<24)|(uint32_t(b)<<16)|(uint32_t(c)<< 8)|(uint32_t(d)<< 0)) - #define FOURCC_LITTLE(a, b, c, d) ((uint32_t(a)<< 0)|(uint32_t(b)<< 8)|(uint32_t(c)<<16)|(uint32_t(d)<<24)) - #define FOURCC_COMPILER(a, b, c, d) FOURCC_BIG(a,b,c,d) -#elif _BYTEORDER_BIG_ENDIAN==0 - #define FOURCC_BIG(a, b, c, d) ((uint32_t(a)<< 0)|(uint32_t(b)<< 8)|(uint32_t(c)<<16)|(uint32_t(d)<<24)) - #define FOURCC_LITTLE(a, b, c, d) ((uint32_t(a)<<24)|(uint32_t(b)<<16)|(uint32_t(c)<< 8)|(uint32_t(d)<< 0)) - #define FOURCC_COMPILER(a, b, c, d) FOURCC_LITTLE(a,b,c,d) -#else - #error _BYTEORDER_BIG_ENDIAN not defined proparly -#endif // _BYTEORDER_HPP_BIG_ENDIAN - -typedef uint32_t WTFourCharCode; - -#ifndef kEnableWCFourCCDebug - #define kEnableWCFourCCDebug 0 // set to 1 to enable debug members -#endif - - -class WCFourCC -{ -private: - template - static WTFourCharCode stored_from_iter(_iter& i) - { - return s_stored_byte_order==wvNS::wvBO::byte_order_big_endian ? FOURCC_BIG(i[0], i[1], i[2], i[3]) : FOURCC_LITTLE(i[0], i[1], i[2], i[3]); - } - -public: - - // static const WCFourCC kDefaultFourCC_prv; - - static WCFourCC kDefaultFourCC_prv() { return WCFourCC(); } - - // change this line will change the byte order in which WCFourCC keeps the four char code - static const wvNS::wvBO::byte_order_type s_stored_byte_order = wvNS::wvBO::compiler_byte_order; - - WCFourCC(const char a, const char b, const char c, const char d) : - m_stored_value(s_stored_byte_order==wvNS::wvBO::compiler_byte_order ? FOURCC_BIG(a,b,c,d) : FOURCC_LITTLE(a,b,c,d)) - { -#if kEnableWCFourCCDebug == 1 - m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0'; -#endif - } - - WCFourCC() : - m_stored_value(FOURCC_BIG('?','?','?','?')) // since the four chars are the same, there is no need to choose between big & little - { -#if kEnableWCFourCCDebug == 1 - m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0'; -#endif - } - - WCFourCC(const WTFourCharCode in_fourCharCode, const wvNS::wvBO::byte_order_type in_byteOrder = wvNS::wvBO::compiler_byte_order) : - m_stored_value(in_byteOrder==s_stored_byte_order ? in_fourCharCode : wvNS::wvBO::swap32(in_fourCharCode)) - { -#if kEnableWCFourCCDebug == 1 - m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0'; -#endif - } - - explicit WCFourCC(const char* in_source_string) : - m_stored_value(stored_from_iter(in_source_string)) - { -#if kEnableWCFourCCDebug == 1 - m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0'; -#endif - } - - explicit WCFourCC(const WCFixedStringBase& in_source_string) : - m_stored_value(stored_from_iter(in_source_string)) - { -#if kEnableWCFourCCDebug == 1 - m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0'; -#endif - } - - WTFourCharCode GetAsSomeEndian(const wvNS::wvBO::byte_order_type in_byteOrder) const - { - return s_stored_byte_order==in_byteOrder ? m_stored_value : wvNS::wvBO::swap32(m_stored_value); - } - - WTFourCharCode GetAsBigEndian() const - { - return s_stored_byte_order==wvNS::wvBO::byte_order_big_endian ? m_stored_value : wvNS::wvBO::swap32(m_stored_value); - } - - WTFourCharCode GetAsLittleEndian() const - { - return s_stored_byte_order==wvNS::wvBO::byte_order_little_endian ? m_stored_value : wvNS::wvBO::swap32(m_stored_value); - } - - WTFourCharCode GetAsCompilerEndian() const - { - return s_stored_byte_order==wvNS::wvBO::compiler_byte_order ? m_stored_value : wvNS::wvBO::swap32(m_stored_value); - } - - WTFourCharCode GetAsStored() const - { - return m_stored_value; - } - - char operator[](const unsigned int in_character_index) const - { - return char(m_stored_value >> (8 * (s_stored_byte_order==wvNS::wvBO::compiler_byte_order ? 3-in_character_index : in_character_index))); - } - - char& operator[](const unsigned int in_character_index) - { - return reinterpret_cast(&m_stored_value)[s_stored_byte_order==wvNS::wvBO::byte_order_little_endian ? 3-in_character_index : in_character_index]; - } - - static size_t size() - { - return sizeof(WTFourCharCode); - } - - static size_t max_size() - { - return size(); - } - - static size_t capacity() - { - return size(); - } - - WCFixedString4 GetString() const - { - WCFixedString4 retVal; - retVal << operator[](0) << operator[](1) << operator[](2) << operator[](3); - - return retVal; - } - -#if kEnableWCFourCCDebug == 1 - const char* c_str() const - { - return m_c_str_stored_value; - } -#endif - -protected: - -private: -#if kEnableWCFourCCDebug == 1 - union - { -#endif - WTFourCharCode m_stored_value; -#if kEnableWCFourCCDebug == 1 - char m_c_str_stored_value[sizeof(WTFourCharCode)+1]; - }; -#endif - - WCFourCC& operator=(const WTFourCharCode); // we want initialization from literal to be dome through the constructor -}; - -inline bool operator<(const WCFourCC in_left, const WCFourCC in_right) -{ - return in_left.GetAsSomeEndian(WCFourCC::s_stored_byte_order) < in_right.GetAsSomeEndian(WCFourCC::s_stored_byte_order); -} -inline bool operator==(const WCFourCC in_left, const WCFourCC in_right) -{ - return in_left.GetAsSomeEndian(WCFourCC::s_stored_byte_order) == in_right.GetAsSomeEndian(WCFourCC::s_stored_byte_order); -} - -inline bool operator!=(const WCFourCC in_left, const WCFourCC in_right) -{ - return ! operator==(in_left, in_right); -} - - -#define kDefaultFourCC WCFourCC::kDefaultFourCC_prv() - -static const WCFourCC kZeroFourCC(0, wvNS::wvBO::compiler_byte_order); - -#endif //#if !defined(__WCFourCC_h__) - - - diff --git a/libs/backends/wavesaudio/wavesapi/BasicTypes/WTByteOrder.h b/libs/backends/wavesaudio/wavesapi/BasicTypes/WTByteOrder.h deleted file mode 100644 index c217fa7a1c..0000000000 --- a/libs/backends/wavesaudio/wavesapi/BasicTypes/WTByteOrder.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#if !defined(__WTByteOrder_h__) -#define __WTByteOrder_h__ - -/* Copy to include -#include "BasicTypes/WTByteOrder.h" -*/ - -#include "WavesPublicAPI/wstdint.h" -#include "BasicTypes/WUDefines.h" - -// Stuff concerning little/big endian and the conversion between them. -// most of the code here was copied from NetShell with some modifications -// Written by Udi on Nov-2005 -// Adjusted to Cross platform by Shai Mar-2006 - -// Macros to determine endian. __BIG_ENDIAN__ & __LITTLE_ENDIAN__ should come from the compiler. -// We try to set the macro _BYTEORDER_BIG_ENDIAN to 1 if big-endian or to 0 if little-endian. - -// if the compiler properly has set either __BIG_ENDIAN__ or __LITTLE_ENDIAN__ -#if defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__) -#if defined(__BIG_ENDIAN__) && defined(__LITTLE_ENDIAN__) //if both defined, check them as booleans -#if __BIG_ENDIAN__ && !__LITTLE_ENDIAN__ -#define _BYTEORDER_BIG_ENDIAN 1 -#elif !__BIG_ENDIAN__ && __LITTLE_ENDIAN__ -#define _BYTEORDER_BIG_ENDIAN 0 -#else -#error I am confused. Is this big-endian or little-endian? -#endif // stupid compiler defines both __LITTLE_ENDIAN__ and __BIG_ENDIAN__ -#elif defined(__BIG_ENDIAN__) -#define _BYTEORDER_BIG_ENDIAN 1 -#else -#define _BYTEORDER_BIG_ENDIAN 0 -#endif // big/little switch -#else // if the compiler proparly has NOT set either __BIG_ENDIAN__ or __LITTLE_ENDIAN__ -// http://msdn.microsoft.com/en-us/library/b0084kay.aspx for all preprocessor defs. _M_X64: 64 bit. _M_IA64: Itanium 64bit -#if defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(__INTEL__) || defined(__x86_64__) || defined(_M_X64) || defined(_M_IA64) -#define _BYTEORDER_BIG_ENDIAN 0 -#elif defined(_M_PPC) || defined(__POWERPC__ ) || defined(__ppc__) -#define _BYTEORDER_BIG_ENDIAN 1 -#else -#error Cannot detect compiler byte-order. Please add a test for your compiler appropriate symbol to this header file. -#endif // symbol search -#endif // standard preprocessor symbol found - -// code to determine which assembly code we can use -#if defined(_MSC_VER) && defined(_M_IX86) -#define _BYTEORDER_ASM_MSVC_I386 1 // Windows -#elif defined(__GNUC__) && defined(__i386__) -#define _BYTEORDER_ASM_GNUC_I386 1 // Linux, or MacOS with MacIntel on Xcode -#define _BYTEORDER_ASM_NONE 1 // Currently we have no assebley for GNU i386, so use the C version -#elif defined(__GNUC__) && defined(__POWERPC__) -#define _BYTEORDER_ASM_GNUC_PPC 1 // MacOS with PPC on Xcode -#define _BYTEORDER_ASM_NONE 1 // Currently we have no assebley for GNU PPC, so use the C version -#else -#define _BYTEORDER_ASM_NONE 1 // don't know the compiler and processor, use C implementation -#endif - -namespace wvNS { - -namespace wvBO // namespace Waves::ByteOrder -{ - typedef int byte_order_type; // we use int rather than enum because some compilers cannot resolve enum constants at compile-time. There are only two options anyway :-) - static const byte_order_type byte_order_little_endian = 0; - static const byte_order_type byte_order_big_endian = 1; - - - // We try to use this static const rather than preprocessor symbols in our code wherever possible. -#if _BYTEORDER_BIG_ENDIAN == 1 - static const byte_order_type compiler_byte_order = byte_order_big_endian; -#else - static const byte_order_type compiler_byte_order = byte_order_little_endian; -#endif - - - //--------------------------------------------------------------------------------- - // swap functions - best if implemented in inline assembly code - // The following are very slow swappers when compiled, do not use in loops -#if _BYTEORDER_ASM_MSVC_I386 - - // assembly implementation for Intel386 on Visual Studio - inline uint16_t swap16(uint16_t x) - { - __asm MOV AX,x; - __asm XCHG AL,AH; - __asm MOV x,AX; - return x; - } - - inline uint32_t swap32(uint32_t x) - { - __asm MOV EAX,x; - __asm BSWAP EAX; - __asm MOV x,EAX; - return x; - } - inline uint64_t swap64(uint64_t x) // TODO: To be replaced - { - return - ((x>>7*8)&0xFF)<<0*8 | ((x>>6*8)&0xFF)<<1*8 | ((x>>5*8)&0xFF)<<2*8 | ((x>>4*8)&0xFF)<<3*8 | - ((x>>3*8)&0xFF)<<4*8 | ((x>>2*8)&0xFF)<<5*8 | ((x>>1*8)&0xFF)<<6*8 | ((x>>0*8)&0xFF)<<7*8 ; - } - - /* the ASM code for swap64 does not compile - inline uint64_t swap64(uint64_t x) - { - __asm MOV EBX, OFFSET x; - __asm MOV EAX, [EBX]; - __asm MOV EDX, [EBX+4]; - __asm BSWAP EAX; - __asm BSWAP EDX; - __asm MOV [EBX],EDX; - __asm MOV [EBX+4],EAX; - return x; - } - */ -#endif // _BYTEORDER_ASM_MSVC_I386 - -#if _BYTEORDER_ASM_GNUC_I386 - // assembly implementation for Intel386 on GCC (Linux) - // TODO -#endif // _BYTEORDER_ASM_GNUC_I386 - -#if _BYTEORDER_ASM_GNUC_PPC - // assembly implementation for PowerPC on GCC (XCode) - // TODO -#endif // _BYTEORDER_ASM_GNUC_PPC - -#if _BYTEORDER_ASM_NONE - inline uint16_t swap16(uint16_t x) { return (x>>8) | ((x&0xFF)<<8); } - inline uint32_t swap32(uint32_t x) { return (x&0xFF)<<24 | (x&0xFF00)<<8 | (x&0xFF0000)>>8 | (x&0xFF000000)>>24; } - inline uint64_t swap64(uint64_t x) - { - return - ((x>>7*8)&0xFF)<<0*8 | ((x>>6*8)&0xFF)<<1*8 | ((x>>5*8)&0xFF)<<2*8 | ((x>>4*8)&0xFF)<<3*8 | - ((x>>3*8)&0xFF)<<4*8 | ((x>>2*8)&0xFF)<<5*8 | ((x>>1*8)&0xFF)<<6*8 | ((x>>0*8)&0xFF)<<7*8 ; - } -#endif // _BYTEORDER_ASM_NONE - - - - - //--------------------------------------------------------------------------------- - - // order conversion functions - // may want to overload for float and double as well. - // overload for signed ints is ambiguous and should be done only if no other choice exists. - // - - - - - - - - - - - - - - - - - - - - - inline uint16_t compiler_to_big_16(uint16_t x) - { - return compiler_byte_order==byte_order_big_endian ? x : swap16(x); - } - inline uint16_t big_to_compiler_16(uint16_t x) - { - return compiler_byte_order==byte_order_big_endian ? x : swap16(x); - } - inline uint16_t compiler_to_little_16(uint16_t x) - { - return compiler_byte_order==byte_order_little_endian ? x : swap16(x); - } - inline uint16_t little_to_compiler_16(uint16_t x) - { - return compiler_byte_order==byte_order_little_endian ? x : swap16(x); - } - // - - - - - - - - - - - - - - - - - - - - - inline uint32_t compiler_to_big_32(uint32_t x) - { - return compiler_byte_order==byte_order_big_endian ? x : swap32(x); - } - inline uint32_t big_to_compiler_32(uint32_t x) - { - return compiler_byte_order==byte_order_big_endian ? x : swap32(x); - } - inline uint32_t compiler_to_little_32(uint32_t x) - { - return compiler_byte_order==byte_order_little_endian ? x : swap32(x); - } - inline uint32_t little_to_compiler_32(uint32_t x) - { - return compiler_byte_order==byte_order_little_endian ? x : swap32(x); - } - // - - - - - - - - - - - - - - - - - - - - - inline uint64_t compiler_to_big_64(uint64_t x) - { - return compiler_byte_order==byte_order_big_endian ? x : swap64(x); - } - inline uint64_t big_to_compiler_64(uint64_t x) - { - return compiler_byte_order==byte_order_big_endian ? x : swap64(x); - } - inline uint64_t compiler_to_little_64(uint64_t x) - { - return compiler_byte_order==byte_order_little_endian ? x : swap64(x); - } - inline uint64_t little_to_compiler_64(uint64_t x) - { - return compiler_byte_order==byte_order_little_endian ? x : swap64(x); - } - -} // namespace wvBO - -} // namespace wvNS { - -#endif // #if !defined(__WTByteOrder_h__) - diff --git a/libs/backends/wavesaudio/wavesapi/BasicTypes/WUComPtr.h b/libs/backends/wavesaudio/wavesapi/BasicTypes/WUComPtr.h deleted file mode 100644 index e8e633d927..0000000000 --- a/libs/backends/wavesaudio/wavesapi/BasicTypes/WUComPtr.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __WUComPtr_h__ -#define __WUComPtr_h__ - -/* Copy to include -#include "BasicTypes/WUComPtr.h" -*/ - -#include "WavesPublicAPI/wstdint.h" - -typedef int32_t wvComPtr[2]; - -// ConvertDPtr has the exact format of a vfp callback function, but it is a local function, native only. -// It converts a pointer in either 32 bits or 64 bits to a place-holder of 64 bits in coefs/states/external memory. -// pData is expected to point to a pre-allocate space enough for storing a pointer (posibly two single-precision coefs). -// Since pointers are not transferable between hardwares, at preset time no need for a shell callback. -// We keep this as a cALGORITHM for compatibility with the rest of the convert functions -//================================================================================ -inline uint32_t vfpConvertDPtr(const void* InPointer, void* pData) -//================================================================================ -{ - uint64_t *pL = (uint64_t *)pData; - *pL = (uint64_t)InPointer; - return (uint32_t)sizeof(uint64_t); -} - - -/* -{ - // data in that struct must be the same type of the Coefs/States type! - int32_t LSW; // Least significant word - int32_t MSW; // Most significant word -}; - -inline wvComPtr PackToComPtr(const intptr_t in_PtrToPack) -// take ptr that hosted in intptr_t type -// and pack it to wvComPtr container type (MSW and LSW of 32bit each) -{ - wvComPtr retVal; - int64_t t_PtrToPack = static_cast(in_PtrToPack); - // This packing is xPlatform coding for x32 and x64 - // #ifdef for x64 - intptr_t is 64 bit - retVal.LSW = static_cast(t_PtrToPack & intptr_t(0xFFFFFFFF)); - retVal.MSW = (static_cast(t_PtrToPack>>32)); - - // #ifdef for x32 - intptr_t is 32 bit -// retVal.LSW = int32_t(in_PtrToPack); -// retVal.MSW = 0; - - return retVal; -} - -inline intptr_t UnpackComPtr( const wvComPtr in_ComPtrToUnpack) -// take wvComPtr with MSW and LSW of 32bit each -// and unpack it to intptr_t type -{ - intptr_t retVal; - - // This unpacking is xPlatform coding for x32 and x64 - // #ifdef for x64 - intptr_t is 64 bit so use intptr_t instead of int64_t - int64_t PtrAt64 = static_cast(in_ComPtrToUnpack.MSW); - PtrAt64 <<= 32; - PtrAt64 |= static_cast(in_ComPtrToUnpack.LSW); - retVal = static_cast(PtrAt64); - - - // #ifdef for x32 - intptr_t is 32 bit -// retVal = static_cast(retVal.LSW); - - return retVal; -} - - -////////////////////////////////////////////////////////////////////////// -inline uint32_t ComPtr_to_DSP( const intptr_t PtrToConvert, char* pDataStruct ) -{ - - *(reinterpret_cast(pDataStruct)) = PackToComPtr(PtrToConvert); - - return uint32_t(sizeof(wvComPtr)); -} -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -inline uint32_t DSP_to_ComPtr( const char* pDataStruct, intptr_t *ThePtr) -// pDataStruct is pointing to wvComPtr in the Coefs/States -// the function reconstruct the pointer into ThePtr -{ - - *ThePtr = UnpackComPtr(*(reinterpret_cast(pDataStruct))); - - return uint32_t(sizeof(wvComPtr)); -} -////////////////////////////////////////////////////////////////////////// -*/ - -#endif //#if !defined(__WUComPtr_h__) - - - diff --git a/libs/backends/wavesaudio/wavesapi/BasicTypes/WUDefines.h b/libs/backends/wavesaudio/wavesapi/BasicTypes/WUDefines.h deleted file mode 100644 index 293f3bd247..0000000000 --- a/libs/backends/wavesaudio/wavesapi/BasicTypes/WUDefines.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __WUDefines_h__ - #define __WUDefines_h__ - -/*Copy to include -#include "BasicTypes/WUDefines.h" -*/ - -#include "1.0/WavesPublicAPI_Defines.h" - -// When changing wvNS value also do the same change in Objective_C_MangledNames.h -// because CWSAUCocoaViewFactoryAsString is hard coded there -#define wvNS wvWavesV9_3 -#ifdef __APPLE__ - #define ObjCNameSpace(__className__) wvWavesV9_3_ ## __className__ -#endif - -#ifdef INSIDE_NETSHELL - #define DllExport -#else - #define DllExport WPAPI_DllExport -#endif - -#define __CDECL __WPAPI_CDECL -#define __STDCALL __WPAPI_STDCALL - - -#ifndef NULL - #define NULL (0) -#endif - -#ifndef nil - #define nil NULL -#endif - -#define PASCAL_MAC_ONLY #error do not use PASCAL_MAC_ONLY. See defintions in WavesFTT.h for replacment. -#define CALLCON #error do not use CALLCON. See defintions in WavesFTT.h for replacment. -#define FUNCEXP #error do not use FUNCEXP. See defintions in WavesFTT.h for replacment. - -#define WUNUSED_PARAM(__SOME_UNUSED_PARAM__) ((void)__SOME_UNUSED_PARAM__) - -#ifdef __APPLE__ - const char* const OS_NAME = "Mac"; - - #define WIN_ONLY(__Something_only_for_windows__) - #define MAC_ONLY(__Something_only_for_mac__) __Something_only_for_mac__ - - #if defined(i386) || defined(__i386) || defined(__i386__) - #define kNumArchBits 32 - #endif - #if defined(__x86_64) || defined(__x86_64__) - #define kNumArchBits 64 - #endif - - #if (__i386 || __x86_64) && !defined(__LITTLE_ENDIAN__) - #define __LITTLE_ENDIAN__ - #endif - #if !(__i386 || __x86_64) && !defined(__BIG_ENDIAN__) - #define __BIG_ENDIAN__ - #endif - #ifdef __GNUC__ - #define STD_EXCEPT_WIN std - #define FAR - #define PASCAL - // #define HINSTANCE void* - #define WINAPI - - #else - - #define DllExport_WinOnly - #define STD_EXCEPT_WIN std - #define FAR - #define PASCAL // windows' pascal - #define HINSTANCE void* - #define WINAPI - - #endif - #define THROW_SPEC(THROW_OBJ) throw (THROW_OBJ) - - #define WUNUSED_PARAM_ON_MAC(__SOME_UNUSED_PARAM__) WUNUSED_PARAM(__SOME_UNUSED_PARAM__) - #define WUNUSED_PARAM_ON_WIN(__SOME_UNUSED_PARAM__) -#endif - - -#ifdef PLATFORM_WINDOWS - const char* const OS_NAME = "Win"; - - #define WIN_ONLY(__Something_only_for_windows__) __Something_only_for_windows__ - #define MAC_ONLY(__Something_only_for_mac__) - - #if defined(_M_X64) - #define kNumArchBits 64 - #else // not sure what are the VisualStudio macros for 32 bits - #define kNumArchBits 32 - #endif - - #define DllExport_WinOnly DllExport // help solve window specific link errors - #define STD_EXCEPT_WIN - - #if !defined(__MINGW64__) - #define round(x) (floor(x+0.5)) - #endif - - #define __LITTLE_ENDIAN__ - #define THROW_SPEC(THROW_OBJ) throw (...) - - #define WUNUSED_PARAM_ON_MAC(__SOME_UNUSED_PARAM__) - #define WUNUSED_PARAM_ON_WIN(__SOME_UNUSED_PARAM__) WUNUSED_PARAM(__SOME_UNUSED_PARAM__) - -#endif - -#ifdef __linux__ - const char* const OS_NAME = "Linux"; - - #define WIN_ONLY(__Something_only_for_windows__) - #define MAC_ONLY(__Something_only_for_mac__) - - #define DllExport_WinOnly - #define STD_EXCEPT_WIN std - #define FAR - #define PASCAL - // #define HINSTANCE void* - #define WINAPI - #if __i386 && !defined(__LITTLE_ENDIAN__) - #define __LITTLE_ENDIAN__ - #endif - #if !__i386 && !defined(__BIG_ENDIAN__) - #define __BIG_ENDIAN__ - #endif - #define THROW_SPEC(THROW_OBJ) throw (THROW_OBJ) - - #if defined(__x86_64) || defined(__LP64__) - #error "64 bit not suported yet on linux" - #else - #define kNumArchBits 32 - #endif -#endif - -#ifndef _WU_DECL - #define _WU_DECL __CDECL // the default is calling model is cdecl, but you can also set this macro from the outside to something different -#endif - -#ifndef _XML_DECL - #define _XML_DECL __CDECL // the default is calling model is cdecl, but you can also set this macro from the outside to something different -#endif - -#ifndef kNumArchBits - #error Macro kNumArchBits was not defined -#endif - -#if kNumArchBits == 64 - const char* const kNumArchBits_c_str = "64"; -#endif -#if kNumArchBits == 32 - const char* const kNumArchBits_c_str = "32"; -#endif - -#endif //__WUDefines_h__ diff --git a/libs/backends/wavesaudio/wavesapi/BasicTypes/WUMathConsts.h b/libs/backends/wavesaudio/wavesapi/BasicTypes/WUMathConsts.h deleted file mode 100644 index 6ee16c2ad6..0000000000 --- a/libs/backends/wavesaudio/wavesapi/BasicTypes/WUMathConsts.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __WUMathConsts_h__ - #define __WUMathConsts_h__ - -/* Copy to include: -#include "BasicTypes/WUMathConsts.h" -*/ - -const float kfPI = 3.1415926535898f; // PI, single precision -const double kdPI = 3.1415926535897932384626433832795; // PI, double precision - -const float kf2PI = 6.2831853071796f; // 2*PI -const double kd2PI = 6.283185307179586476925286766559; // 2*PI - -const float kfhalfPI = 1.5707963267949f; // 0.5*PI -const double kdhalfPI = 1.57079632679489661923; // 0.5*PI - -const double kdLn2 = 0.69314718055994530942; // natural log(2.0) -const double kdOneOverLn2 = 1.4426950408889634073599246810019; // natural (1.0/log(2.0)) - for multiply log() to get it as with base 2 - -const double kdLog2 = 0.301029995663981; // log10(2.0) -const double kdOneOverLog2 = 3.321928094887363; // (1.0/log10(2.0)) - for multiply log() to get it as with base 2 - -const double kdExponent = 2.718281828459045235360287471352; // e - -const double kdSqrt2 = 1.41421356237309504880; // sqrt(2) - - - -#endif //__WUMathConsts_h__ diff --git a/libs/backends/wavesaudio/wavesapi/BasicTypes/WUTypes.h b/libs/backends/wavesaudio/wavesapi/BasicTypes/WUTypes.h deleted file mode 100644 index 8c6ac71cfc..0000000000 --- a/libs/backends/wavesaudio/wavesapi/BasicTypes/WUTypes.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __WUTypes_h__ - #define __WUTypes_h__ - -/* Copy to include: -#include "BasicTypes/WUTypes.h" -*/ - -#include "WavesPublicAPI/WTErr.h" -#include "WavesPublicAPI/wstdint.h" -#include "BasicTypes/WUDefines.h" -#include "BasicTypes/WCFourCC.h" // declares WTFourCharCode & WCFourCC -#include "BasicTypes/WUComPtr.h" // Communication Ptr for x64 compatibility -#include "WCFixedString.h" -#include -#include -/******************************************************************************** - Atoms -*********************************************************************************/ - -#define WTSInt64 "WTSInt64 is obsolete, please use int64_t instead"; -#define WTUInt64 "WTUInt64 is obsolete, please use uint64_t instead"; -#define WTSInt32 "WTSInt32 is obsolete, please use int32_t instead"; -#define WTUInt32 "WTUInt32 is obsolete, please use uint32_t instead"; -#define WTSInt16 "WTSInt16 is obsolete, please use int16_t instead"; -#define WTUInt16 "WTUInt16 is obsolete, please use uint16_t instead"; -#define WTSInt8 "WTSInt8 is obsolete, please use int8_t instead"; -#define WTUInt8 "WTUInt8 is obsolete, please use uint8_t instead"; -#define WTFloat32 "WTFloat32 is obsolete, please use float instead"; -#define WTByte "WTByte is obsolete, please use uint8_t instead"; - -/******************************************************************************** - Consts -*********************************************************************************/ -//#define PI 3.1415926535897 // ... Was moved to WUMathConsts.h under the name kPI -const uint32_t kDefaultCircleSlices = 100; - - -/******************************************************************************** - Utilities -*********************************************************************************/ - -// SCOPED_ENUM is a macro that defines an enum inside a class with a given name, thus declaring the enum values -// inside a named scope. This allows declaring: -// SCOPED_ENUM(SomeType) -// { -// Val1, -// Val2, -// Val3 -// } -// SCOPED_ENUM_END -// And then you can reference SomeType::Val1, SomeType::Val2, SomeType::Val3 for the various values, unlike -// a regular enum on which Val1, Val2 and Val3 would become global names. -// Additionally, you get SomeType::Type to specify the type of the whole enum in case you want to transfer it to -// a function. -// Don't forget to close the enum with SCOPED_ENUM_END, otherwise you'll get bogus compilation errors. -// This requirement can probably be removed some day, but it will make the SCOPED_ENUM macro much less readable... -#define SCOPED_ENUM(name) \ -class name \ -{ \ -public: enum Type - -#define SCOPED_ENUM_END ;}; - - -//******************************************************************************** -// Files - -//! file (and resource container) opening permissions -// Note: When opening with eFMWriteOnly on existing file, writing to the file will append, not overwrite, Shai, 9/8/2007. -enum WEPermitions{ eFMReadOnly, eFMWriteOnly, eFMReadWrite}; - -// File cursor positions -enum WEPositionMode{eFMFileBegin, eFMFileCurrent, eFMFileEnd}; - -// File creation types -enum WECreateFlags { - eFMCreateFile_DontOverrideIfAlreadyExists, // Create a new file , If the file exists leaves the existing data intact - eFMCreateFile_FailIfAlreadyExists, // Attempt to create a new file, if file already exists - fail. - eFMCreateFile_OverrideIfAlreadyExists // Create a new file , If the file exists, overwrite the file and clear the existing data -}; - - -enum WEFoldersDomain{ - eSystemDomain, - eLocalDomain, - eUserDomain, - - eNumberOfFoldersDomains -}; -enum WEArchBits{ - e32Bits, - e64Bits, - eNumberOfArchBits -}; - -enum WESystemFolders{ - eSystemFolder, - eDesktopFolder, - ePreferencesFolder, - eWavesPreferencesFolder, //deprecated use eWavesPreferencesFolder2 - eTemporaryFolder, - eTrashFolder, - eCurrentFolder, - eRootFolder, - eLibrariesFolder, - eAudioComponentsFolder, // MacOS only - eCacheFolder, - eWavesCacheFolder, - eAppDataFolder, - eWavesAppDataFolder, - eSharedUserDataFolder, - eWavesSharedUserDataFolder, - eWavesScanViewFolder, - - eWavesPreferencesFolder2, // Mac: "/Users/username/Library/Preferences/Waves Audio" - // Win: "C:\Users\username\AppData\Roaming\Waves Audio\Preferences" - - eNumberOfSystemFolders -}; - -//******************************************************************************** -// Process - -#ifdef __APPLE__ - typedef uint32_t WTProcessID; // actually pid_t which is __darwin_pid_t which is __uint32_t -#endif -#ifdef PLATFORM_WINDOWS - typedef int WTProcessID; -#endif -#ifdef __linux__ - typedef uint32_t WTProcessID; -#endif - -enum WEManagerInitOptions -{ - eUnknown_ManagerInitOption, - eMacOS_Carbon_Runtime, - eMacOS_Cocoa_Runtime, - eLinuxOS_gtk_Runtime, - eLinuxOS_X_Runtime, - eWindowsOS_GoodOld_Runtime, // good old windows API - eWindowsOS_DotNET_Runtime, - eVerticalFliped_Graphics, - eInit_RM, - eInit_GMConfig, - eInit_PVM, - eInit_UM, - eInit_BKG -}; -#ifdef __APPLE__ - #if __LP64__ || NS_BUILD_32_LIKE_64 // in 64bit (or when NS_BUILD_32_LIKE_64 is specified) we decline Carbon implementation. - const WEManagerInitOptions eDefaultRuntime = eMacOS_Cocoa_Runtime; - #else - const WEManagerInitOptions eDefaultRuntime = eMacOS_Carbon_Runtime; - #endif -#endif -#ifdef PLATFORM_WINDOWS - const WEManagerInitOptions eDefaultRuntime = eWindowsOS_GoodOld_Runtime; -#endif -#ifdef __linux__ - const WEManagerInitOptions eDefaultRuntime = eLinuxOS_gtk_Runtime; -#endif - - -//******************************************************************************** -// Files - -const uint32_t kMaxPathLength = 1023; // maximum length of a path -const uint32_t kMaxFileNameLength = 255; // maximum length of a file name including extension -typedef WCFixedString WTPathString; -typedef WCFixedString WTFileNameString; - -typedef uint64_t WTFileSize; -const WTFileSize kIllegalFileSize = (WTFileSize)-1; - -typedef off_t WTFileOffset; - -typedef std::time_t WTFileTime; -const WTFileTime kIllegalFileTime = (WTFileTime)-1; - -typedef struct WTPathType* WTPathRef; // represents a path, path need not exists -typedef struct WTOpenFileType* WTOpenFileRef; // represents a real, open file -typedef struct WTNativeDLLRefType* WTNativeDLLRef; // define WTNativeDLLRef as a unique type CFBundleRef on Mac, HINSTANCE on Windows -const WTNativeDLLRef kIllegalNativeDLLRef = 0; -//******************************************************************************** -// Resources - -const size_t kMaxResTypeLength = 31; -typedef WCFixedString31 WTResType; -typedef short WTResID; -const WTResID kIllegalResID = -1; - - -typedef struct WTResContainerType* WTResContainerRef; -typedef struct WTResourceType* WTResRef; -const WTResContainerRef kIllegalContainerRef = 0; -const WTResRef kIllegalResourceRef = 0; - -#ifdef __APPLE__ - typedef struct WTNativeResourceType* WTNativeResourceRef; // for use when need to have access to the native resource without going though resource manager caching anf conversion. - const WTNativeResourceRef kIllegalNativeResourceRef = 0; -#endif -#ifdef PLATFORM_WINDOWS - typedef struct WTNativeResourceType* WTNativeResourceRef; //HGLOBAL // for use when need to have access to the native resource without going though resource manager caching anf conversion. - const WTNativeResourceRef kIllegalNativeResourceRef = 0; -#endif -#ifdef __linux__ -typedef void* WTNativeResourceRef; // WTOpenFileRef // for use when need to have access to the native resource without going though resource manager caching anf conversion. - const WTNativeResourceRef kIllegalNativeResourceRef = 0; -#endif - -//******************************************************************************** -// OpenGL - -typedef struct WCOGLContext* WCOGLContextRef; -typedef struct WCOGLTexture* WCOGLTextureRef; -typedef struct WSPluginView* WCPluginViewRef; -typedef struct WSMenu* WCMenuRef; -typedef struct WCPluginNativeView* WCPluginNativeViewRef; - -const WCOGLContextRef kIllegalOGLContextRef = 0; -const WCOGLTextureRef kIllegalOGLTextureRef = 0; -const WCPluginViewRef kIllegalPluginViewRef = 0; -const WCMenuRef kIllegalWCMenuRef = 0; - -const intptr_t kIllegalTexturesMaster = -1; - - -typedef unsigned int WTTextureRef; -const WTTextureRef kIllegalTextureRef = 0; - -// type for storing pointer to functions. Used to avoid warning such as "C++ forbids conversion between pointer to function and pointer to object" -typedef void (*DUMMY_FUNC_PTR)(void); - -// type for a generic callback function with one parameter -typedef intptr_t (*CALLBACK_1_PARAM_FUNC_PTR)(intptr_t); - -////////////////////////////////////////////////////////////// -// Timer -typedef intptr_t WTTimerRef; -const WTTimerRef kIllegalTimerRef = 0; -typedef void (*WTTimerCallback)(intptr_t); - -// generic type for OS native pointer -typedef void* WTPtr; - -#endif //__WUTypes_h__ diff --git a/libs/backends/wavesaudio/wavesapi/MiscUtils/MinMaxUtilities.h b/libs/backends/wavesaudio/wavesapi/MiscUtils/MinMaxUtilities.h deleted file mode 100644 index 4260f680a5..0000000000 --- a/libs/backends/wavesaudio/wavesapi/MiscUtils/MinMaxUtilities.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __MinMaxUtilities_h__ -#define __MinMaxUtilities_h__ - -/* copy to include -#include "MiscUtils/MinMaxUtilities.h" -*/ - -#include "BasicTypes/WUDefines.h" -#include "BasicTypes/WUMathConsts.h" -#include "WavesPublicAPI/wstdint.h" - -#ifdef __GNUC__ -#undef round -#endif - -// New accelerated templates -#if defined ( __cplusplus ) && !defined (__WUMinMax) -#define __WUMinMax // Also defined in Nativepr.h - - -template inline T WUMin(const T &a, const T &b) {return (a < b) ? a : b;} // requires only < to be defined for T -template inline T WUMax(const T &a,const T &b) {return (a < b) ? b : a;} // requires only < to be defined for T -template inline T WUMinMax(const T &Smallest, const T &Biggest, const T &Val) // requires only < to be defined for T -{ - return ((Val < Smallest) ? Smallest : ((Biggest < Val) ? Biggest : Val)); -} -/* -// Min and Max - template inline T WUMin(T a,T b) {return (a < b) ? a : b;} // requires only < to be defined for T - template inline T WUMax(T a,T b) {return (a < b) ? b : a;} // requires only < to be defined for T - template inline T WUMinMax(T SMALLEST, T BIGGEST, T X) // requires only < to be defined for T - { - return ((X < SMALLEST) ? SMALLEST : ((BIGGEST < X) ? BIGGEST : X)); - } - */ -// Absolute value - -#ifdef PLATFORM_WINDOWS - #include - -#ifndef __GNUC__ -#define __abs(x) abs(x) -#define __labs(x) labs(x) -#define __fabs(x) fabs(x) -#endif - -#endif - -#ifdef __GNUC__ - #include // why don't know makes it work need to check - #include - #include - -#define __abs(x) std::abs(x) -#define __labs(x) std::labs(x) -#define __fabs(x) std::fabs(x) -#endif - #ifdef __APPLE__ - #ifdef __GNUC__ - #include // why don't know makes it work need to check - #include -#define __abs(x) std::abs(x) -#define __labs(x) std::labs(x) -#define __fabs(x) std::fabs(x) - #endif - #endif - -// log2: on Windows there's no proper definition for log2, whereas on other platform there is. - #ifndef WUlog2 - #if defined(PLATFORM_WINDOWS) - #define WUlog2(x) (kdOneOverLog2 * log10((x))) - #else - #define WUlog2(x) log2(x) - #endif - #endif - -template inline T WUAbs(const T &xA) -{ - return (xA > T(0))? xA: -xA; -} - -template <> inline int WUAbs(const int &xA) -{ - return __abs(xA); -} - -//template <> inline int32_t WUAbs(const int32_t &xA)// 64BitConversion -//{ -// return __labs(xA); -//} - -template <> inline float WUAbs(const float &xA) -{ - return (float) __fabs(xA); -} - -template <> inline double WUAbs(const double &xA) -{ - return __fabs(xA); -} - -#endif - -int32_t DllExport WURand(intptr_t in_Seed); -int32_t DllExport WURand(); -int32_t DllExport rand_gen_formula(int32_t rndSeed); - -template inline bool WUIsEqualWithTolerance(const T &xA, const T &xB, const T &xTolerance) -{ - return (WUAbs(xA - xB) < xTolerance) ? true : false; -} - - -#endif diff --git a/libs/backends/wavesaudio/wavesapi/MiscUtils/UMicroseconds.cpp b/libs/backends/wavesaudio/wavesapi/MiscUtils/UMicroseconds.cpp deleted file mode 100644 index c51d1910b0..0000000000 --- a/libs/backends/wavesaudio/wavesapi/MiscUtils/UMicroseconds.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifdef PLATFORM_WINDOWS - #include "IncludeWindows.h" -#endif -#if defined(__linux__) || defined(__APPLE__) - #include -#endif - -#include "UMicroseconds.h" - -namespace wvNS { -UMicroseconds& UMicroseconds::ReadTime() -{ - // Note: g_get_monotonic_time() may be a viable alternative - // (it is on Linux and OSX); if not, this code should really go into libpbd -#ifdef PLATFORM_WINDOWS - LARGE_INTEGER Frequency, Count ; - - QueryPerformanceFrequency(&Frequency) ; - QueryPerformanceCounter(&Count); - theTime = uint64_t((Count.QuadPart * 1000000.0 / Frequency.QuadPart)); - -#elif defined __MACH__ // OSX, BSD.. - - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - theTime = (uint64_t)mts.tv_sec * 1e6 + (uint64_t)mts.tv_nsec / 1000; - -#else // Linux, POSIX - - struct timespec *ts - clock_gettime(CLOCK_MONOTONIC, ts); - theTime = (uint64_t)ts.tv_sec * 1e6 + (uint64_t)buf.tv_nsec / 1000; - -#endif - - return *this; -} -/* - Removed in favor of the posix implementation. -#ifdef __APPLE__ - uint32_t UMicroseconds::hi() {return reinterpret_cast(&theTime)->hi;} - uint32_t UMicroseconds::lo() {return reinterpret_cast(&theTime)->lo;} -#endif -*/ -void UMicrosecondsAccumulator::Start() -{ - m_start_time.ReadTime(); -} - -void UMicrosecondsAccumulator::Stop() -{ - UMicroseconds stop_time; - - m_accumulator += stop_time.GetNativeTime() - m_start_time.GetNativeTime(); -} - -void UMicrosecondsAccumulator::Clear() -{ - m_start_time = 0; - m_accumulator = 0; -} - -UMicroseconds UMicrosecondsAccumulator::GetAccumulatedTime() const -{ - return m_accumulator; -} - -UMicrosecondsAccumulator& UMicrosecondsAccumulator::operator+=(const UMicrosecondsAccumulator& inaccum_to_add) -{ - m_accumulator += inaccum_to_add.GetAccumulatedTime(); - return *this; -} - -} // namespace wvNS { diff --git a/libs/backends/wavesaudio/wavesapi/MiscUtils/UMicroseconds.h b/libs/backends/wavesaudio/wavesapi/MiscUtils/UMicroseconds.h deleted file mode 100644 index af1eb8e37f..0000000000 --- a/libs/backends/wavesaudio/wavesapi/MiscUtils/UMicroseconds.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __UMicroseconds_h__ - #define __UMicroseconds_h__ - -/* Copy to include -#include "UMicroseconds.h" -*/ - - - -#include "BasicTypes/WUDefines.h" -#include "BasicTypes/WUTypes.h" - -namespace wvNS { -// a wraper for Microseconds function from Timer.h -class DllExport UMicroseconds -{ -public: - -#ifdef PLATFORM_WINDOWS - typedef int64_t TimeKeeper; -#endif -#ifdef __APPLE__ - typedef uint64_t TimeKeeper; -#endif -#ifdef __linux__ - typedef uint64_t TimeKeeper; -#endif - -private: - TimeKeeper theTime; - -public: - - UMicroseconds() - { - ReadTime(); - } - - UMicroseconds(const TimeKeeper in_initVal) : theTime(in_initVal) {} - - UMicroseconds(const UMicroseconds& inUM) : theTime(inUM.theTime) {} - UMicroseconds& operator=(const UMicroseconds& inUM) {theTime = inUM.theTime; return *this;} - UMicroseconds& operator+=(const TimeKeeper in_timeToAdd) {theTime += in_timeToAdd; return *this;} - - UMicroseconds& ReadTime(); - - TimeKeeper GetNativeTime() const {return theTime;} - operator uint64_t () {return static_cast(theTime);} - operator double () const {return static_cast(theTime);} - - double Seconds() const {return static_cast(theTime) / double(1000000);} - double MilliSeconds() const {return static_cast(theTime) / double(1000);} - double MicroSeconds() const {return static_cast(theTime);} - -#ifdef __APPLE__ - uint32_t hi(); - uint32_t lo(); -#endif -}; - -inline UMicroseconds operator-(const UMicroseconds& in_one, const UMicroseconds& in_two) -{ - UMicroseconds retVal(in_one.GetNativeTime() - in_two.GetNativeTime()); - return retVal; -} - -class UMicrosecondsAccumulator -{ -public: - UMicrosecondsAccumulator() : m_start_time(0), m_accumulator(0) {} - - void Start(); - void Stop(); - void Clear(); - - UMicroseconds GetAccumulatedTime() const; - - UMicrosecondsAccumulator& operator+=(const UMicrosecondsAccumulator&); - -protected: - UMicroseconds m_start_time; - UMicroseconds m_accumulator; -}; - -inline UMicroseconds operator-(const UMicrosecondsAccumulator& in_one, const UMicrosecondsAccumulator& in_two) -{ - UMicroseconds retVal(in_one.GetAccumulatedTime() - in_two.GetAccumulatedTime()); - return retVal; -} - -//=========================================================================================// -inline void MicrosecondDelay(double amt) -//=========================================================================================// -{ - UMicroseconds than; - UMicroseconds now; - - do - { - now.ReadTime(); - } while ((now.MicroSeconds() - than.MicroSeconds()) < amt); -} - -} // namespace wvNS { -#endif //#ifndef __UMicroseconds_h__ diff --git a/libs/backends/wavesaudio/wavesapi/MiscUtils/WCFixedString.h b/libs/backends/wavesaudio/wavesapi/MiscUtils/WCFixedString.h deleted file mode 100644 index d127e0116a..0000000000 --- a/libs/backends/wavesaudio/wavesapi/MiscUtils/WCFixedString.h +++ /dev/null @@ -1,904 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __WCFixedString_h__ - #define __WCFixedString_h__ - -/* Copy to include. -#include "WCFixedString.h" -*/ -// do not #include anything else here but standard C++ library files, this file should be free from any and all depandencies -// do not put any DEBUG_s or TRACE_s in this file, since it is used in BgkConsole functions - -#include -#include -#include -#include - -#ifdef __APPLE__ -#include -#endif - -#include "BasicTypes/WUDefines.h" -#include "BasicTypes/WTByteOrder.h" -#include "WavesPublicAPI/wstdint.h" -#include "MiscUtils/MinMaxUtilities.h" - -// use this macro instead of std :: string to mark the that use of std :: string could not be replaced -// by WFixedString. -#define std_string_approved std::string - -#ifdef __POSIX__ -const char* const kStrNewLine = "\n"; -#endif -#ifdef PLATFORM_WINDOWS -const char* const kStrNewLine = "\r\n"; -#endif - -class DllExport WCFixedStringBase -{ -public: - typedef size_t pos_t; - typedef intptr_t spos_t; // signed position, defined to intptr_t because Windows does not have ssize_t - static const pos_t npos = UINTPTR_MAX; // Same as size_max - - WCFixedStringBase(char* const in_begin, const size_t in_MaxFixedStringLength) : - m_begin(in_begin), - m_MaxFixedStringLength(in_MaxFixedStringLength), - m_end(in_begin) - { - *m_end = '\0'; - } - - inline WCFixedStringBase& operator=(const WCFixedStringBase& in_fixedStrToAssign) - { - if (this != &in_fixedStrToAssign) - { - clear(); - operator<<(in_fixedStrToAssign); - } - - return *this; - } - - inline WCFixedStringBase& operator=(const char* in_CStrToAssign) - { - clear(); - operator<<(in_CStrToAssign); - - return *this; - } - - inline WCFixedStringBase& operator=(const char in_charToAssign) - { - clear(); - operator<<(in_charToAssign); - - return *this; - } - - char operator[](const pos_t in_index) const - { - if (in_index < m_MaxFixedStringLength) - return m_begin[in_index]; - else - return m_begin[m_MaxFixedStringLength]; // in_index was too big - } - - char& operator[](const pos_t in_index) - { - if (in_index < m_MaxFixedStringLength) - return m_begin[in_index]; - else - return m_begin[m_MaxFixedStringLength]; // in_index was too big - } - - inline size_t resize(const size_t in_newSize) - { - m_end = m_begin + WUMin(in_newSize, m_MaxFixedStringLength); - *m_end = '\0'; - return size(); - } - - size_t max_size() - { - return m_MaxFixedStringLength; - } - - size_t capacity() - { - return m_MaxFixedStringLength; - } - - - inline char * peek() - { - return m_begin; - } - - inline const char * c_str() const - { - *m_end = '\0'; - return m_begin; - } - - inline void clear() - { - m_end = m_begin; - *m_end = '\0'; - } - - inline size_t size() const - { - return m_end - m_begin; - } - - inline char* begin() const - { - return m_begin; - } - - inline char* end() const - { - return m_end; - } - - inline size_t length() const - { - return size(); - } - - inline bool empty() const - { - return m_begin == m_end; - } - - inline void reverse(char* in_left, char* in_right) - { - char* left = in_left; - char* right = in_right; - while (left < right) - { - char temp = *--right; - *right = *left; - *left++ = temp; - } - } - - inline void reverse() - { - reverse(m_begin, m_end); - } - - inline void to_lower() - { - char* pToDo = m_begin; - - while (pToDo < m_end) - { - *pToDo = static_cast(std::tolower(*pToDo)); - ++pToDo; - } - } - - inline void to_upper() - { - char* pToDo = m_begin; - - while (pToDo < m_end) - { - *pToDo = static_cast(std::toupper(*pToDo)); - ++pToDo; - } - } - - // append a single char in_count times - inline void append(const char in_charToAppend, const size_t in_count) - { - size_t counter = 0; - while ((m_end < m_begin+m_MaxFixedStringLength) && counter++ < in_count) - *m_end++ = in_charToAppend; -#if kEnableDebug == 1 - if (counter < in_count) // if there wasn't enough room for some appended chars - { - m_begin[0] = '@'; // mark the string as overflowed - } -#endif - *m_end = '\0'; - } - - inline void append(const char* in_chars) - { - operator<<(in_chars); - } - - // append "iterator style" - inline void append(const char* in_chars_begin, const char* in_chars_end) - { - const char* curr_char = in_chars_begin; - while ((m_end < m_begin+m_MaxFixedStringLength) && curr_char < in_chars_end && *curr_char != '\0') - *m_end++ = *curr_char++; - -#if kEnableDebug == 1 - if (curr_char < in_chars_end) // if there wasn't enough room for some appended chars - { - m_begin[0] = '@'; // mark the string as overflowed - } -#endif - *m_end = '\0'; - } - - // append from a char* in_count chars, (no \0 is required to terminate the input string) - inline void append(const char* in_chars_begin, const size_t in_count) - { - append(in_chars_begin, in_chars_begin + in_count); - } - - // assign from a char* in_count chars, (no \0 is required to terminate the input string) - inline void assign(const char* in_chars_begin, const size_t in_count) - { - clear(); - append(in_chars_begin, in_chars_begin + in_count); - } - - // assign from a char* , (a \0 is required to terminate the input string) - inline void assign(const char* in_chars_ptr) - { - clear(); - operator<<(in_chars_ptr); - } - - // assign from a char* to a char* - inline void assign(const char* in_begin, const char* in_end) - { - assign(in_begin, size_t(in_end - in_begin)); - } - - inline void append_double_with_precision(const double in_double, const int in_precision) - { - const unsigned int tempBufSize = 32; - char buf[tempBufSize]; - - #ifdef PLATFORM_WINDOWS - _snprintf_s(buf, tempBufSize, tempBufSize - 1, "%.*f", in_precision, in_double); - #endif - #ifdef __APPLE__ - std::snprintf(buf, tempBufSize, "%.*f", in_precision, in_double); - #endif - #ifdef __linux__ - snprintf(buf, tempBufSize, "%.*f", in_precision, in_double); - #endif - - operator<<(buf); - } - - inline void append_uint(const uint64_t in_uint, const int_fast16_t in_base = 10) - { - uint_fast64_t num = in_uint; - - char* lasr_char_before = m_end; - - do { - char remainder(static_cast(num % in_base)); - - if ( remainder < 10 ) - operator<<(char(remainder + '0')); - else - operator<<(char(remainder - 10 + 'A')); - - num /= in_base; - } while (num != 0); - - reverse(lasr_char_before, m_end); - } - - inline void append_hex_binary(const uint8_t* in_binary, const size_t in_size) - { - static const char hexdigits[] = "0123456789ABCDEF"; - -#if _BYTEORDER_BIG_ENDIAN==1 - for (size_t ibyte = 0; ibyte < in_size; ++ibyte) -#elif _BYTEORDER_BIG_ENDIAN==0 - for (size_t ibyte = in_size; ibyte > 0; --ibyte) -#endif - { - operator<<(hexdigits[in_binary[ibyte - 1] >> 4]); - operator<<(hexdigits[in_binary[ibyte - 1] & 0x0F]); - } - } - - inline WCFixedStringBase& operator<<(const char in_charToAppend) - { - if (m_end < m_begin+m_MaxFixedStringLength) - *m_end++ = in_charToAppend; -#if kEnableDebug == 1 - else // if there wasn't enough room for the appended char - { - m_begin[0] = '@'; // mark the string as overflowed - } -#endif - - *m_end = '\0'; - - return *this; - } - - inline WCFixedStringBase& operator<<(const char* const in_strToAppend) - { - if (0 != in_strToAppend) - { - const char* pSource = in_strToAppend; - - while (*pSource != '\0' && m_end < m_begin+m_MaxFixedStringLength) - *m_end++ = *pSource++; - -#if kEnableDebug == 1 - if (*pSource != '\0') // if there wasn't enough room for some appended chars - { - m_begin[0] = '@'; // mark the string as overflowed - } -#endif - *m_end = '\0'; - } - - return *this; - } - - WCFixedStringBase& operator<<(const uint64_t in_uint) - { - append_uint(in_uint, 10); - - return *this; - } - - - // Warning prevention: the operator<< function overload for unsigneds used to create lots - // of warnings once size_t usage was becoming widespread. So for each OS we define only - // those overloads that are actually needed. On Windows 32 bit we still get - // 'warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned int', possible loss of data' - // warning which we do not know how to solve yet. The function DummyFunctionsForWarningTest - // in file WCFixedStringStream.cpp calls all combinations of operator<<(unsigned something) - // And should produce no warnings - (except the C4267 on windows). -#if defined(__APPLE__) // both 32 & 64 bit - WCFixedStringBase& operator<<(const size_t in_uint) { - return operator<<(static_cast(in_uint)); - } -#endif -// WCFixedStringBase& operator<<(const unsigned char in_uint) { -// return operator<<(static_cast(in_uint)); -// } -// -// WCFixedStringBase& operator<<(const size_t in_uint) { -// return operator<<(static_cast(in_uint)); -// } -// -#if defined(__APPLE__) || defined(PLATFORM_WINDOWS) || defined(__linux__) // both 32 & 64 bit - WCFixedStringBase& operator<<(const unsigned int in_uint) { - return operator<<(static_cast(in_uint)); - } -#endif -// -#if defined(PLATFORM_WINDOWS) || defined(__linux__) // both 32 & 64 bit - WCFixedStringBase& operator<<(const unsigned long in_uint) { - return operator<<(static_cast(in_uint)); - } -#endif - - WCFixedStringBase& operator<<(const long long in_int) - { - if (in_int < 0) - operator<<('-'); -#ifdef PLATFORM_WINDOWS -// uintmax_t unsigned_in_num = _abs64(in_int); - uintmax_t unsigned_in_num = in_int < 0 ? static_cast(-in_int) : static_cast(in_int); -#else - uintmax_t unsigned_in_num = std::abs(in_int); -#endif - append_uint(unsigned_in_num, 10); - - return *this; - } - - WCFixedStringBase& operator<<(const short in_int) { - return operator<<(static_cast(in_int)); - } - - WCFixedStringBase& operator<<(const int in_int) { - return operator<<(static_cast(in_int)); - } - - WCFixedStringBase& operator<<(const long in_int) { - return operator<<(static_cast(in_int)); - } - - WCFixedStringBase& operator<<(const double in_doubleToWrite) - { - append_double_with_precision(in_doubleToWrite, 10); - - return *this; - } - - WCFixedStringBase& operator<<(const float in_floatToWrite) - { - append_double_with_precision(double(in_floatToWrite), 5); - - return *this; - } - - inline WCFixedStringBase& operator<<(const WCFixedStringBase& in_fixedStrToAppend) - { - operator<<(in_fixedStrToAppend.c_str()); - - return *this; - } - - WCFixedStringBase& operator<< (bool abool) - { - return abool ? operator<<("true") : operator<<("false"); - } - - template WCFixedStringBase& operator+=(T in_type) - { - return operator<<(in_type); - } - - ptrdiff_t compare(const char* in_to_compare) const - { - ptrdiff_t retVal = 1; - - if (0 != in_to_compare) - { - retVal = strcmp(c_str(), in_to_compare); - } - - return retVal; - } - - - ptrdiff_t compare(const WCFixedStringBase& in_to_compare) const - { - ptrdiff_t retVal = compare(in_to_compare.c_str()); - return retVal; - } - - ptrdiff_t case_insensitive_compare(const char* in_to_compare) const - { - ptrdiff_t retVal = 1; - - if (0 != in_to_compare) - { -#ifdef PLATFORM_WINDOWS - retVal = _stricmp(c_str(), in_to_compare); -#endif -#if defined(__linux__) || defined(__APPLE__) - retVal = strcasecmp(c_str(), in_to_compare); -#endif - } - - return retVal; - } - - ptrdiff_t case_insensitive_compare(const WCFixedStringBase& in_to_compare) const - { - ptrdiff_t retVal = case_insensitive_compare(in_to_compare.c_str()); - return retVal; - } - - pos_t find(const char in_char_to_find) const - { - const char* pCurrChar = m_begin; - while (pCurrChar < m_end && *pCurrChar != in_char_to_find) - ++pCurrChar; - - return (pCurrChar < m_end) ? (pCurrChar - m_begin) : npos; - } - - pos_t rfind(const char in_char_to_find) const - { - pos_t retVal = npos; - const char* pCurrChar = m_end; - - while (pCurrChar != m_begin) - { - --pCurrChar; - if (*pCurrChar == in_char_to_find) - { - retVal = pCurrChar - m_begin; - break; - } - } - - return retVal; - } - - pos_t find(const char* in_chars_to_find, const pos_t in_start_from = 0) const - { - pos_t retVal = npos; - size_t to_find_size = ::strlen(in_chars_to_find); - - if (to_find_size > 0 && to_find_size <= size() && in_start_from < size()) - { - const char* pCurrChar = m_begin + in_start_from; - while ((m_end - pCurrChar) >= (ptrdiff_t)to_find_size) - { - int found = ::memcmp(pCurrChar, in_chars_to_find, to_find_size); - if (0 == found) - { - retVal = (pCurrChar - m_begin); - break; - } - - ++pCurrChar; - } - } - - return retVal; - } - - pos_t rfind(const char* in_chars_to_find) const - { - pos_t retVal = npos; - size_t to_find_size = ::strlen(in_chars_to_find); - - if (to_find_size > 0 && to_find_size <= size()) - { - const char* pCurrChar = m_end - to_find_size; - while (m_begin <= pCurrChar) - { - int found = ::memcmp(pCurrChar, in_chars_to_find, to_find_size); - if (0 == found) - { - retVal = (pCurrChar - m_begin); - break; - } - - --pCurrChar; - } - } - - return retVal; - } - - pos_t find_case_insensitive(const char* in_chars_to_find, const pos_t in_start_from = 0) const - { - pos_t retVal = npos; - size_t to_find_size = ::strlen(in_chars_to_find); - - if (to_find_size > 0 && to_find_size <= size() && in_start_from < size()) - { - const char* pCurrChar = m_begin + in_start_from; - while ((m_end - pCurrChar) >= (ptrdiff_t)to_find_size) - { - size_t i; - for (i = 0; i < to_find_size; ++i) - { - if (tolower(*(pCurrChar+i)) != tolower(in_chars_to_find[i])) - break; - } - - if (i == to_find_size) - { - retVal = (pCurrChar - m_begin); - break; - } - - ++pCurrChar; - } - } - - return retVal; - } - - pos_t find_first_of(const char* in_possibe_chars_to_find, const pos_t in_start_from = 0) const - { - pos_t retVal = npos; - - if (in_start_from < size()) - { - const char* pFoundChar = strpbrk(m_begin + in_start_from, in_possibe_chars_to_find); - if (0 != pFoundChar) - { - retVal = (pFoundChar - m_begin); - } - } - - return retVal; - } - - pos_t find_last_of(const char* in_possibe_chars_to_find, const pos_t in_start_from = 0) const - { - pos_t retVal = npos; - - pos_t curr_location = in_start_from; - - while (size() > curr_location) - { - pos_t found = find_first_of(in_possibe_chars_to_find, curr_location); - if (npos != found) - { - retVal = found; - curr_location = found + 1; - } - else - break; - } - - return retVal; - } - - pos_t find_first_not_of(const char* in_acceptable_chars, const pos_t in_start_from = 0) const - { - pos_t retVal = npos; - - if (in_start_from < size()) - { - retVal = (strspn(m_begin + in_start_from, in_acceptable_chars)); - if (size() <= retVal + in_start_from) - { - retVal = npos; - } - else - { - retVal += in_start_from; - } - } - - return retVal; - } - - pos_t find_last_not_of(const char* in_acceptable_chars, const pos_t in_start_from = 0) const - { - pos_t retVal = npos; - - pos_t curr_location = in_start_from; - - while (size() > curr_location) - { - pos_t found = find_first_not_of(in_acceptable_chars, curr_location); - if (npos != found) - { - retVal = found; - curr_location = found + 1; - } - else - break; - } - - return retVal; - } - - // return true if in_begin_text is found at position 0 OR if in_begin_text is empty - bool begins_with(const char* in_begin_text) const - { - pos_t where = find(in_begin_text, 0); - bool retVal = (0 == where) || (0 == ::strlen(in_begin_text)); - return retVal; - } - - // return true if in_end_text is found at th end OR if in_end_text is empty - bool ends_with(const char* in_end_text) const - { - pos_t where = rfind(in_end_text); - bool retVal = ((size() - strlen(in_end_text)) == where) || (0 == ::strlen(in_end_text)); - return retVal; - } - - size_t replace(const char in_look_for, const char in_replace_with) - { - size_t retVal = 0; - - char* pCurrChar = m_begin; - while (pCurrChar < m_end) - { - if (*pCurrChar == in_look_for) - { - *pCurrChar = in_replace_with; - ++retVal; - } - ++pCurrChar; - } - - return retVal; - } - - // erase in_size chars starting from in_location - void erase(const pos_t in_location, const size_t in_num_chars = 1) - { - if (size() > in_location && in_num_chars > 0) - { - size_t actual_num_chars = WUMin(in_num_chars, size_t(size() - in_location)); - char* pTo = m_begin + in_location; - char* pFrom = pTo + actual_num_chars; - - while (pFrom < m_end) - *pTo++ = *pFrom++; - - resize(size() - actual_num_chars); - } - } - - // erase any char that appear in in_forbidden_chars - void erase_all_of(const char* in_forbidden_chars) - { - pos_t curr_location = 0; - - while (npos != curr_location) - { - curr_location = find_first_of(in_forbidden_chars, curr_location); - if (npos != curr_location) - erase(curr_location); - } - } - - // erase any char that do not appear in in_allowed_chars - void erase_all_not_of(const char* in_allowed_chars) - { - pos_t curr_location = 0; - - while (npos != curr_location) - { - curr_location = find_first_not_of(in_allowed_chars, curr_location); - if (npos != curr_location) - erase(curr_location); - } - } - - //! Copy the content of fixed string to a buffer appending a '\0' at the end. - //! If in_buffer_size is more than the allocated buffer size memory over write will happen! - void copy_to_buffer(const size_t in_buffer_size, char* out_buffer) - { - if (in_buffer_size > 0 && 0 != out_buffer) - { - char* cur_buffer = out_buffer; - const char* cur_fixed = m_begin; - const char* end_buffer = out_buffer + (WUMin(in_buffer_size - 1, m_end - m_begin)); - while (cur_buffer < end_buffer) - *cur_buffer++ = *cur_fixed++; - - *cur_buffer = '\0'; - } - } - -protected: - ~WCFixedStringBase() {} - - char* const m_begin; - const size_t m_MaxFixedStringLength; - char* m_end; - -private: - WCFixedStringBase(); - WCFixedStringBase(const WCFixedStringBase& in_fixedStrToCopy); -#if 0 - : - m_begin(in_fixedStrToCopy.m_begin), - m_MaxFixedStringLength(in_fixedStrToCopy.m_MaxFixedStringLength), - m_end(in_fixedStrToCopy.m_end) - { - } -#endif -}; - -template class DllExport WCFixedString : public WCFixedStringBase -{ -public: - - inline WCFixedString() : - WCFixedStringBase(m_fixedString, kMaxFixedStringLength) - { - } - - inline WCFixedString(const char* const in_strToAssign) : - WCFixedStringBase(m_fixedString, kMaxFixedStringLength) - { - operator<<(in_strToAssign); - } - - inline WCFixedString(const WCFixedStringBase& in_fixedStrToAssign) : - WCFixedStringBase(m_fixedString, kMaxFixedStringLength) - { - operator<<(in_fixedStrToAssign); - } - - inline WCFixedString(const WCFixedString& in_fixedStrToAssign) : - WCFixedStringBase(m_fixedString, kMaxFixedStringLength) - { - operator<<(in_fixedStrToAssign); - } - - inline WCFixedString(const char in_char, const size_t in_count = 1) : - WCFixedStringBase(m_fixedString, kMaxFixedStringLength) - { - append(in_char, in_count); - } - - inline WCFixedString(const char* in_chars, const size_t in_count) : - WCFixedStringBase(m_fixedString, kMaxFixedStringLength) - { - append(in_chars, in_count); - } - - // substr now supports negative in_length, which means "from the end" so - // "abcdefg".substr(1, -1) == "bcdef" - inline const WCFixedString substr(const pos_t in_pos = 0, const spos_t in_length = kMaxFixedStringLength) const - { - pos_t adjusted_pos = WUMin(in_pos, size()); - size_t adjusted_length = 0; - if (in_length < 0) - { - adjusted_length = size_t(WUMax(0, spos_t(size() - adjusted_pos) + in_length)); - } - else - adjusted_length = WUMin(in_length, size() - adjusted_pos); - - WCFixedString retVal; - retVal.append(m_begin + adjusted_pos, adjusted_length); - - return retVal; - } - -protected: - - char m_fixedString[kMaxFixedStringLength + 1]; // the "+ 1" is so that *m_end is always valid, and we can put the '\0' there}; -}; - -inline bool operator==(const WCFixedStringBase& in_left, const WCFixedStringBase& in_right) -{ - return 0 == in_left.compare(in_right.c_str()); -} - -inline bool operator==(const WCFixedStringBase& in_left, const char* const in_right) -{ - return 0 == in_left.compare(in_right); -} - -inline bool operator!=(const WCFixedStringBase& in_left, const WCFixedStringBase& in_right) -{ - return 0 != in_left.compare(in_right.c_str()); -} - -inline bool operator!=(const WCFixedStringBase& in_left, const char* const in_right) -{ - return 0 != in_left.compare(in_right); -} - -// class WCFixedStringBase -typedef WCFixedString<4> WCFixedString4; -typedef WCFixedString<15> WCFixedString15; -typedef WCFixedString<31> WCFixedString31; -typedef WCFixedString<63> WCFixedString63; -typedef WCFixedString<127> WCFixedString127; -typedef WCFixedString<255> WCFixedString255; -typedef WCFixedString<511> WCFixedString511; -typedef WCFixedString<1023> WCFixedString1023; -typedef WCFixedString<2047> WCFixedString2047; - -template - class WCFixedStringPair : public std::pair< WCFixedString, WCFixedString > -{ -public: - WCFixedStringPair(const char* const in_firstStr = 0, const char* const in_secondStr = 0) : - std::pair< WCFixedString, WCFixedString >(in_firstStr, in_secondStr) {} - WCFixedStringPair(const WCFixedStringBase& in_firstStr, const char* const in_secondStr = 0) : - std::pair< WCFixedString, WCFixedString >(in_firstStr, in_secondStr) {} - WCFixedStringPair(const WCFixedStringBase& in_firstStr, const WCFixedStringBase& in_secondStr) : - std::pair< WCFixedString, WCFixedString >(in_firstStr, in_secondStr) {} -}; - -#endif // #ifndef __WCFixedString_h__ diff --git a/libs/backends/wavesaudio/wavesapi/MiscUtils/WUErrors.h b/libs/backends/wavesaudio/wavesapi/MiscUtils/WUErrors.h deleted file mode 100644 index 007d32f433..0000000000 --- a/libs/backends/wavesaudio/wavesapi/MiscUtils/WUErrors.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __WUErrors_h__ - #define __WUErrors_h__ - -/* Copy to include: -#include "WUErrors.h" -*/ - -#include "BasicTypes/WUTypes.h" - -// General errors -//const WTErr eNoErr = 0; // moved to #include "WavesPublicAPI/WTErr.h" -const WTErr eGenericErr = -1; -const WTErr eUserCanceled = -2; -const WTErr eUnknownErr = -3; -const WTErr eExceptionErr = -4; -const WTErr eEndianError = -5; -const WTErr eThreadSafeError = -6; -const WTErr eSomeThingNotInitailzed = -7; -const WTErr eWrongObjectState = -8; //!< object was not in an acceptable state -const WTErr eUninitalized = -9; -const WTErr eDeprecated = -10; -const WTErr eCommandLineParameter = -11; -const WTErr eNotANumber = -12; //!< expected a number but none was found -const WTErr eNotJustANumber = -13; //!< expected a number and found one but also other stuff (e.g. "123XYZ") -const WTErr eNegativeNumber = -14; //!< expected a positive number and found a negative -const WTErr eTimeOut = -15; //!< something timed out -const WTErr eCoreAudioFailed = -16; //!< Error in a core audio call -const WTErr eSomeThingInitailzedTwice = -17; -const WTErr eGenerateHelpInfo = -18; -const WTErr eOutOfRangeNumber = -19; -const WTErr eMacOnlyCode = -20; -const WTErr eWinOnlyCode = -21; -const WTErr eAppLaunchFailed = -22; //!< failed to launch an application -const WTErr eAppTerminateFailed = -23; //!< failed to terminate an application -const WTErr eAppReturnedError = -24; //!< Non zero exit code from application -const WTErr eNotImplemented = -25; //!< Function is not implmemented -const WTErr eNotEmpty = -26; //!< Something was expected to be empty but is not -const WTErr eAsioFailed = -27; - -// File Manager errors -const WTErr eFMNoSuchVolume = -1001; -const WTErr eFMFileNotFound = -1002; -const WTErr eFMFileAllreadyExists = -1003; -const WTErr eFMAllreadyOpenWithWritePerm = -1004; -const WTErr eFMEndOfFile = -1005; -const WTErr eFMPermissionErr = -1006; -const WTErr eFMBusyErr = -1007; -const WTErr eFMOpenFailed = -1008; -const WTErr eFMTranslateFileNameFailed = -1009; -const WTErr eFMWTPathRefCreationFailed = -1010; -const WTErr eFMReadFailed = -1011; -const WTErr eFMIllegalPathRef = -1012; -const WTErr eFMFileNotOpened = -1013; -const WTErr eFMFileSizeTooBig = -1014; -const WTErr eFMNoSuchDomain = -1015; -const WTErr eFMNoSuchSystemFolder = -1016; -const WTErr eFMWrongParameters = -1017; -const WTErr eFMIsNotAFolder = -1018; -const WTErr eFMIsAFolder = -1019; -const WTErr eFMIsNotAFile = -1020; -const WTErr eFMIsAFile = -1021; -const WTErr eFMDeleteFailed = -1022; -const WTErr eFMCreateFailed = -1023; -const WTErr eFMPathTooLong = -1024; -const WTErr eFMIOError = -1025; -const WTErr eFMIllegalOpenFileRef = -1026; -const WTErr eFMDiskFull = -1027; -const WTErr eFMFileNotEmpty = -1028; -const WTErr eFMEndOfFolder = -1029; -const WTErr eFMSamePath = -1030; -const WTErr eFMPathTooShort = -1031; -const WTErr eFMIncompletePath = -1032; -const WTErr eFMIsNoAFileSystemLink = -1033; -const WTErr eFMSymlinkBroken = -1034; -const WTErr eFMMoveFailed = -1035; -const WTErr eFMWriteFailed = -1036; -const WTErr eFMTooManyOpenFiles = -1037; -const WTErr eFMTooManySymlinks = -1038; - -// System errors -const WTErr eGenericSystemError = -2000; -const WTErr eSysNoEnvironmentVariable = -2001; -const WTErr eDLLLoadingFailed = -2002; -const WTErr eFuncPoinerNotFound = -2003; -const WTErr eDLLNotFound = -2004; -const WTErr eBundleNotLoaded = -2005; -const WTErr eBundleCreateFailed = -2006; -const WTErr eBundleExecutableNotFound = -2007; -const WTErr eNotABundle = -2008; -const WTErr eInvalideDate = -2009; -const WTErr eNoNetDevice = -2010; -const WTErr eCacheCreatedFromResource = -2011; -const WTErr eNotAValidApplication = -2012; - -// Resource Manager errors -const WTErr eRMResNotFound = -3000; -const WTErr eRMResExists = -3001; //!< a resource exist even though it's not expected to -const WTErr eRMContainerNotFound = -3002; //!< The container was not found in the list of containers -const WTErr eRMResRefNotFound = -3003; //!< The resRef was not found in container's resource list -const WTErr eRMInvalidResRef = -3004; -const WTErr eRMInvalidResContainer = -3005; -const WTErr eRMInvalidNativeResContainer = -3006; -const WTErr eRMAttachResContainerFailed = -3007; -const WTErr eRMInvalidResID = -3008; -const WTErr eRMResUpdateFailed = -3009; - -// Graphic Manager & GUI errors -const WTErr eGMIsNotInitailzed = -3500; -const WTErr eGMInvalidImage = -3501; -const WTErr eGMGenericErr = -3502; -const WTErr eGMNoCurrentContext = -3503; -const WTErr eGUISkinNotFound = -3504; -const WTErr eGMNoVertices = -3505; -const WTErr eGMNoColors = -3506; -const WTErr eGMNoTexture = -3507; -const WTErr eGMIncompatibleOGLVersion = -3508; -const WTErr eGMNoDeviceContext = -3509; -const WTErr eGMNoPixelFormat = -3510; -const WTErr eGMNoOGLContext = -3511; -const WTErr eGMNoOGLContextSharing = -3512; -const WTErr eGMUnsupportedImageFormat = -3513; -const WTErr eGMUninitializedContext = -3514; -const WTErr eControlOutOfRange = -3515; -const WTErr eGMUninitializedFont = -3516; -const WTErr eGMInvalidFontDrawMethod = -3517; -const WTErr eGMUnreleasedTextures = -3518; -const WTErr eGMWrongThread = -3519; -const WTErr eGMDontCommitDraw = -3520; -// Errors in the -5000 -> -5999 are defined in Waves-incs.h - -// Memory errors -const WTErr eMemNewFailed = -4001; //!< Something = new CSomething, returned null -const WTErr eMemNewTPtrFailed = -4002; //!< NewTPtr or NewTPtrClear failed -const WTErr eMemNullPointer = -4003; //!< a null pointer was encountered where it should not -const WTErr eMemObjNotInitialized = -4004; -const WTErr eMemBuffTooShort = -4005; //!< the buffer in question did not have enough space for the operation -const WTErr eInstanciationFailed = -4006; -const WTErr eMemAddressSpaceError = -4007; //!< memory falls outside the legal address space -const WTErr eMemBadPointer = -4008; -const WTErr eMemOutOfMemory = -4009; - -// XML Errors -const WTErr eXMLParserFailed = -6001; -const WTErr eXMLTreeNotValid = -6002; -const WTErr eXMLTreeEmpty = -6003; -const WTErr eXMLElementMissing = -6004; -const WTErr eXMLElementUninitalized = -6005; //!< element was default constructed it has not element name, etc.. -const WTErr eXMLElementIncomplete = -6006; //!< XML parser did not complete building the element -const WTErr eXMLAttribMissing = -6007; - -// Preset errors -const WTErr ePresetFileProblem = -7860; -const WTErr eInvalidFileFormatProblem = -7861; -const WTErr ePresetLockedProblem = -7862; -const WTErr ePresetInfoNotFound = -7863; -const WTErr eDuplicatePluginSpecificTag = -7959; -const WTErr ePluginSpecifcNotExisting = -7960; -const WTErr eBuffSizeToSmall = -7961; -const WTErr eCreatingPopupWhereAnItemExists = -7962; -const WTErr eDeletePluginSpecifcFailed = -7963; -const WTErr eFactoryPresetNumOutOfRange = -7964; -const WTErr eNoFactoryPresets = -7965; -const WTErr eLoadPresetToPlugin_vec_empty = -7966; -const WTErr eFactoryPresetNotFound = -7967; -const WTErr eCantCreateUserPrefFile = -7968; -const WTErr eDataFormatNotSupported = -7969; -const WTErr eCantLoadProcessFunction = -7970; -const WTErr eIllegalChunkIndex = -7971; -const WTErr eIllegalChunkID = -7972; -const WTErr eIllegalChunkVersion = -7973; - - -// Shell errors -const WTErr eNotAPluginFile = -8001; -const WTErr eFaildToLoadPluginDLL = -8002; -const WTErr eNoPluginManager = -8003; -const WTErr eGetAvailablePluginsFailed = -8004; -const WTErr eNoPluginsAvailable = -8005; -const WTErr ePluginSubComponentNotFound = -8006; -const WTErr ePluginOpenFailed = -8007; -const WTErr eSubComponentRejected = -8009; //!< user did not want this sub-component - probably through preferences -const WTErr eIncompatibleNumOfIOs = -8010; //!< e.g. surround sub-component in stereo only shell -const WTErr eStemProblem = -8011; //!< Some problem with stems -const WTErr eComponentTypeNotSupported = -8012; -const WTErr ePluginNotLoaded = -8013; -const WTErr ePluginInstanceNotCreate = -8014; -const WTErr ePluginAlgNotCreate = -8015; -const WTErr ePluginGUINotCreate = -8016; -const WTErr eMissmatchChannelCount = -8017; -const WTErr eIncompatibleVersion = -8018; -const WTErr eIncompatibleAffiliation = -8019; -const WTErr eNoSubComponentsFound = -8020; - -// Net-shell errors -const WTErr eNetShellInitFailed = -9001; - -// Protection errors -const WTErr eWLSLicenseFileNotFound = -10001; -const WTErr eWLSPluginNotAuthorized = -10002; -const WTErr eWLSNoLicenseForPlugin = -10003; -const WTErr eWLSInvalidLicenseFileName = -10004; -const WTErr eWLSInvalidLicenseFileContents = -10005; -const WTErr eWLSInvalidDeviceID = -10006; -const WTErr eWLSInvalidClientID = -10007; -const WTErr eWLSLicenseFileDownloadFailed = -10008; -const WTErr eWLSNoLicensesForClientOrDevice = -10009; -const WTErr eWLSNoLicensesForSomePlugins = -10010; - -// Communication errors -const WTErr eCommEndOfRecievedMessage = -11001; -const WTErr eCommSocketDisconnected = -11002; - -// Window Manager Errors -const WTErr eWMEventNotHandled = -12001; -const WTErr eWMDisposeViewFailed = -12002; - -// Plugin View Manager Errors -const WTErr ePVMPlatformNotSupported = -13001; -const WTErr ePVMAlreadyInitialized = -13002; -const WTErr ePVMIllegalParent = -13003; -const WTErr ePVMCannotCreateView = -13004; -const WTErr ePVMNothingSelected = -13005; -const WTErr ePVMDisabledItemChosen = -13006; -const WTErr ePVMMenuItemNotFound = -13007; -const WTErr ePVMMenuItemNotASubMenu = -13008; -const WTErr ePVMUnknownMenu = -13009; -const WTErr ePVMEmptyNativeViewRef = -13010; -const WTErr ePVMGenericError = -13011; -const WTErr ePVMFunctionNotImplemented = -13012; - -// Plugin View Manager - Menu Errors -const WTErr ePVMCannotCreateMenu = -13501; -const WTErr ePVMCannotSetMenuFont = -13502; -const WTErr ePVMCannotSetMenu = -13503; -const WTErr ePVMItemParentNotExists = -13504; - -// Plugin View Manager - TextField Errors -const WTErr ePVMCannotCreateTextField = -13553; -const WTErr ePVMCannotEmbedTextField = -13554; -const WTErr ePVMNoTextToValidate = -13555; -const WTErr ePVMTextTooLong = -13556; -const WTErr ePVMIllegalCharacter = -13557; - - -// Meter Manager Errors -const WTErr eMM_MeterGetMeterValueForParameterNotConnected = -14000 ; - - -//Surface Driver Manager Errors -const WTErr eSDM_SurfaceDriverAPIFailed = -14101; - -// IPC Errors -const WTErr eIPC_CreateNamedPipeFailed = -14200; -const WTErr eIPC_OpenPipeTimeout = -14201; -const WTErr eIPC_DeleteNamedPipeFailed = -14202; -const WTErr eIPC_SelectOnNamedPipeFailed = -14203; -const WTErr eIPC_ReadFromNamedPipeFailed = -14204; -const WTErr eIPC_ReadEndOfFileFromNamedPipe = -14205; -const WTErr eIPC_CloseNamedPipeFailed = -14206; -const WTErr eIPC_ParseArgsFailed = -14207; -const WTErr eIPC_OpenPipeFailed = -14208; -const WTErr eIPC_SendMsgFailed = -14209; -const WTErr eIPC_SendCommandInvalid = -14210; -const WTErr eIPC_QtTestMode = -14211; -const WTErr eIPC_ChangePermissionOnPipe = -14212; -const WTErr eIPC_ConnectionLost = -14213; - -const WTErr eIPC_InvalidRole = -14213; -const WTErr eIPC_CreateNamedPipeM2SFailed = -14214; -const WTErr eIPC_CreateNamedPipeS2MFailed = -14215; -const WTErr eIPC_ChangePermissionOnPipeM2S = -14216; -const WTErr eIPC_ChangePermissionOnPipeS2M = -14217; -const WTErr eIPC_OpenReadPipeFailed = -14218; -const WTErr eIPC_OpenReadPipeDIsableSigPipe = -14219; -const WTErr eIPC_OpenWritePipeFailed = -14220; -const WTErr eIPC_WritePipeFailed = -14221; -const WTErr eIPC_WritePipeNotOpen = -14222; -const WTErr eIPC_WriteBufferResizeFailed = -14223; -const WTErr eIPC_NotConnectedSendMsgFailed = -14224; -const WTErr eIPC_OpenWritePipeWorkerStoping = -14225; -const WTErr eIPC_SoketSendFailed = -14226; -const WTErr eIPC_PtonFailed = -14227; -const WTErr eIPC_SocketFailed = -14228; -const WTErr eIPC_BindFailed = -14229; -const WTErr eIPC_ListenFailed = -14230; -const WTErr eIPC_ConnectFailed = -14231; -const WTErr eIPC_WsaStartupFailed = -14232; -const WTErr eIPC_UdpSocketCreateFailed = -14233; -const WTErr eIPC_UdpSocketConnectFailed = -14234; -const WTErr eIPC_UdpSocketBinFailed = -14235; -const WTErr eIPC_SetBufferPreambleFailed = -14226; - -// Database errors -const WTErr eDB_BatchRollback = -15501; - -// inventory related errors -const WTErr eUnknown_Device = -16001; -const WTErr eInvNoDevice = -16002; - -// SG protocol service errors -const WTErr eSGProtocolService_Not_Running = -17001; -const WTErr eSGProtocolService_Version_MisMatch = -17002; - -// Error code related to Param -const WTErr eInvalidParam = -18001; - -#define WUIsError(theErrorCode) (eNoErr != (theErrorCode)) -#define WUNoError(theErrorCode) (eNoErr == (theErrorCode)) -#define WUThrowError(theErrorCode) {if(WUIsError(theErrorCode))throw (theErrorCode);} -#define WUThrowErrorIfNil(thePtr , theErrorCode) {if (0 == thePtr )throw (theErrorCode);} -#define WUThrowErrorIfFalse(theBool , theErrorCode) {if (!(theBool))throw (theErrorCode);} -#define WUThrowErrorCodeIfError(err,theErrorCode) {if(WUIsError(err))throw (theErrorCode);} - -// Get the error string that match the error code. -DllExport const char* WTErrName(WTErr wtErr); - -#endif //__WUErrors_h__: diff --git a/libs/backends/wavesaudio/wavesapi/MiscUtils/pthread_utils.h b/libs/backends/wavesaudio/wavesapi/MiscUtils/pthread_utils.h deleted file mode 100644 index b370845112..0000000000 --- a/libs/backends/wavesaudio/wavesapi/MiscUtils/pthread_utils.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2014 John Emmas - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __waves_pthread_utils__ -#define __waves_pthread_utils__ - -/* Accommodate thread setting (and testing) for both - * 'libpthread' and 'libpthread_win32' (whose implementations - * of 'pthread_t' are subtlely different) - */ -#ifndef PTHREAD_MACROS_DEFINED -#define PTHREAD_MACROS_DEFINED -#ifdef PTW32_VERSION /* pthread_win32 */ -#define mark_pthread_inactive(threadID) threadID.p=0 -#define is_pthread_active(threadID) threadID.p!=0 -#else /* normal pthread */ -#define mark_pthread_inactive(threadID) threadID=0 -#define is_pthread_active(threadID) threadID!=0 -#endif /* PTW32_VERSION */ - -#endif /* PTHREAD_MACROS_DEFINED */ -#endif /* __waves_pthread_utils__ */ diff --git a/libs/backends/wavesaudio/wavesapi/MiscUtils/safe_delete.h b/libs/backends/wavesaudio/wavesapi/MiscUtils/safe_delete.h deleted file mode 100644 index 0537d1591b..0000000000 --- a/libs/backends/wavesaudio/wavesapi/MiscUtils/safe_delete.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __safe_delete_h__ - #define __safe_delete_h__ - - -/* Copy to include: -#include "safe_delete.h" -*/ - -#define safe_delete(__pObject__) {if((__pObject__) != 0) {delete (__pObject__); (__pObject__) = 0;}} - -#define safe_delete_array(__pArray__) {if((__pArray__) != 0) {delete [] (__pArray__); (__pArray__) = 0;}} - -template void safe_delete_from_iterator(T* pToDelete) -{ - safe_delete(pToDelete); -} - -#endif // __safe_delete_h__ diff --git a/libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.cpp b/libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.cpp deleted file mode 100644 index 1ee568af1e..0000000000 --- a/libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.cpp +++ /dev/null @@ -1,826 +0,0 @@ -#include "Threads/WCThreadSafe.h" -#include - -#if XPLATFORMTHREADS_WINDOWS - #define _WIN32_WINNT 0x0500 // need at least Windows2000 (for TryEnterCriticalSection() and SignalObjectAndWait() - #include "IncludeWindows.h" - #include -#endif // XPLATFORMTHREADS_WINDOWS - - -#if defined(__APPLE__) - #include - #include -#endif // __APPLE__ - -#if XPLATFORMTHREADS_POSIX - #include // avoid the framework version and use the /usr/include version - #include - #include - #include - #include - #include -// We do this externs because comes from MSL -extern "C" FILE *popen(const char *command, const char *type); -extern "C" int pclose(FILE *stream); -static int (*BSDfread)( void *, size_t, size_t, FILE * ) = 0; - -#include - -#endif //XPLATFORMTHREADS_POSIX - -namespace wvNS { -static const unsigned int knMicrosecondsPerSecond = 1000*1000; -static const unsigned int knNanosecondsPerMicrosecond = 1000; -static const unsigned int knNanosecondsPerSecond = knMicrosecondsPerSecond*knNanosecondsPerMicrosecond; - -namespace wvThread -{ - - //-------------------------------------------------------------------------------- - static inline bool EnsureThreadingInitialized() - { - bool bRetval = true; - - return bRetval; - } - //-------------------------------------------------------------------------------- - - - - - //-------------------------------------------------------------------------------- - static uint32_t CalculateTicksPerMicrosecond(); - static uint32_t CalculateTicksPerMicrosecond() - { - uint32_t nTicksPerMicrosecond=0; -#if defined(_WIN32) - LARGE_INTEGER TSC; - ::QueryPerformanceFrequency(&TSC); - nTicksPerMicrosecond = uint32_t (TSC.QuadPart / knMicrosecondsPerSecond); -#elif defined(__linux__) && defined(__i386__) - static const timediff sktd_TSC_MeasurementPeriod = 40*1000; // delay for CalculateTicksPerMicrosecond() to measure the TSC frequency - uint64_t Tstart, Tend; - timeval tvtmp, tvstart, tvend; - - //--------------------- begin measurement code - // poll to align to a tick of gettimeofday - ::gettimeofday(&tvtmp,0); - do { - ::gettimeofday(&tvstart,0); - __asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (Tstart)); // RDTSC - } while (tvtmp.tv_usec!=tvstart.tv_usec); - // delay some - ::usleep(sktd_TSC_MeasurementPeriod); - // - ::gettimeofday(&tvtmp,0); - do { - ::gettimeofday(&tvend,0); - __asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (Tend)); // RDTSC - } while (tvtmp.tv_usec!=tvend.tv_usec); - //--------------------- end measurement code - - suseconds_t elapsed_usec = (tvend.tv_sec-tvstart.tv_sec)*knMicrosecondsPerSecond + (tvend.tv_usec-tvstart.tv_usec); - uint64_t elapsed_ticks = Tend-Tstart; - nTicksPerMicrosecond = uint32_t (elapsed_ticks/elapsed_usec); -#endif - return nTicksPerMicrosecond; - } - -#if defined(__APPLE__) //&& !defined(__MACH__) - - - bool FindNetInterfaceByIPAddress(const char *sIP, char *sInterface) // sIP and sInterface are both char[16] - { - FILE *fProcess , *pSubcall; - char sLine[256]="", *pToken, sCommand[150]; - bool res = false; - int iret; - - fProcess = popen("ifconfig -l inet", "r"); - if (fProcess) - { - memset(sInterface, '\0', 16); - iret = BSDfread(sLine, sizeof(char), sizeof(sLine), fProcess); - pToken = strtok(sLine, " "); - while (pToken) - { - sprintf(sCommand, "ifconfig %s | grep \"inet %s \"", pToken, sIP); - - pSubcall = popen(sCommand, "r"); - if (pSubcall) - { - char sSubline[100]=""; - if (BSDfread(sSubline, sizeof(char), sizeof(sSubline), pSubcall)) - { - // found - strcpy(sInterface, pToken); - res = true; - pclose(pSubcall); - break; - } - } - pclose(pSubcall); - pToken = strtok(NULL, " "); - } - - } - pclose(fProcess); - - return res; - } -#endif // MACOS - - timestamp now(void) - { - EnsureThreadingInitialized(); - static const uint32_t nTicksPerMicrosecond = CalculateTicksPerMicrosecond(); -#if defined(_WIN32) - if (nTicksPerMicrosecond) - { - LARGE_INTEGER TSC; - ::QueryPerformanceCounter(&TSC); - return timestamp(uint32_t(TSC.QuadPart/nTicksPerMicrosecond)); - } - else return timestamp(0); -#elif defined(__APPLE__) - if (nTicksPerMicrosecond) {} // prevent 'unused' warnings - UnsignedWide usecs; - ::Microseconds(&usecs); - return timestamp(usecs.lo); -#elif defined(__linux__) && defined(__i386__) && defined(__gnu_linux__) - uint64_t TSC; - __asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (TSC)); // RDTSC - return timestamp(TSC/nTicksPerMicrosecond); -#elif defined(__linux__) && defined(__PPC__) && defined(__gnu_linux__) - #warning need to implement maybe -#else - #error Dont know how to get microseconds timer ! -#endif // defined(_WIN32) - } - - - void sleep_milliseconds(unsigned int nMillisecs) - { - EnsureThreadingInitialized(); -#if XPLATFORMTHREADS_WINDOWS - ::Sleep(nMillisecs); -#elif XPLATFORMTHREADS_POSIX - ::usleep(nMillisecs*1000); -#else - #error Not implemented for your OS -#endif - } - - -#if XPLATFORMTHREADS_WINDOWS - inline DWORD win32_milliseconds(timediff td) { return (td+499)/1000; } -#endif - - void sleep(timediff _td) - { - if (_td>0) - { - EnsureThreadingInitialized(); -#if XPLATFORMTHREADS_WINDOWS - ::Sleep(win32_milliseconds(_td)); // This is the best we can do in windows -#elif XPLATFORMTHREADS_POSIX - ::usleep(_td); -#else - #error Not implemented for your OS -#endif - } - } - - -#if XPLATFORMTHREADS_WINDOWS - void yield() { ::Sleep(0); } -#elif XPLATFORMTHREADS_POSIX - void yield() { ::sched_yield(); } -#endif - - - - - class ThreadMutexInited::OSDependentMutex : public noncopyableobject - { -#if defined (XPLATFORMTHREADS_WINDOWS) - protected: - CRITICAL_SECTION m_critsec; - public: - - inline OSDependentMutex() { EnsureThreadingInitialized(); ::InitializeCriticalSection(&m_critsec); } - inline ~OSDependentMutex() { EnsureThreadingInitialized(); ::DeleteCriticalSection (&m_critsec); } - inline void obtain() { EnsureThreadingInitialized(); ::EnterCriticalSection (&m_critsec); } - inline void release() { EnsureThreadingInitialized(); ::LeaveCriticalSection (&m_critsec); } - inline bool tryobtain() { EnsureThreadingInitialized(); return TryEnterCriticalSection(&m_critsec)!=FALSE; } - -#elif defined (XPLATFORMTHREADS_POSIX) - protected: - pthread_mutex_t m_ptmutex; - public: - inline OSDependentMutex() - { - EnsureThreadingInitialized(); - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - ::pthread_mutex_init (&m_ptmutex, &attr); - } - inline ~OSDependentMutex() { EnsureThreadingInitialized(); ::pthread_mutex_destroy(&m_ptmutex); } - inline void obtain() { EnsureThreadingInitialized(); ::pthread_mutex_lock (&m_ptmutex); } - inline void release() { EnsureThreadingInitialized(); ::pthread_mutex_unlock (&m_ptmutex); } - inline bool tryobtain() { EnsureThreadingInitialized(); return ::pthread_mutex_trylock(&m_ptmutex)!=EBUSY; } - -#endif - }; - - ThreadMutexInited::ThreadMutexInited() : - m_osdmutex(0) {} - - void ThreadMutexInited::init() - { - if (! is_init()) - { - m_osdmutex = new OSDependentMutex; - } - } - - void ThreadMutexInited::uninit() - { - if (is_init()) - { - delete m_osdmutex; - m_osdmutex = 0; - } - } - - ThreadMutexInited::~ThreadMutexInited() - { - uninit(); - } - - void ThreadMutexInited::obtain() - { - if (is_init()) - { - m_osdmutex->obtain(); - } - } - - void ThreadMutexInited::release() - { - if (is_init()) - { - m_osdmutex->release(); - } - } - - bool ThreadMutexInited::tryobtain() - { - bool retVal = true; - if (is_init()) - { - retVal = m_osdmutex->tryobtain(); - } - return retVal; - } - - class ThreadConditionSignal::OSDependentObject : public noncopyableobject - { -#if defined (XPLATFORMTHREADS_POSIX) - - protected: - pthread_cond_t m_ptcond; - pthread_mutex_t m_ptmutex; - public: - inline OSDependentObject() - { - EnsureThreadingInitialized(); - ::pthread_mutex_init(&m_ptmutex,0); - ::pthread_cond_init(&m_ptcond, 0); - } - inline ~OSDependentObject() { ::pthread_cond_destroy(&m_ptcond), ::pthread_mutex_destroy(&m_ptmutex); } - inline void signal_unicast() { ::pthread_cond_signal(&m_ptcond); } - inline void signal_broadcast() { ::pthread_cond_broadcast(&m_ptcond); } - inline void await_signal() { ::pthread_cond_wait(&m_ptcond, &m_ptmutex); } - inline bool await_signal(timediff td) - { - timespec tspecDeadline; - timeval tvNow; - ::gettimeofday(&tvNow,0); - tspecDeadline.tv_nsec = (tvNow.tv_usec + td%knMicrosecondsPerSecond)*knNanosecondsPerMicrosecond; - tspecDeadline.tv_sec = tvNow.tv_sec + td/knMicrosecondsPerSecond; - if (!(tspecDeadline.tv_nsec < suseconds_t(knNanosecondsPerSecond))) - ++tspecDeadline.tv_sec, tspecDeadline.tv_nsec-=knNanosecondsPerSecond; - return ::pthread_cond_timedwait(&m_ptcond, &m_ptmutex, &tspecDeadline) != ETIMEDOUT; - } - - void obtain_mutex() { ::pthread_mutex_lock(&m_ptmutex); } - bool tryobtain_mutex() { return ::pthread_mutex_trylock(&m_ptmutex)!=EBUSY; } - void release_mutex() { ::pthread_mutex_unlock(&m_ptmutex); } - - -#elif XPLATFORMTHREADS_WINDOWS - protected: - unsigned int m_nWaiterCount; - CRITICAL_SECTION m_csectWaiterCount; - - HANDLE m_hndSemaphoreSignaller; // We keep this semaphore always at 0 count (non-signalled). We use it to release a controlled number of threads. - HANDLE m_hndEventAllWaitersReleased; // auto-reset - HANDLE m_hndMutex; // the mutex associated with the condition - bool m_bBroadcastSignalled; // means that the last waiter must signal m_hndEventAllWaitersReleased when done waiting - - protected: - // - - - - - - - - - - - - - - - - - - - - - - - - - bool await_signal_win32(DWORD dwTimeout) - { - ::EnterCriticalSection(&m_csectWaiterCount); - ++m_nWaiterCount; - ::LeaveCriticalSection(&m_csectWaiterCount); - // This is the actual wait for the signal - bool bWaitSucceeded = ::SignalObjectAndWait(m_hndMutex, m_hndSemaphoreSignaller, dwTimeout, FALSE) == WAIT_OBJECT_0; - // - ::EnterCriticalSection(&m_csectWaiterCount); - bool bLastWaiter = --m_nWaiterCount==0 && m_bBroadcastSignalled; - ::LeaveCriticalSection(&m_csectWaiterCount); - - // re-acquire the mutex - if (bLastWaiter) - ::SignalObjectAndWait(m_hndEventAllWaitersReleased, m_hndMutex, INFINITE, FALSE); - else - ::WaitForSingleObject(m_hndMutex, INFINITE); - return bWaitSucceeded; - } - - - public: - - inline bool await_signal(timediff td) { return await_signal_win32((win32_milliseconds(td))); } - inline void await_signal() { await_signal_win32(INFINITE); } - - OSDependentObject() : m_nWaiterCount(0), m_bBroadcastSignalled(false) - { - EnsureThreadingInitialized(); - ::InitializeCriticalSection(&m_csectWaiterCount); - m_hndEventAllWaitersReleased = ::CreateEvent( - 0, // security - FALSE, // auto-reset - FALSE, // initial state non-sognalled - 0); // name - m_hndSemaphoreSignaller = ::CreateSemaphore( - 0, // security - 0, // initial count (and will stay this way) - 0x100000, // maximum count (should be as large as the maximum number of waiting threads) - 0); // name - m_hndMutex = ::CreateMutex( - 0, // security - FALSE, // not owned initially - 0); // name - //if (m_hndEventAllWaitersReleased==INVALID_HANDLE_VALUE || m_hndSemaphoreSignaller==INVALID_HANDLE_VALUE) - // throw something(); - } - - ~OSDependentObject() - { - ::CloseHandle(m_hndMutex); - ::CloseHandle(m_hndSemaphoreSignaller); - ::CloseHandle(m_hndEventAllWaitersReleased); - ::DeleteCriticalSection(&m_csectWaiterCount); - } - - inline void signal_unicast() - { - ::EnterCriticalSection(&m_csectWaiterCount); - unsigned int nWaiters = m_nWaiterCount; - ::LeaveCriticalSection(&m_csectWaiterCount); - if (nWaiters) - ::ReleaseSemaphore(m_hndSemaphoreSignaller, 1, 0); // release 1 semaphore credit to release one waiting thread - } - - void signal_broadcast() - { - ::EnterCriticalSection(&m_csectWaiterCount); - unsigned int nWaiters = m_nWaiterCount; - if (nWaiters) - { - m_bBroadcastSignalled = true; - ::ReleaseSemaphore(m_hndSemaphoreSignaller, nWaiters, 0); // release as many credits as there are waiting threads - ::LeaveCriticalSection(&m_csectWaiterCount); - ::WaitForSingleObject(m_hndEventAllWaitersReleased, INFINITE); - // at this point all threads are waiting on m_hndMutex, which would be released outside this function call - m_bBroadcastSignalled = false; - } - else - // no one is waiting - ::LeaveCriticalSection(&m_csectWaiterCount); - } - //------------------------------------------------ - inline void obtain_mutex() { ::WaitForSingleObject(m_hndMutex, INFINITE); } - inline bool tryobtain_mutex() { return ::WaitForSingleObject(m_hndMutex,0) == WAIT_OBJECT_0; } - inline void release_mutex() { ::ReleaseMutex(m_hndMutex); } - //------------------------------------------------ -#endif // OS switch - }; - - void ThreadConditionSignal::obtain_mutex() - { - m_osdepobj.obtain_mutex(); - } - bool ThreadConditionSignal::tryobtain_mutex() { return m_osdepobj.tryobtain_mutex(); } - void ThreadConditionSignal::release_mutex() - { - m_osdepobj.release_mutex(); - } - - void ThreadConditionSignal::await_condition() { m_osdepobj.await_signal(); } - bool ThreadConditionSignal::await_condition(timediff tdTimeout) { return m_osdepobj.await_signal(tdTimeout); } - void ThreadConditionSignal::signal_condition_single() { m_osdepobj.signal_unicast(); } - void ThreadConditionSignal::signal_condition_broadcast() { m_osdepobj.signal_broadcast(); } - - ThreadConditionSignal::ThreadConditionSignal() : m_osdepobj(*new OSDependentObject) {} - ThreadConditionSignal::~ThreadConditionSignal() { delete &m_osdepobj; } - - - - - - - - -#if XPLATFORMTHREADS_POSIX - namespace // anon - { - inline int max_FIFO_schedparam() - { - static const int max_priority = ::sched_get_priority_max(SCHED_FIFO); - return max_priority; - } - inline int schedparam_by_percentage(unsigned short percentage) - { - return (max_FIFO_schedparam()*10*percentage+500)/1000; - } - class POSIXThreadPriority - { - public: - int m_SchedPolicy; - int m_SchedPriority; - POSIXThreadPriority(ThreadPriority pri) - { - switch (pri) - { - case ThreadPriority::TimeCritical: m_SchedPolicy=SCHED_FIFO, m_SchedPriority=schedparam_by_percentage(80); break; - case ThreadPriority::AboveNormal: m_SchedPolicy=SCHED_FIFO, m_SchedPriority=schedparam_by_percentage(20); break; - case ThreadPriority::BelowNormal: // fall through to normal; nothing is below normal in POSIX - case ThreadPriority::Normal: // fall through to default - default: m_SchedPolicy=SCHED_OTHER, m_SchedPriority=0; break; - } - } - }; - - } // namespace anonymous -#endif // XPLATFORMTHREADS_POSIX - -#if XPLATFORMTHREADS_WINDOWS - namespace // anon - { - inline int WinThreadPriority(ThreadPriority pri) - { - switch (pri) - { - case ThreadPriority::BelowNormal: return THREAD_PRIORITY_BELOW_NORMAL; - case ThreadPriority::AboveNormal: return THREAD_PRIORITY_ABOVE_NORMAL; - case ThreadPriority::TimeCritical: return THREAD_PRIORITY_TIME_CRITICAL; - case ThreadPriority::Normal: // fall through to default - default: return THREAD_PRIORITY_NORMAL; - } - } - } // namespace anon -#endif // XPLATFORMTHREADS_WINDOWS - - - - void SetMyThreadPriority(ThreadPriority pri) - { -#if XPLATFORMTHREADS_WINDOWS - ::SetThreadPriority(::GetCurrentThread(), WinThreadPriority(pri)); -#endif // XPLATFORMTHREADS_WINDOWS -#if XPLATFORMTHREADS_POSIX - const POSIXThreadPriority posixpri(pri); - sched_param sparam; - ::memset(&sparam, 0, sizeof(sparam)); - sparam.sched_priority = posixpri.m_SchedPriority; -#if defined(__linux__) - ::sched_setscheduler(0, posixpri.m_SchedPolicy, &sparam); // linux uses this function instead of pthread_ -#else - pthread_setschedparam(pthread_self(), posixpri.m_SchedPolicy, &sparam); -#endif -#endif // XPLATFORMTHREADS_POSIX - } - - - struct ThreadWrapperData - { - ThreadFunction *func; - ThreadFunctionArgument arg; - }; - -#if XPLATFORMTHREADS_WINDOWS - static unsigned int __stdcall ThreadWrapper(void * arg) - { - register ThreadWrapperData *twd = reinterpret_cast(arg); - ThreadFunction *func=twd->func; - ThreadFunctionArgument farg=twd->arg; - delete twd; - return DWORD(func(farg)); - } -#elif XPLATFORMTHREADS_POSIX - static void * ThreadWrapper(void *arg) - { - register ThreadWrapperData *twd = reinterpret_cast(arg); - ThreadFunction *func=twd->func; - ThreadFunctionArgument farg=twd->arg; - delete twd; - return reinterpret_cast(func(farg)); - } - typedef void*(ThreadWrapperFunction)(void*); - - static ThreadWrapperFunction *ThunkedThreadWrapper = ThreadWrapper; - -#endif // OS switch - - - - - - class ThreadHandle::OSDependent - { - public: - static void StartThread(ThreadWrapperData *, ThreadHandle &, ThreadPriority); - static bool KillThread(ThreadHandle); - static bool JoinThread(ThreadHandle, ThreadFunctionReturnType*); - static void Close(ThreadHandle); -#if XPLATFORMTHREADS_WINDOWS - static inline uintptr_t from_oshandle(HANDLE h) { return reinterpret_cast(h); } - static inline HANDLE to_oshandle(uintptr_t h) { return reinterpret_cast(h); } -#elif XPLATFORMTHREADS_POSIX - static inline uintptr_t from_oshandle(pthread_t pt) { return uintptr_t(pt); } - static inline pthread_t to_oshandle(uintptr_t h) { return pthread_t(h); } -#endif // OS switch - }; - -#if XPLATFORMTHREADS_WINDOWS - const ThreadHandle ThreadHandle::Invalid(OSDependent::from_oshandle(INVALID_HANDLE_VALUE)); -#elif XPLATFORMTHREADS_POSIX - const ThreadHandle ThreadHandle::Invalid(OSDependent::from_oshandle(0)); -#endif // OS switch - - inline void ThreadHandle::OSDependent::StartThread(ThreadWrapperData *ptwdata, ThreadHandle &th, ThreadPriority pri) - { -#if XPLATFORMTHREADS_WINDOWS - uintptr_t h = ::_beginthreadex( - 0, // no security attributes, not inheritable - 0, // default stack size - ThreadWrapper, // function to call - (void*)(ptwdata), // argument for function - 0, // creation flags - 0 // where to store thread ID - ); - - if (h) - { - th.m_oshandle = h; - if (pri!=ThreadPriority::Normal) - ::SetThreadPriority(to_oshandle(h), WinThreadPriority(pri)); - } - else - th=Invalid; -#elif XPLATFORMTHREADS_POSIX - pthread_attr_t my_thread_attr, *pmy_thread_attr = 0; - sched_param my_schedparam; - - if (pri!=ThreadPriority::Normal) - { - pmy_thread_attr = &my_thread_attr; - - const POSIXThreadPriority posixpriority(pri); - int result; - result = pthread_attr_init (pmy_thread_attr); - result = pthread_attr_setschedpolicy(pmy_thread_attr, posixpriority.m_SchedPolicy); - - memset(&my_schedparam, 0, sizeof(my_schedparam)); - my_schedparam.sched_priority = posixpriority.m_SchedPriority; - result = pthread_attr_setschedparam(pmy_thread_attr, &my_schedparam); - } - - pthread_t pt; - int anyerr = pthread_create( - &pt, // variable for thread handle - pmy_thread_attr, // default attributes - ThunkedThreadWrapper, - ptwdata - ); - - if (anyerr) - th=Invalid; - else - th.m_oshandle = OSDependent::from_oshandle(pt); -#endif - } - - inline bool ThreadHandle::OSDependent::KillThread(ThreadHandle h) - { -#if XPLATFORMTHREADS_WINDOWS - return ::TerminateThread(to_oshandle(h.m_oshandle), (DWORD)-1) != 0; -#elif XPLATFORMTHREADS_POSIX - return pthread_cancel(to_oshandle(h.m_oshandle)) == 0; -#endif - } - - bool ThreadHandle::OSDependent::JoinThread(ThreadHandle h, ThreadFunctionReturnType *pretval) - { -#if XPLATFORMTHREADS_WINDOWS - const bool kbReturnedOk = (WAIT_OBJECT_0 == ::WaitForSingleObject(OSDependent::to_oshandle(h.m_oshandle), INFINITE)); - if (kbReturnedOk && pretval) - { - DWORD dwExitCode; - ::GetExitCodeThread(to_oshandle(h.m_oshandle), &dwExitCode); - *pretval = (ThreadFunctionReturnType)(dwExitCode); - } - return kbReturnedOk; -#endif -#if XPLATFORMTHREADS_POSIX - ThreadFunctionReturnType ptrExitCode = 0; - int join_return_code = pthread_join(to_oshandle(h.m_oshandle), (void**)ptrExitCode); - const bool kbReturnedOk = (0 == join_return_code); - if (0 != pretval) - { - *pretval = ptrExitCode; - } - return kbReturnedOk; -#endif - } - -#if XPLATFORMTHREADS_WINDOWS - inline void ThreadHandle::OSDependent::Close(ThreadHandle h) - { - ::CloseHandle(OSDependent::to_oshandle(h.m_oshandle)); - } -#endif // XPLATFORMTHREADS_WINDOWS -#if XPLATFORMTHREADS_POSIX - inline void ThreadHandle::OSDependent::Close(ThreadHandle) {} -#endif // XPLATFORMTHREADS_POSIX - - //********************************************************************************************** - - class WCThreadRef::OSDependent - { - public: - static void GetCurrentThreadRef(WCThreadRef& tid); -#if XPLATFORMTHREADS_WINDOWS - static inline uintptr_t from_os(DWORD thread_id) { return (uintptr_t)(thread_id); } - static inline DWORD to_os(uintptr_t thread_id) { return (DWORD)(thread_id); } -#elif XPLATFORMTHREADS_POSIX - static inline uintptr_t from_os(pthread_t thread_id) { return (uintptr_t)(thread_id); } - static inline pthread_t to_os(uintptr_t thread_id) { return pthread_t(thread_id); } -#endif // OS switch - }; - - //********************************************************************************************** - inline void WCThreadRef::OSDependent::GetCurrentThreadRef(WCThreadRef& tid) - { -#if XPLATFORMTHREADS_WINDOWS - DWORD thread_id = ::GetCurrentThreadId(); - tid.m_osThreadRef = OSDependent::from_os(thread_id); - -#elif XPLATFORMTHREADS_POSIX - pthread_t thread_id = ::pthread_self(); - tid.m_osThreadRef = OSDependent::from_os(thread_id); - -#endif // OS switch - } - - //********************************************************************************************** - - ThreadHandle StartThread(ThreadFunction func, ThreadFunctionArgument arg, ThreadPriority thpri) - { - EnsureThreadingInitialized(); - ThreadWrapperData *ptwdata = new ThreadWrapperData; - ptwdata->func = func; - ptwdata->arg = arg; - ThreadHandle thToReturn; - ThreadHandle::OSDependent::StartThread(ptwdata, thToReturn, thpri); - return thToReturn; - } - - bool KillThread(ThreadHandle h) - { - EnsureThreadingInitialized(); - return ThreadHandle::OSDependent::KillThread(h); - } - - bool JoinThread(ThreadHandle h, ThreadFunctionReturnType *pretval) - { - EnsureThreadingInitialized(); - return ThreadHandle::OSDependent::JoinThread(h, pretval); - } - - void Close(ThreadHandle h) - { - EnsureThreadingInitialized(); - return ThreadHandle::OSDependent::Close(h); - } - - //******************************************************************************************* - - WCThreadRef GetCurrentThreadRef() - { - EnsureThreadingInitialized(); // Is it necessary? - WCThreadRef tRefToReturn; - WCThreadRef::OSDependent::GetCurrentThreadRef(tRefToReturn); - return tRefToReturn; - } - - //******************************************************************************************* - - bool IsThreadExists(const WCThreadRef& threadRef) - { -#if XPLATFORMTHREADS_WINDOWS - DWORD dwThreadId = WCThreadRef::OSDependent::to_os((uintptr_t)threadRef); - HANDLE handle = ::OpenThread(SYNCHRONIZE, // dwDesiredAccess - use of the thread handle in any of the wait functions - FALSE, // bInheritHandle - processes do not inherit this handle - dwThreadId); - - // Now we have the handle, check if the associated thread exists: - DWORD retVal = WaitForSingleObject(handle, 0); - if (retVal == WAIT_FAILED) - return false; // the thread does not exists - else - return true; // the thread exists - -#elif XPLATFORMTHREADS_POSIX - pthread_t pthreadRef = WCThreadRef::OSDependent::to_os((uintptr_t)threadRef); - int retVal = pthread_kill(pthreadRef, 0); // send a signal to the thread, but do nothing - if (retVal == ESRCH) - return false; // the thread does not exists - else - return true; // the thread exists - -#endif // OS switch - } - - //******************************************************************************************* - - bool operator==(const WCThreadRef& first, const WCThreadRef& second) - { - return (first.m_osThreadRef == second.m_osThreadRef); - } - - bool operator!=(const WCThreadRef& first, const WCThreadRef& second) - { - return (first.m_osThreadRef != second.m_osThreadRef); - } - - bool operator<(const WCThreadRef& first, const WCThreadRef& second) - { - return (first.m_osThreadRef < second.m_osThreadRef); - } - - bool operator>(const WCThreadRef& first, const WCThreadRef& second) - { - return (first.m_osThreadRef > second.m_osThreadRef); - } - - bool WCAtomicLock::obtain(const uint32_t in_num_trys) - { - bool retVal = false; - - uint32_t timeOut = in_num_trys; - while (true) - { - retVal = g_atomic_int_compare_and_exchange(&m_the_lock, gint(0), gint(1)); - if (retVal) - { - break; - } - else - { - if (--timeOut == 0) - { - break; - } - sleep_milliseconds(1000); - } - } - - return retVal; - } - - void WCAtomicLock::release() - { - m_the_lock = 0; - } - -} // namespace wvThread -} // namespace wvNS { - diff --git a/libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.h b/libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.h deleted file mode 100644 index eb8d91c696..0000000000 --- a/libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.h +++ /dev/null @@ -1,411 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __WCThreadSafe_h_ - #define __WCThreadSafe_h_ - -/* Copy to include -#include "Threads/WCThreadSafe.h" -*/ - -// -// * WCThreadSafe.h (used to be called XPlatformOSServices.hpp) -// * -// * Consistent C++ interfaces to common Operating System services. -// * -// * -// * -// * -// * Created 2004-December-13 by Udi Barzilai as XPlatformOSServices.hpp -// * Moved to WCThreadSafe.h by Shai 26/10/2005 -// * 26/10/2005: ThreadMutex now inhetites from ThreadMutexInited -// * namespace changed to wvThread - -#include "WavesPublicAPI/wstdint.h" -#include - -#include "BasicTypes/WUDefines.h" - -#if defined(__linux__) || defined(__APPLE__) - #define XPLATFORMOSSERVICES_UNIX 1 -#endif - -#if defined(_WIN32) - #define XPLATFORMOSSERVICES_WIN32 1 -#endif - -#if XPLATFORMOSSERVICES_WIN32 - #define XPLATFORMTHREADS_WINDOWS 1 -#elif XPLATFORMOSSERVICES_UNIX - #define XPLATFORMTHREADS_POSIX 1 -#endif -namespace wvNS { -typedef uint32_t WTThreadSafetyType; -const WTThreadSafetyType kNoThreadSafetyNeeded = 0; -const WTThreadSafetyType kpthreadsmutexThreadSafety = 1; - - -namespace wvThread -{ - //#include "BasicTypes/WavesAPISetAligment.h" - //Packing affects the layout of classes, and commonly, if packing changes across header files, there can be problems. -#ifdef PLATFORM_WINDOWS -#pragma pack(push) -#pragma pack(8) -#endif - -#ifdef __APPLE__ -#ifdef __GNUC__ -#pragma pack(push, 8) -#endif -#endif - - //-------------------------------------------------------- - typedef int32_t timediff; // in microseconds - static const timediff ktdOneSecond = 1000*1000; - //-------------------------------------------------------- - class timestamp - { - protected: - typedef uint32_t tickcount; - tickcount m_nMicroseconds; // may wrap around - static const tickcount ms_knWraparoundThreshold = ~tickcount(0) ^ (~tickcount(0)>>1); // half the range - - public: - timestamp() : m_nMicroseconds(0) { /* uninitialized */ } - timestamp(const timestamp &_ts) : m_nMicroseconds(_ts.m_nMicroseconds) {} - timestamp &operator=(const timestamp &_rhs) { m_nMicroseconds = _rhs.m_nMicroseconds; return *this; } - explicit timestamp(tickcount _i) : m_nMicroseconds(_i) {} - uint32_t ticks() const { return m_nMicroseconds; } - timediff operator-(timestamp _rhs) const { return timediff(m_nMicroseconds-_rhs.m_nMicroseconds); } - timestamp & operator+=(timediff _t) { m_nMicroseconds+=_t; return *this; } - timestamp & operator-=(timediff _t) { m_nMicroseconds-=_t; return *this; } - timestamp operator+(timediff _t) const { return timestamp(m_nMicroseconds+_t); } - timestamp operator-(timediff _t) const { return timestamp(m_nMicroseconds-_t); } - bool operator==(timestamp _rhs) const { return m_nMicroseconds==_rhs.m_nMicroseconds; } - bool operator!=(timestamp _rhs) const { return m_nMicroseconds!=_rhs.m_nMicroseconds; } - bool operator< (timestamp _rhs) const { return m_nMicroseconds-_rhs.m_nMicroseconds >= ms_knWraparoundThreshold; } - static timestamp null() { return timestamp(0); } - bool is_null() const { return m_nMicroseconds==0; } - }; - //-------------------------------------------------------- -#ifdef __APPLE__ - bool FindNetInterfaceByIPAddress(const char *sIP, char *sInterface); -#endif // MACOS - //-------------------------------------------------------- - timestamp now(); - //-------------------------------------------------------- - DllExport void sleep(timediff); - DllExport void sleep_milliseconds(unsigned int nMillisecs); - //-------------------------------------------------------- - void yield(); - //-------------------------------------------------------- - - - - typedef uintptr_t os_dependent_handle_type; - - //-------------------------------------------------------- - typedef int ThreadFunctionReturnType; - typedef void * ThreadFunctionArgument; - //-------------------------------------------------------- - typedef ThreadFunctionReturnType (ThreadFunction)(ThreadFunctionArgument); - //-------------------------------------------------------- - class ThreadHandle - { - public: - class OSDependent; - protected: - uintptr_t m_oshandle; // hopefully this is good enough for all systems - public: - static const ThreadHandle Invalid; - protected: - ThreadHandle(uintptr_t n) : m_oshandle(n) {} - public: - ThreadHandle() : m_oshandle(Invalid.m_oshandle) {} - bool is_invalid() const { return !m_oshandle || m_oshandle==Invalid.m_oshandle; } - }; - //-------------------------------------------------------- - class ThreadPriority - { - public: enum value { BelowNormal=1, Normal=2, AboveNormal=3, TimeCritical=4 }; - protected: value m_value; - public: ThreadPriority(value v) : m_value(v) {} - public: operator value() const { return m_value; } - }; - //-------------------------------------------------------- - void SetMyThreadPriority(ThreadPriority); - //-------------------------------------------------------- - ThreadHandle StartThread(ThreadFunction, ThreadFunctionArgument, ThreadPriority=ThreadPriority::Normal); - bool JoinThread(ThreadHandle, ThreadFunctionReturnType * = 0); - bool KillThread(ThreadHandle); // use only for abnormal termination - void Close(ThreadHandle); // should be called once for every handle obtained from StartThread. - //-------------------------------------------------------- - - - - - //-------------------------------------------------------- - class DllExport noncopyableobject - { - protected: - noncopyableobject() {} - private: - noncopyableobject(const noncopyableobject &); - noncopyableobject & operator=(const noncopyableobject &); - }; - //-------------------------------------------------------- - - - //-------------------------------------------------------- - // Thread Mutex class that needs to be explicitly initialized - class DllExport ThreadMutexInited : public noncopyableobject - { - protected: - class OSDependentMutex; - OSDependentMutex* m_osdmutex; - - public: - ThreadMutexInited(); - ~ThreadMutexInited(); - - void init(); - void uninit(); - inline bool is_init() { return 0 != m_osdmutex; } - void obtain(); - bool tryobtain(); - void release(); - - private: - ThreadMutexInited(const ThreadMutexInited&); // cannot be copied - ThreadMutexInited& operator=(const ThreadMutexInited&); // cannot be copied - - public: - class lock : public noncopyableobject - { - protected: - ThreadMutexInited &m_mutex; - public: - inline lock(ThreadMutexInited &mtx) : m_mutex(mtx) { m_mutex.obtain(); } - inline ~lock() { m_mutex.release(); } - }; - class trylock : public noncopyableobject - { - protected: - ThreadMutexInited &m_mutex; - bool m_bObtained; - public: - inline trylock(ThreadMutexInited &mtx) : m_mutex(mtx), m_bObtained(false) { m_bObtained = m_mutex.tryobtain(); } - inline ~trylock() { if (m_bObtained) m_mutex.release(); } - inline operator bool() const { return m_bObtained; } - }; - }; - //-------------------------------------------------------- - - // Thread Mutex class that is automatically initialized - class ThreadMutex : public ThreadMutexInited - { - public: - ThreadMutex() {init();} - }; - - //-------------------------------------------------------- - class DllExport ThreadConditionSignal : public noncopyableobject - { - protected: - class OSDependentObject; - OSDependentObject &m_osdepobj; - - protected: - void obtain_mutex(); - bool tryobtain_mutex(); - void release_mutex(); - - public: - class lock : public noncopyableobject - { - protected: - ThreadConditionSignal &m_tcs; - public: - lock(ThreadConditionSignal &tcs) : m_tcs(tcs) { m_tcs.obtain_mutex(); } - ~lock() { m_tcs.release_mutex(); } - }; - class trylock : public noncopyableobject - { - protected: - ThreadConditionSignal &m_tcs; - bool m_bObtained; - public: - trylock(ThreadConditionSignal &tcs) : m_tcs(tcs), m_bObtained(false) { m_bObtained = m_tcs.tryobtain_mutex(); } - ~trylock() { if (m_bObtained) m_tcs.release_mutex(); } - operator bool() const { return m_bObtained; } - }; - - public: - ThreadConditionSignal(); - ~ThreadConditionSignal(); - - // IMPORTANT: All of the functions below MUST be called ONLY while holding a lock for this object !!! - void await_condition(); - bool await_condition(timediff tdTimeout); - void signal_condition_single(); - void signal_condition_broadcast(); - }; - //-------------------------------------------------------- - - - - - - //-------------------------------------------------------- - // A doorbell is a simple communication mechanism that allows - // one thread two wake another when there is some work to be done. - // The signal is 'clear on read'. This class is not intended for - // multi-way communication (i.e. more than two threads). -//#define XPLATFORMTHREADS_DOORBELL_INLINE_USING_COND_VAR (!XPLATFORMTHREADS_WINDOWS && !XPLATFORMOSSERVICES_MACOS) -#ifdef XPLATFORMTHREADS_DOORBELL_INLINE_USING_COND_VAR -#undef XPLATFORMTHREADS_DOORBELL_INLINE_USING_COND_VAR -#endif -#define XPLATFORMTHREADS_DOORBELL_INLINE_USING_COND_VAR 1 -#if XPLATFORMTHREADS_DOORBELL_INLINE_USING_COND_VAR - class doorbell_type - { - protected: - ThreadConditionSignal m_signal; - bool m_rang; - protected: - template bool wait_for_ring_internal(timediff timeout) - {// mutex - ThreadConditionSignal::lock guard(m_signal); - if (!m_rang) - { - if (wait_forever) - { - m_signal.await_condition(); - } - else - { - m_signal.await_condition(timeout); - } - } - const bool rang = m_rang; - m_rang = false; - return rang; - }// mutex - - public: - doorbell_type() : m_rang(false) {} - inline ~doorbell_type() {} - inline void ring() - {// mutex - ThreadConditionSignal::lock guard(m_signal); - m_rang = true; - m_signal.signal_condition_single(); - }// mutex - inline bool wait_for_ring() { return wait_for_ring_internal(0); } - inline bool wait_for_ring(timediff timeout) { return wait_for_ring_internal(timeout); } - }; -#else - class doorbell_type : public noncopyableobject - { - protected: - os_dependent_handle_type m_os_dependent_handle; - protected: - template bool wait_for_ring_internal(timediff); - public: - doorbell_type(); - ~doorbell_type(); - void ring(); - bool wait_for_ring(); - bool wait_for_ring(timediff timeout); - }; -#endif // XPLATFORMTHREADS_DOORBELL_INLINE_USING_COND_VAR - //-------------------------------------------------------- - - //--------------------------------------------------------------- - class DllExport WCThreadRef // Class which holds the threadRef, DWORD in Windows and pthread_t in POSIX (Mac, Unix) - { - public: - class OSDependent; // the class which contains the OS Dependent implementation - - WCThreadRef() : m_osThreadRef(0) {} - bool is_invalid() const { return m_osThreadRef == 0;} - - operator uintptr_t() const {return m_osThreadRef;} - - protected: - uintptr_t m_osThreadRef; - WCThreadRef(uintptr_t n) : m_osThreadRef(n) {} - - friend DllExport bool operator==(const WCThreadRef& first, const WCThreadRef& second); - friend DllExport bool operator!=(const WCThreadRef& first, const WCThreadRef& second); - friend DllExport bool operator<(const WCThreadRef& first, const WCThreadRef& second); - friend DllExport bool operator>(const WCThreadRef& first, const WCThreadRef& second); - }; - - DllExport WCThreadRef GetCurrentThreadRef(); // getting the current thread reference - cross-platform implemented - bool IsThreadExists(const WCThreadRef& threadRef); // correct to the very snapshot of time of execution - - //--------------------------------------------------------------- - - class DllExport WCAtomicLock - { - public: - WCAtomicLock() : m_the_lock(0) {} - bool obtain(const uint32_t in_num_trys = 1); - void release(); - private: - int32_t m_the_lock; - }; - - //#include "BasicTypes/WavesAPIResetAligment.h" -#ifdef PLATFORM_WINDOWS -#pragma pack(pop) -#endif - -#ifdef __APPLE__ -#ifdef __GNUC__ -#pragma pack(pop) -#endif -#endif - -class WCStThreadMutexLocker -{ -public: - WCStThreadMutexLocker(wvNS::wvThread::ThreadMutexInited& in_mutex) : - m_mutex(in_mutex) - { - m_mutex.obtain(); - } - - ~WCStThreadMutexLocker() - { - m_mutex.release(); - } -protected: - wvNS::wvThread::ThreadMutexInited& m_mutex; - WCStThreadMutexLocker(const WCStThreadMutexLocker&); - WCStThreadMutexLocker& operator=(const WCStThreadMutexLocker&); -}; - -} // namespace wvThread - - -} //namespace wvNS { -#endif // #ifndef __WCThreadSafe_h_ diff --git a/libs/backends/wavesaudio/wavesapi/WavesPublicAPI/1.0/WavesPublicAPI_Defines.h b/libs/backends/wavesaudio/wavesapi/WavesPublicAPI/1.0/WavesPublicAPI_Defines.h deleted file mode 100644 index 24bfb10573..0000000000 --- a/libs/backends/wavesaudio/wavesapi/WavesPublicAPI/1.0/WavesPublicAPI_Defines.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __WavesPublicAPI_Defines_h__ - #define __WavesPublicAPI_Defines_h__ - -/*Copy to include -#include "WavesPublicAPI_Defines.h" -*/ - -#ifdef __APPLE__ - - #ifdef __GNUC__ - #define WPAPI_DllExport __attribute__ ((visibility("default"))) - #define __WPAPI_CDECL - #define __WPAPI_STDCALL - - #else - - #define WPAPI_DllExport __declspec(export) - #define __WPAPI_CDECL - #define __WPAPI_STDCALL - - #endif - -#endif - - -#ifdef PLATFORM_WINDOWS - #define WPAPI_DllExport __declspec(dllexport) - #define __WPAPI_CDECL __cdecl - #define __WPAPI_STDCALL __stdcall -#endif - -#ifdef __linux__ - - #define WPAPI_DllExport __attribute__ ((visibility("default"))) - - #define __WPAPI_CDECL - #define __WPAPI_STDCALL - -#endif - -#endif //__WavesPublicAPI_Defines_h__ diff --git a/libs/backends/wavesaudio/wavesapi/WavesPublicAPI/WTErr.h b/libs/backends/wavesaudio/wavesapi/WavesPublicAPI/WTErr.h deleted file mode 100644 index 451369db6f..0000000000 --- a/libs/backends/wavesaudio/wavesapi/WavesPublicAPI/WTErr.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -// \file WTErr.h, defines basic error type and "No Error" code -// All users may use their own error codes with this type, as long as eNoErr remains defined here -/////////////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef __WTErr_h__ -#define __WTErr_h__ - -/* Copy to include: -#include "WavesPublicAPI/WTErr.h" -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "WavesPublicAPI/wstdint.h" - -typedef int32_t WTErr; // Waves Type Error -const WTErr eNoErr = 0; - - -#ifdef __cplusplus -} //extern "C" { -#endif - -#endif // __WTErr_h__ - diff --git a/libs/backends/wavesaudio/wavesapi/WavesPublicAPI/wstdint.h b/libs/backends/wavesaudio/wavesapi/WavesPublicAPI/wstdint.h deleted file mode 100644 index 46869c40ae..0000000000 --- a/libs/backends/wavesaudio/wavesapi/WavesPublicAPI/wstdint.h +++ /dev/null @@ -1,367 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __stdint_h__ -#define __stdint_h__ - -/* Copy to include -#include "wstdint.h" -*/ - - -#ifdef __APPLE__ - #include - #include // Mac has this file in /usr/includez -#endif -#ifdef __linux__ - #if ! defined(__STDC_LIMIT_MACROS) - #define __STDC_LIMIT_MACROS - #endif - - #include - #include -#endif - -#if (defined (PLATFORM_WINDOWS) || defined(WIN32) || defined(WIN64)) -#if (_MSC_VER > 1600) || defined(__MINGW64__) || defined(__MINGW32__) - // Taken from MSDN official page: - // In Visual Studio 2010 _MSC_VER is defined as 1600, In Visual Studio 2012 _MSC_VER is defined as 1700. - #include -#else -#ifndef _STDINT_H - #define _STDINT_H // this will prevent Altura's CGBase.h from defining int32_t -#endif -/* - * ISO C 99 for platforms that lack it. - * - */ - -/* Get wchar_t, WCHAR_MIN, WCHAR_MAX. */ -#include -/* Get CHAR_BIT, LONG_MIN, LONG_MAX, ULONG_MAX. */ -#include - -/* Get those types that are already defined in other system include files. */ -#if defined(__FreeBSD__) -# include -#endif - -#if defined(__sun) && HAVE_SYS_INTTYPES_H -# include - /* Solaris 7 has the types except the *_fast*_t types, and - the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. - But note that contains only the type definitions! */ -# define HAVE_SYSTEM_INTTYPES -#endif -#if (defined(__hpux) || defined(_AIX)) && HAVE_INTTYPES_H -# include - /* HP-UX 10 has nearly everything, except UINT_LEAST8_MAX, - UINT_FAST8_MAX, PTRDIFF_MIN, PTRDIFF_MAX. */ - /* AIX 4 has nearly everything, except INTPTR_MIN, INTPTR_MAX, - UINTPTR_MAX, PTRDIFF_MIN, PTRDIFF_MAX. */ -# define HAVE_SYSTEM_INTTYPES -#endif -#if !(defined(UNIX_CYGWIN32) && defined(__BIT_TYPES_DEFINED__)) -# define NEED_SIGNED_INT_TYPES -#endif - -#if !defined(HAVE_SYSTEM_INTTYPES) - -/* 7.18.1.1. Exact-width integer types */ -#if !defined(__FreeBSD__) - -#if defined(_MSC_VER) -#ifndef __int8_t_defined -#define __int8_t_defined -typedef __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#endif - -#else // _MSC_VER - -#ifdef NEED_SIGNED_INT_TYPES -typedef signed char int8_t; -#endif -typedef unsigned char uint8_t; - -#ifdef NEED_SIGNED_INT_TYPES -typedef short int16_t; -#endif -typedef unsigned short uint16_t; - -#ifdef NEED_SIGNED_INT_TYPES -typedef int int32_t; -#endif -typedef unsigned int uint32_t; - -#if 0 -#ifdef NEED_SIGNED_INT_TYPES -typedef long int64_t; -#endif -typedef unsigned long uint64_t; -#elif 0 -#ifdef NEED_SIGNED_INT_TYPES -typedef long long int64_t; -#endif -typedef unsigned long long uint64_t; -#endif - -#endif // _MSC_VER - -#endif /* !FreeBSD */ - -/* 7.18.1.2. Minimum-width integer types */ - -typedef int8_t int_least8_t; -typedef uint8_t uint_least8_t; -typedef int16_t int_least16_t; -typedef uint16_t uint_least16_t; -#if !defined(kAlturaAlreadyDefinesInt32) -typedef int32_t int_least32_t; -#endif -typedef uint32_t uint_least32_t; -typedef int64_t int_least64_t; -typedef uint64_t uint_least64_t; - - -/* 7.18.1.3. Fastest minimum-width integer types */ - -#ifndef _STDINT_H -typedef int32_t int_fast8_t; -typedef uint32_t uint_fast8_t; -typedef int32_t int_fast16_t; -typedef uint32_t uint_fast16_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast32_t; -typedef int64_t int_fast64_t; -typedef uint64_t uint_fast64_t; -#endif - - -/* 7.18.1.4. Integer types capable of holding object pointers */ - -#if !defined(__FreeBSD__) - -/* On some platforms (like IRIX6 MIPS with -n32) sizeof(void*) < sizeof(long), - but this doesn't matter here. */ -#if !defined(_INTPTR_T_DEFINED) -typedef long intptr_t; -#define _INTPTR_T_DEFINED -#endif -#if !defined(_UINTPTR_T_DEFINED) -typedef unsigned long uintptr_t; -#define _UINTPTR_T_DEFINED -#endif - -#endif /* !FreeBSD */ - -/* 7.18.1.5. Greatest-width integer types */ - - -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; -#if 0 || 0 -typedef int32_t intmax_t; -typedef uint32_t uintmax_t; -#endif - -/* 7.18.2. Limits of specified-width integer types */ - -//#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) - -/* 7.18.2.1. Limits of exact-width integer types */ - -#ifndef _STDINT_H - -#define INT8_MIN -128 -#define INT8_MAX 127 -#define UINT8_MAX 255U -#define INT16_MIN -32768 -#define INT16_MAX 32767 -#define UINT16_MAX 65535U -#define INT32_MIN (~INT32_MAX) -#define INT32_MAX 2147483647 -#define UINT32_MAX 4294967295U -#if 0 -#define INT64_MIN (~INT64_MIN) -#define INT64_MAX 9223372036854775807L -#define UINT64_MAX 18446744073709551615UL -#elif 0 -#define INT64_MIN (~INT64_MIN) -#define INT64_MAX 9223372036854775807LL -#define UINT64_MAX 18446744073709551615ULL -#endif - -/* 7.18.2.2. Limits of minimum-width integer types */ - -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#if 0 || 0 -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST64_MAX UINT64_MAX -#endif - -/* 7.18.2.3. Limits of fastest minimum-width integer types */ - -#define INT_FAST8_MIN INT32_MIN -#define INT_FAST8_MAX INT32_MAX -#define UINT_FAST8_MAX UINT32_MAX -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST16_MAX INT32_MAX -#define UINT_FAST16_MAX UINT32_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define UINT_FAST32_MAX UINT32_MAX -#if 0 || 0 -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST64_MAX UINT64_MAX -#endif - -/* 7.18.2.4. Limits of integer types capable of holding object pointers */ - -#define INTPTR_MIN LONG_MIN -#define INTPTR_MAX LONG_MAX -#define UINTPTR_MAX ULONG_MAX - -/* 7.18.2.5. Limits of greatest-width integer types */ - -#if 0 || 0 -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX -#else -#define INTMAX_MIN INT32_MIN -#define INTMAX_MAX INT32_MAX -#define UINTMAX_MAX UINT32_MAX -#endif - -/* 7.18.3. Limits of other integer types */ - -#define PTRDIFF_MIN (~(ptrdiff_t)0 << (sizeof(ptrdiff_t)*CHAR_BIT-1)) -#define PTRDIFF_MAX (~PTRDIFF_MIN) - -/* This may be wrong... */ -#define SIG_ATOMIC_MIN 0 -#define SIG_ATOMIC_MAX 127 - -#endif /* _STDINT_H */ - -//#define SIZE_MAX (~(size_t)0) - -/* wchar_t limits already defined in . */ -/* wint_t limits already defined in . */ - -//#endif - -/* 7.18.4. Macros for integer constants */ - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) - -/* 7.18.4.1. Macros for minimum-width integer constants */ - -#ifdef INT8_C -#undef INT8_C -#endif -#define INT8_C(x) x - -#ifdef UINT8_C -#undef UINT8_C -#endif -#define UINT8_C(x) x##U - -#ifdef INT16_C -#undef INT16_C -#endif -#define INT16_C(x) x - -#ifdef UINT16_C -#undef UINT16_C -#endif -#define UINT16_C(x) x##U - -#ifdef INT32_C -#undef INT32_C -#endif -#define INT32_C(x) x - -#ifdef UINT32_C -#undef UINT32_C -#endif -#define UINT32_C(x) x##U - -// INT64_C and UINT64_C definitions -#ifdef INT64_C -#undef INT64_C -#endif -#ifdef UINT64_C -#undef UINT64_C -#endif -#if 0 -#define INT64_C(x) x##L -#define UINT64_C(x) x##UL -#elif 0 -#define INT64_C(x) x##LL -#define UINT64_C(x) x##ULL -#endif // #if 0 - -/* 7.18.4.2. Macros for greatest-width integer constants */ - -// INTMAX_C and UINTMAX_C definitions -#ifdef INTMAX_C -#undef INTMAX_C -#endif -#ifdef UINTMAX_C -#undef UINTMAX_C -#endif - -#if 0 -#define INTMAX_C(x) x##L -#define UINTMAX_C(x) x##UL -#elif 0 -#define INTMAX_C(x) x##LL -#define UINTMAX_C(x) x##ULL -#else -#define INTMAX_C(x) x -#define UINTMAX_C(x) x##U -#endif - -#endif - -#endif /* !HAVE_SYSTEM_INTTYPES */ - -#endif /* (_MSC_VER < 1400) */ - -#endif /* #ifdef PLATFORM_WINDOWS */ - -#endif /* __stdint_h__ */ diff --git a/libs/backends/wavesaudio/wavesapi/akupara/basics.hpp b/libs/backends/wavesaudio/wavesapi/akupara/basics.hpp deleted file mode 100644 index 33808ede8d..0000000000 --- a/libs/backends/wavesaudio/wavesapi/akupara/basics.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * basics.hpp - * Akupara - * - * Created by Udi on 12/19/06. - * Copyright 2006 __MyCompanyName__. All rights reserved. - * - */ -#if !defined(_AKUPARA_BASICS_HPP__INCLUDED_) -#define _AKUPARA_BASICS_HPP__INCLUDED_ - -#include "WavesPublicAPI/wstdint.h" - -namespace Akupara -{ - // The ultimate nothingness - // This is useful for writing constructors that nullify their object, and for testing nullness - struct null_type - { - null_type() {} - null_type(const null_type *) {} // this allows 0 to be implicitly converted to null_type - }; - inline null_type null() { return null_type(); } - - - // This is a byte, guaranteed to be unsigned regardless of your compiler's char signedness - typedef uint8_t byte_type; - - - // derive from this if your class needs to be noncopyable - class noncopyable_type - { - private: - noncopyable_type(const noncopyable_type &); - noncopyable_type &operator=(const noncopyable_type &); - public: - noncopyable_type() {} - }; - - -} // namespace Akupara - - -#if defined(__GNUC__) -#define AKUPARA_EXPECT_FALSE(x) __builtin_expect(x,false) -#define AKUPARA_EXPECT_TRUE(x) __builtin_expect(x,true ) -#else -#define AKUPARA_EXPECT_FALSE(x) x -#define AKUPARA_EXPECT_TRUE(x) x -#endif // __GNUC__ - - -#endif // _AKUPARA_BASICS_HPP__INCLUDED_ diff --git a/libs/backends/wavesaudio/wavesapi/akupara/compiletime_functions.hpp b/libs/backends/wavesaudio/wavesapi/akupara/compiletime_functions.hpp deleted file mode 100644 index 14c5f96523..0000000000 --- a/libs/backends/wavesaudio/wavesapi/akupara/compiletime_functions.hpp +++ /dev/null @@ -1,205 +0,0 @@ -/* -* compiletime_functions.hpp -* Akupara -* -* Created by Udi on 12/19/06. -* -*/ -#if !defined(_AKUPARA_COMPILETIME_FUNCTIONS_HPP__INCLUDED_) -#define _AKUPARA_COMPILETIME_FUNCTIONS_HPP__INCLUDED_ - -//#include "WavesPublicAPIs/wstdint.h" - -namespace Akupara -{ - // For templates that "return" a value, use template_name::value - // For templates that "return" a type, use template_name::type - - - // Integer log2 functions - //------------------------------------------------------------------------ - template - struct compiletime_bit_count_to_represent { static const unsigned int value = 1+compiletime_bit_count_to_represent<(n>>1)>::value; }; - - template<> - struct compiletime_bit_count_to_represent<0> { static const unsigned int value = 0; }; - //------------------------------------------------------------------------ - template - struct compiletime_log2_ceiling { static const unsigned int value=compiletime_bit_count_to_represent::value; }; - - template<> - struct compiletime_log2_ceiling<0> {}; // no value for 0 argument - //------------------------------------------------------------------------ - template - struct compiletime_log2_floor { static const unsigned int value=compiletime_bit_count_to_represent::value-1; }; - - template<> - struct compiletime_log2_floor<0> {}; // no value for 0 argument - //------------------------------------------------------------------------ - - - - // Assertion - accessing 'value' will generate a compile-time error if the argument evaluates to false - //------------------------------------------------------------------------ - template - struct compiletime_assert; - - template<> - struct compiletime_assert { static const bool value=true; }; - - template<> - struct compiletime_assert {}; // no value member for false assertion -> compile time error - //------------------------------------------------------------------------ - - - // Select type - selects one of two types based on a boolean - //------------------------------------------------------------------------ - template - struct compiletime_select_type; - - template - struct compiletime_select_type { typedef _true_type type; }; - - template - struct compiletime_select_type { typedef _false_type type; }; - //------------------------------------------------------------------------ - - - - - - // Integer types by byte count - //------------------------------------------------------------------------ - namespace detail - { - template - struct integer_with_byte_count_base; - - template<> - struct integer_with_byte_count_base<1,true> { typedef int8_t type; }; - - template<> - struct integer_with_byte_count_base<2,true> { typedef int16_t type; }; - - template<> - struct integer_with_byte_count_base<4,true> { typedef int32_t type; }; - - template<> - struct integer_with_byte_count_base<8,true> { typedef int64_t type; }; - - template<> - struct integer_with_byte_count_base<1,false> { typedef uint8_t type; }; - - template<> - struct integer_with_byte_count_base<2,false> { typedef uint16_t type; }; - - template<> - struct integer_with_byte_count_base<4,false> { typedef uint32_t type; }; - - template<> - struct integer_with_byte_count_base<8,false> { typedef uint64_t type; }; - } // namespace detail - //------------------------------------------------------------------------ - template - struct integer_with_byte_count : public detail::integer_with_byte_count_base<_size,_signed> - { - typedef typename detail::integer_with_byte_count_base<_size,_signed>::type type; // not required but makes the statement below less messy - static const bool s_correct_size = compiletime_assert::value; // if you get a compilation error here then integer_with_byte_count is not defined correctly - }; - //------------------------------------------------------------------------ - template - struct signed_integer_with_byte_count : public integer_with_byte_count<_size,true> {}; - - template - struct unsigned_integer_with_byte_count : public integer_with_byte_count<_size,false> {}; - //------------------------------------------------------------------------ - - - - // The following are TR1 compatible, until we get decent TR1 library support on all platforms - //------------------------------------------------------------------------ - template - struct integral_constant - { - static const _T value = _v; - typedef _T value_type; - typedef integral_constant<_T, _v> type; - }; // struct integral_constant - typedef integral_constant false_type; - typedef integral_constant true_type; - //------------------------------------------------------------------------ - template struct is_same : public false_type {}; - template struct is_same<_T,_T> : public true_type {}; - //------------------------------------------------------------------------ - - - - // These are NOT TR1 but make use of some TR1 stuff - //------------------------------------------------------------------------ - namespace detail - { - struct no_type; // if you end up getting this type, it means that you asked for something that doesn't exist - template struct signed_unsigned_pair; -#define AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(index, base_type_name) \ - template<> struct signed_unsigned_pair { typedef signed base_type_name signed_type; typedef unsigned base_type_name unsigned_type; }; -#define AKUPARA_SIGNED_UNSIGNED_FLOAT_PAIR(index, type_name) \ - template<> struct signed_unsigned_pair { typedef type_name signed_type; typedef no_type unsigned_type; }; - AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(1, char ) - AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(2, short ) - AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(3, int ) - - //AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(4, int32_t )// 64BitConversion - template<> - struct - signed_unsigned_pair<4> - { - typedef int32_t signed_type; - typedef uint32_t unsigned_type; - }; - - - AKUPARA_SIGNED_UNSIGNED_INTEGER_PAIR(5, long long) - AKUPARA_SIGNED_UNSIGNED_FLOAT_PAIR (6, float ) - AKUPARA_SIGNED_UNSIGNED_FLOAT_PAIR (7, double ) - AKUPARA_SIGNED_UNSIGNED_FLOAT_PAIR (8, long double) - const unsigned int k_signed_unsigned_pair_count = 8; - - // eliminate the no_type type - template struct filtered_type { typedef _T type; }; - template<> struct filtered_type {}; // no type defined - - // search for _T in signed type list - template struct find_in_signed_type_list_from_index - { - static const unsigned int value = is_same< _T, typename signed_unsigned_pair<_index>::signed_type >::value ? _index : find_in_signed_type_list_from_index<_index-1,_T>::value; - }; - template struct find_in_signed_type_list_from_index<0, _T> { static const unsigned int value = 0; }; - template struct find_in_signed_type_list : public find_in_signed_type_list_from_index {}; - - // search for _T in unsigned type list - template struct find_in_unsigned_type_list_from_index - { - static const unsigned int value = is_same< _T, typename signed_unsigned_pair<_index>::unsigned_type >::value ? _index : find_in_unsigned_type_list_from_index<_index-1,_T>::value; - }; - template struct find_in_unsigned_type_list_from_index<0, _T> { static const unsigned int value = 0; }; - template struct find_in_unsigned_type_list : public find_in_unsigned_type_list_from_index {}; - - template struct equivalent_signed_type; - template struct equivalent_signed_type { typedef _T type; }; - template struct equivalent_signed_type { typedef typename filtered_type< typename signed_unsigned_pair< find_in_unsigned_type_list<_T>::value >::signed_type >::type type; }; - - template struct equivalent_unsigned_type; - template struct equivalent_unsigned_type { typedef typename filtered_type< typename signed_unsigned_pair< find_in_signed_type_list<_T>::value >::unsigned_type >::type type; }; - template struct equivalent_unsigned_type { typedef _T type; }; - } // namespace detail - //------------------------------------------------------------------------ - template struct is_signed { static const bool value = detail::find_in_signed_type_list <_T>::value != 0; }; - template struct is_unsigned { static const bool value = detail::find_in_unsigned_type_list<_T>::value != 0; }; - //------------------------------------------------------------------------ - template struct equivalent_signed_type : public detail::equivalent_signed_type < is_signed<_T>::value, is_unsigned<_T>::value, _T > {}; - template struct equivalent_unsigned_type : public detail::equivalent_unsigned_type< is_signed<_T>::value, is_unsigned<_T>::value, _T > {}; - //------------------------------------------------------------------------ - -} // namespace Akupara - -#endif // _AKUPARA_COMPILETIME_FUNCTIONS_HPP__INCLUDED_ diff --git a/libs/backends/wavesaudio/wavesapi/akupara/threading/atomic_ops.hpp b/libs/backends/wavesaudio/wavesapi/akupara/threading/atomic_ops.hpp deleted file mode 100644 index 2111026d0b..0000000000 --- a/libs/backends/wavesaudio/wavesapi/akupara/threading/atomic_ops.hpp +++ /dev/null @@ -1,388 +0,0 @@ -/* -* Akupara/threading/atomic_ops.hpp -* -* -* Created by Udi Barzilai on 06/06. -* Copyright 2006 __MyCompanyName__. All rights reserved. -* -*/ -#if !defined(_AKUPARA_THREADING_ATOMIC_OPS_HPP__INCLUDED_) -#define _AKUPARA_THREADING_ATOMIC_OPS_HPP__INCLUDED_ - -#include "Akupara/basics.hpp" // for EXPECT macro -#include "Akupara/compiletime_functions.hpp" // for TR1 stuff, signed/unsigned stuff - -namespace Akupara -{ - namespace threading - { - namespace atomic - { - namespace machine - { - // Machine capabilities - // The following templates are specialized by the machine-specific headers to indicate - // the capabilities of the machine being compiled for. A true 'value' member for a given - // byte count means that there is an implementation of the corresponding atomic operation. - //------------------------------------- - template struct implements_load : public false_type {}; // simple assignment from memory (assumes naturally aligned address) - template struct implements_store : public false_type {}; // simple assignment to memory (assumes naturally aligned address) - template struct implements_CAS : public false_type {}; // compare_and_store() - template struct implements_LL_SC : public false_type {}; // load_linked(), store_conditional() - template struct implements_add : public false_type {}; // add(), subtract() - template struct implements_fetch_and_add : public false_type {}; // fetch_and_add(), fetch_and_subtract() - template struct implements_add_and_fetch : public false_type {}; // add_and_fetch(), subtract_and_fetch() - //------------------------------------- - - - //------------------------------------- - // functions in this namespace may or may not be implemented, for any integer types, as specified by the machine capabilities templates above - template bool compare_and_store(volatile _integer_type * operand_address, const _integer_type & expected_value, const _integer_type & value_to_store); - - template _integer_type load_linked(volatile _integer_type * operand_address); - template bool store_conditional(volatile _integer_type * operand_address, const _integer_type & value_to_store); - - template void add(volatile _integer_type * operand_address, const _integer_type & addend); - template void subtract(volatile _integer_type * operand_address, const _integer_type & subtrahend); - - template _integer_type fetch_and_add(volatile _integer_type * operand_address, const _integer_type & addend); - template _integer_type fetch_and_subtract(volatile _integer_type * operand_address, const _integer_type & subtrahend); - - template _integer_type add_and_fetch(volatile _integer_type * operand_address, const _integer_type & addend); - template _integer_type subtract_and_fetch(volatile _integer_type * operand_address, const _integer_type & subtrahend); - - void memory_barrier_read(); - void memory_barrier_write(); - void memory_barrier_readwrite(); - //------------------------------------- - - } // namespace machine - } // namespace atomic - } // namespace threading -} // namespace Akupara - -// Include the machine-specific implementations; these only implement the templates above for some of the _signed_ integer types -#if defined(__GNUC__) && defined(__POWERPC__) -#include "atomic_ops_gcc_ppc.hpp" -#endif // defined(__GNUC__) && defined(__POWERPC__) - -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#include "atomic_ops_gcc_x86.hpp" -#endif // defined(__GNUC__) && defined(__i386__) - -#if defined(_MSC_VER) && defined(_M_IX86) -#include "atomic_ops_msvc_x86.hpp" -#endif // defined(_MSC_VER) && defined(_M_IX86) - -#if defined(_MSC_VER) && defined(_M_X64) -#include "atomic_ops_msvc_x86_64.hpp" -#endif // defined(_MSC_VER) && defined(_M_X64) - -namespace Akupara -{ - namespace threading - { - namespace atomic - { - - - // Select the most convenient atomic integer type based on the machine's ability to load/store atomically - // The definition below selects that largest atomically accessible integer up to the size of int - //---------------------------------------------------------------------------------------- - namespace detail - { - template - struct largest_atomic_byte_count_upto - { - static const unsigned int value = - machine::implements_load<_byte_count>::value && machine::implements_store<_byte_count>::value ? -_byte_count : - largest_atomic_byte_count_upto<_byte_count/2>::value; - }; - - template<> - struct largest_atomic_byte_count_upto<0> { static const unsigned int value = 0; }; - - const unsigned int k_byte_count_best_atomic = largest_atomic_byte_count_upto::value; - } - typedef signed_integer_with_byte_count< detail::k_byte_count_best_atomic >::type signed_integer_type; - typedef unsigned_integer_with_byte_count< detail::k_byte_count_best_atomic >::type unsigned_integer_type; - typedef signed_integer_type integer_type; - //---------------------------------------------------------------------------------------- - - //---------------------------------------------------------------------------------------- - // These need to be implemented by all machines - using machine::memory_barrier_read; - using machine::memory_barrier_write; - using machine::memory_barrier_readwrite; - //---------------------------------------------------------------------------------------- - - //---------------------------------------------------------------------------------------- - // These may or may not be implemented, but if they aren't, we can't help much - using machine::load_linked; - using machine::store_conditional; - //---------------------------------------------------------------------------------------- - - - //---------------------------------------------------------------------------------------- - // CAS implementation - namespace detail - { - template< - typename _integer_type, - bool _implements_CAS = machine::implements_CAS ::value, - bool _implements_LL_SC = machine::implements_LL_SC::value> - struct implementation_CAS - { - static const bool s_exists = false; - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization for native CAS support - template - struct implementation_CAS<_integer_type, true, _implements_LL_SC> - { - static const bool s_exists = true; - static inline bool compare_and_store(volatile _integer_type * operand_address, const _integer_type & expected_value, const _integer_type & value_to_store) - { - return machine::compare_and_store(operand_address, expected_value, value_to_store); - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization for cases with no CAS but with LL/SC - template - struct implementation_CAS<_integer_type, false, true> - { - static const bool s_exists = true; - static inline bool compare_and_store(volatile _integer_type * operand_address, const _integer_type & expected_value, const _integer_type & value_to_store) - { - while (machine::load_linked(operand_address) == expected_value) - if (AKUPARA_EXPECT_TRUE(machine::store_conditional(operand_address, value_to_store))) - return true; - return false; - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } // namespace detail - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template - inline bool compare_and_store(volatile _integer_type * operand_address, const _integer_type & expected_value, const _integer_type & value_to_store) - { - // if your compiler can't find the function to call here then there is no implementation available for your machine - return detail::implementation_CAS<_integer_type>::compare_and_store(operand_address, expected_value, value_to_store); - } - //---------------------------------------------------------------------------------------- - - - - - - //---------------------------------------------------------------------------------------- - // fetch_and_add - namespace detail - { - template< - typename _integer_type, - bool _0 = machine::implements_fetch_and_add::value, - bool _1 = machine::implements_add_and_fetch::value, - bool _2 = machine::implements_LL_SC ::value, - bool _3 = machine::implements_CAS ::value> - struct implementation_FAA - { - static const bool s_exists = false; - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization for native support - template - struct implementation_FAA<_integer_type, true, _1, _2, _3> - { - static const bool s_exists = true; - static inline _integer_type fetch_and_add(volatile _integer_type * operand_address, const _integer_type & addend) - { - return machine::fetch_and_add(operand_address, addend); - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization using add_and_fetch - template - struct implementation_FAA<_integer_type, false, true, _2, _3> - { - static const bool s_exists = true; - static inline _integer_type fetch_and_add(volatile _integer_type * operand_address, const _integer_type & addend) - { - return machine::add_and_fetch(operand_address, addend) - addend; - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization using LL/SC - template - struct implementation_FAA<_integer_type, false, false, true, _3> - { - static const bool s_exists = true; - static inline _integer_type fetch_and_add(volatile _integer_type * operand_address, const _integer_type & addend) - { - _integer_type old_value; - do - old_value = machine::load_linked(operand_address); - while (!machine::store_conditional(operand_address, old_value+addend)); - return old_value; - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization using CAS - template - struct implementation_FAA<_integer_type, false, false, false, true> - { - static const bool s_exists = true; - static inline _integer_type fetch_and_add(volatile _integer_type * operand_address, const _integer_type & addend) - { - _integer_type old_value; - do - old_value = *operand_address; - while (!machine::compare_and_store(operand_address, old_value, old_value+addend)); - return old_value; - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } // namespace detail - template - inline _integer_type fetch_and_add(volatile _integer_type * operand_address, const _integer_type & addend) - { - // if your compiler can't find the function to call here then there is no implementation available for your machine - return detail::implementation_FAA<_integer_type>::fetch_and_add(operand_address, addend); - } - //---------------------------------------------------------------------------------------- - - - - - //---------------------------------------------------------------------------------------- - // add_and_fetch - namespace detail - { - template< - typename _integer_type, - bool _0 = machine::implements_add_and_fetch::value, - bool _1 = machine::implements_fetch_and_add::value, - bool _2 = machine::implements_LL_SC ::value, - bool _3 = machine::implements_CAS ::value> - struct implementation_AAF - { - static const bool s_exists = false; - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization for native support - template - struct implementation_AAF<_integer_type, true, _1, _2, _3> - { - static const bool s_exists = true; - static inline _integer_type add_and_fetch(volatile _integer_type * operand_address, const _integer_type & addend) - { - return machine::add_and_fetch(operand_address, addend); - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization using add_and_fetch - template - struct implementation_AAF<_integer_type, false, true, _2, _3> - { - static const bool s_exists = true; - static inline _integer_type add_and_fetch(volatile _integer_type * operand_address, const _integer_type & addend) - { - return machine::fetch_and_add(operand_address, addend) + addend; - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization using LL/SC - template - struct implementation_AAF<_integer_type, false, false, true, _3> - { - static const bool s_exists = true; - static inline _integer_type add_and_fetch(volatile _integer_type * operand_address, const _integer_type & addend) - { - _integer_type new_value; - do - new_value = machine::load_linked(operand_address)+addend; - while (!machine::store_conditional(operand_address, new_value)); - return new_value; - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // specialization using CAS - template - struct implementation_AAF<_integer_type, false, false, false, true> - { - static const bool s_exists = true; - static inline _integer_type add_and_fetch(volatile _integer_type * operand_address, const _integer_type & addend) - { - _integer_type old_value, new_value; - do - old_value = *operand_address, new_value = old_value + addend; - while (!machine::compare_and_store(operand_address, old_value, new_value)); - return new_value; - } - }; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } // namespace detail - template - inline _integer_type add_and_fetch(volatile _integer_type * operand_address, const _integer_type & addend) - { - // if your compiler can't find the function to call here then there is no implementation available for your machine - return detail::implementation_AAF<_integer_type>::add_and_fetch(operand_address, addend); - } - //---------------------------------------------------------------------------------------- - - - - //---------------------------------------------------------------------------------------- - // add - template - inline void add(volatile _integer_type * operand_address, const _integer_type & addend) - { - if (machine::implements_add::value) - machine::add(operand_address, addend); - else if (machine::implements_fetch_and_add::value) - machine::fetch_and_add(operand_address, addend); - else if (machine::implements_add_and_fetch::value) - machine::add_and_fetch(operand_address, addend); - else - fetch_and_add(operand_address, addend); // this will simulate using CAS or LL/SC (or it will fail the compilation if neither is available) - } - //---------------------------------------------------------------------------------------- - - - - //---------------------------------------------------------------------------------------- - // TODO: this is where we add implementations for: - // - functions not implemented by the machine - // - functions that take unsigned types (routed to call the signed versions with appropriate conversions) - // For now we add nothing, so developers will need to stick to what their machine can do, and use signed - // integers only. - using machine::subtract; - using machine::subtract_and_fetch; - using machine::fetch_and_subtract; - //---------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------- - template - struct pad_to_cache_line : public _base_type - { - private: - typedef pad_to_cache_line this_type; - typedef _base_type base_type; - public: - static const unsigned int s_bytes_per_cache_line = _bytes_per_cache_line; - private: - int m_padding[(s_bytes_per_cache_line - sizeof(base_type))/sizeof(int)]; - public: - pad_to_cache_line() {} - template pad_to_cache_line(_arg_type arg) : base_type(arg) {} - }; - //--------------------------------------------------------------------- - - } // namespace atomic - } // namespace threading -} // namespace Akupara - -#endif // _AKUPARA_THREADING_ATOMIC_OPS_HPP__INCLUDED_ diff --git a/libs/backends/wavesaudio/wavesapi/akupara/threading/atomic_ops_gcc_x86.hpp b/libs/backends/wavesaudio/wavesapi/akupara/threading/atomic_ops_gcc_x86.hpp deleted file mode 100644 index 74d73106f8..0000000000 --- a/libs/backends/wavesaudio/wavesapi/akupara/threading/atomic_ops_gcc_x86.hpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Akupara/threading/atomic_ops_gcc_x86.hpp - * - * - * Created by Udi Barzilai on 06/06. - * Copyright 2006 __MyCompanyName__. All rights reserved. - * - */ -#if !defined(_AKUPARA_THREADING_ATOMIC_OPS_GCC_X86_HPP__INCLUDED_) -# define _AKUPARA_THREADING_ATOMIC_OPS_GCC_X86_HPP__INCLUDED_ -# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - -namespace Akupara -{ - namespace threading - { - namespace atomic - { - namespace machine - { - const unsigned int k_bytes_per_cache_line = 64; // this is true for P4 & K8 - - - // Flags for operations supported by this machine - //------------------------------------- - template<> struct implements_load <4> : public true_type {}; - template<> struct implements_store <4> : public true_type {}; - template<> struct implements_CAS <4> : public true_type {}; - template<> struct implements_CAS <8> : public true_type {}; - template<> struct implements_add <4> : public true_type {}; - template<> struct implements_fetch_and_add<4> : public true_type {}; - //------------------------------------- - - - - // CAS - //-------------------------------------------------------------------------------- - template<> - inline bool compare_and_store(volatile int64_t * p, const int64_t & x, const int64_t & y) - { - register int32_t evh=int32_t(x>>32), evl=int32_t(x); - register const int32_t nvh=int32_t(y>>32), nvl=int32_t(y); - register bool result; - __asm__ __volatile__ ( - "# CAS64\n" - " lock \n" - " cmpxchg8b %[location] \n" - " sete %[result] \n" - : [location] "+m" (*p), [result] "=qm" (result), [expected_value_high] "+d" (evh), [expected_value_low] "+a" (evl) - : [new_value_high] "c" (nvh), [new_value_low] "b" (nvl) - : "cc" - ); - return result; - } - //-------------------------------------------------------------------------------- - template<> - inline bool compare_and_store(volatile int32_t *p, const int32_t & x, const int32_t & y) - { - register int32_t expected_value = x; - register bool result; - __asm__ __volatile__ ( - "# CAS32\n" - " lock \n" - " cmpxchgl %[new_value],%[operand] \n" - " sete %[result] \n" - : [operand] "+m" (*p), [result] "=qm" (result), [expected_value] "+a" (expected_value) - : [new_value] "r" (y) - : "cc" - ); - return result; - } - //-------------------------------------------------------------------------------- - - - - - // Atomic add/sub - //-------------------------------------------------------------------------------- - inline void increment(volatile int32_t * operand_address) - { - __asm__ __volatile__ ( - "# atomic_increment_32\n" - " lock; \n" - " incl %[operand]; \n" - : [operand] "+m" (*operand_address) - : - : "cc" - ); - } - //-------------------------------------------------------------------------------- - inline void decrement(volatile int32_t * operand_address) - { - __asm__ __volatile__ ( - "# atomic_decrement_32\n" - " lock; \n" - " decl %[operand]; \n" - : [operand] "+m" (*operand_address) - : - : "cc" - ); - } - //-------------------------------------------------------------------------------- - template<> - inline void add(volatile int32_t * operand_address, const int32_t & addend) - { - if (__builtin_constant_p(addend) && addend==1) - increment(operand_address); - else if (__builtin_constant_p(addend) && addend==-1) - decrement(operand_address); - else - __asm__ __volatile__ ( - "# atomic_add_32 \n" - " lock \n" - " addl %[addend], %[operand] \n" - : [operand] "+m" (*operand_address) - : [addend] "ir" (addend) - : "cc" - ); - } - //-------------------------------------------------------------------------------- - template<> - inline void subtract(volatile int32_t * operand_address, const int32_t & subtrahend) - { - if (__builtin_constant_p(subtrahend) && subtrahend==1) - decrement(operand_address); - else if (__builtin_constant_p(subtrahend) && subtrahend==-1) - increment(operand_address); - else - __asm__ __volatile__ ( - "# atomic_subtract_32 \n" - " lock \n" - " subl %[subtrahend], %[operand] \n" - : [operand] "+m" (*operand_address) - : [subtrahend] "ir" (subtrahend) - : "cc" - ); - } - //-------------------------------------------------------------------------------- - - - - // Atomic fetch and add/sub - //-------------------------------------------------------------------------------- - template<> - inline int32_t fetch_and_add(volatile int32_t * operand_address, const int32_t & addend) - { - register int32_t addend_and_fetched = addend; - __asm__ __volatile__ ( - "# atomic_fetch_and_add_32 \n" - " lock; \n" - " xaddl %[addend], %[operand]; \n" - : [operand] "+m" (*operand_address), [addend] "+r" (addend_and_fetched) - : - : "cc" - ); - return addend_and_fetched; - } - //-------------------------------------------------------------------------------- - template<> - inline int32_t fetch_and_subtract(volatile int32_t * operand_address, const int32_t & subtrahend) - { - return fetch_and_add(operand_address, -subtrahend); - } - //-------------------------------------------------------------------------------- - - - - - // Memory barriers - //-------------------------------------------------------------------------------- - inline void memory_barrier_readwrite() - { - #if _AKUPARA_X86_SSE_NOT_AVAILABLE - __asm__ __volatile__ (" lock; addl $0,0(%%esp); # memory_barrier_readwrite" : : : "memory"); - #else - __asm__ __volatile__ (" mfence; # memory_barrier_readwrite" : : : "memory"); - #endif // _LOCKFREE_ATOMIC_OPS_X86_LFENCE_NOT_AVAILABLE - } - //-------------------------------------------------------------------------------- - inline void memory_barrier_read() - { - #if _AKUPARA_X86_SSE_NOT_AVAILABLE - __asm__ __volatile__ (" lock; addl $0,0(%%esp); # memory_barrier_read" : : : "memory"); - #else - __asm__ __volatile__ (" lfence; # memory_barrier_read" : : : "memory"); - #endif // _LOCKFREE_ATOMIC_OPS_X86_LFENCE_NOT_AVAILABLE - } - //-------------------------------------------------------------------------------- - inline void memory_barrier_write() - { - __asm__ __volatile__ (" sfence; # memory_barrier_write" : : : "memory"); - } - //-------------------------------------------------------------------------------- - - } // namespace machine - } // namespace atomic - } // namespace threading -} // namespace Akupara - -# endif // defined(__GNUC__) && defined(__i386__) -#endif // _AKUPARA_THREADING_ATOMIC_OPS_GCC_X86_HPP__INCLUDED_ diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/IncludeWindows.h b/libs/backends/wavesaudio/wavesapi/devicemanager/IncludeWindows.h deleted file mode 100644 index 53ed7e69bc..0000000000 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/IncludeWindows.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __IncludeWindows_h__ -#define __IncludeWindows_h__ - -#ifdef PLATFORM_WINDOWS - -/* Copy to include -#include "IncludeWindows.h" -*/ - -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0601 // Windows 7 -#endif - -#ifndef WINVER -#define WINVER 0x0601 // Windows 7 -#endif - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#ifndef NOMINMAX -#define NOMINMAX // DO NOT REMOVE NOMINMAX - DOING SO CAUSES CONFLICTS WITH STD INCLUDES ( ...) -#endif - -#include -#include -#include -#endif // #if PLATFORM_WINDOWS -#endif // #ifndef __IncludeWindows_h__ - diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp deleted file mode 100644 index 7c4a3e9962..0000000000 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp +++ /dev/null @@ -1,692 +0,0 @@ -//---------------------------------------------------------------------------------- -// -// Copyright (c) 2008 Waves Audio Ltd. All rights reserved. -// -//! \file WCMRAudioDeviceManager.cpp -//! -//! WCMRAudioDeviceManager and related class declarations -//! -//---------------------------------------------------------------------------------*/ -#include -#include "WCMRAudioDeviceManager.h" - - -//********************************************************************************************** -// WCMRAudioDevice::WCMRAudioDevice -// -//! Constructor for the audio device. The derived classes will need to do more actual work, such -//! as determining supported sampling rates, buffer sizes, and channel counts. Connection -//! and streaming will also be provided by the derived implementations. -//! -//! \param *pManager : The audio device manager that's managing this device. -//! \return Nothing. -//! -//********************************************************************************************** -WCMRAudioDevice::WCMRAudioDevice (WCMRAudioDeviceManager *pManager) : - m_pMyManager (pManager) - , m_ConnectionStatus (DeviceDisconnected) - , m_IsActive (false) - , m_IsStreaming (false) - , m_CurrentSamplingRate (-1) - , m_CurrentBufferSize (0) - , m_LeftMonitorChannel (-1) - , m_RightMonitorChannel (-1) - , m_MonitorGain (1.0f) -{ - m_DeviceName = "Unknown"; -} - - - -//********************************************************************************************** -// WCMRAudioDevice::~WCMRAudioDevice -// -//! Destructor for the audio device. It release all the connections that were created. -//! -//! \param none -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRAudioDevice::~WCMRAudioDevice () -{ - AUTO_FUNC_DEBUG; - try - { - } - catch (...) - { - //destructors should absorb exceptions, no harm in logging though!! - DEBUG_MSG ("Exception during destructor"); - } -} - - - - -//********************************************************************************************** -// WCMRAudioDevice::DeviceName -// -//! Retrieves Device's name. -//! -//! \param none -//! -//! \return The device name. -//! -//********************************************************************************************** -const std::string& WCMRAudioDevice::DeviceName () const -{ - return (m_DeviceName); - -} - - - -//********************************************************************************************** -// WCMRAudioDevice::InputChannels -// -//! Retrieves Input Channel information. Note that the list may be changed at run-time. -//! -//! \param none -//! -//! \return A vector with Input Channel Names. -//! -//********************************************************************************************** -const std::vector& WCMRAudioDevice::InputChannels () -{ - return (m_InputChannels); - -} - - - -//********************************************************************************************** -// WCMRAudioDevice::OutputChannels -// -//! Retrieves Output Channel Information. Note that the list may be changed at run-time. -//! -//! \param none -//! -//! \return A vector with Output Channel Names. -//! -//********************************************************************************************** -const std::vector& WCMRAudioDevice::OutputChannels () -{ - return (m_OutputChannels); -} - - - - -//********************************************************************************************** -// WCMRAudioDevice::SamplingRates -// -//! Retrieves supported sampling rate information. -//! -//! \param none -//! -//! \return A vector with supported sampling rates. -//! -//********************************************************************************************** -const std::vector& WCMRAudioDevice::SamplingRates () -{ - return (m_SamplingRates); -} - - - -//********************************************************************************************** -// WCMRAudioDevice::CurrentSamplingRate -// -//! The device's current sampling rate. This may be overridden, if the device needs to -//! query the driver for the current rate. -//! -//! \param none -//! -//! \return The device's current sampling rate. -1 on error. -//! -//********************************************************************************************** -int WCMRAudioDevice::CurrentSamplingRate () -{ - return (m_CurrentSamplingRate); -} - - - - -//********************************************************************************************** -// WCMRAudioDevice::SetCurrentSamplingRate -// -//! Change the sampling rate to be used by the device. This will most likely be overridden, -//! the base class simply updates the member variable. -//! -//! \param newRate : The rate to use (samples per sec). -//! -//! \return eNoErr always. The derived classes may return error codes. -//! -//********************************************************************************************** -WTErr WCMRAudioDevice::SetCurrentSamplingRate (int newRate) -{ - //changes the status. - m_CurrentSamplingRate = newRate; - return (eNoErr); -} - - - - -//********************************************************************************************** -// WCMRAudioDevice::BufferSizes -// -//! Retrieves supported buffer size information. -//! -//! \param none -//! -//! \return A vector with supported buffer sizes. -//! -//********************************************************************************************** -const std::vector& WCMRAudioDevice::BufferSizes () -{ - return (m_BufferSizes); -} - - - -//********************************************************************************************** -// WCMRAudioDevice::CurrentBufferSize -// -//! The device's current buffer size in use. This may be overridden, if the device needs to -//! query the driver for the current size. -//! -//! \param none -//! -//! \return The device's current buffer size. 0 on error. -//! -//********************************************************************************************** -int WCMRAudioDevice::CurrentBufferSize () -{ - return (m_CurrentBufferSize); -} - -//********************************************************************************************** -// WCMRAudioDevice::CurrentBlockSize -// -//! Device's block size we use for holding the audio samples. -//! Usually this is equal to the buffer size, but in some cases the buffer size holds additional -//! data other then the audio buffers, like frames info in SG, so it can be overridden -//! -//! \param none -//! -//! \return The device's current block size. 0 on error. -//! -//********************************************************************************************** -int WCMRAudioDevice::CurrentBlockSize() -{ - // By default - return the buffer size - return CurrentBufferSize(); -} - - -//********************************************************************************************** -// WCMRAudioDevice::SetCurrentBufferSize -// -//! Change the buffer size to be used by the device. This will most likely be overridden, -//! the base class simply updates the member variable. -//! -//! \param newSize : The buffer size to use (in sample-frames) -//! -//! \return eNoErr always. The derived classes may return error codes. -//! -//********************************************************************************************** -WTErr WCMRAudioDevice::SetCurrentBufferSize (int newSize) -{ - //This will most likely be overridden, the base class simply - //changes the member. - m_CurrentBufferSize = newSize; - return (eNoErr); -} - - - - -//********************************************************************************************** -// WCMRAudioDevice::ConnectionStatus -// -//! Retrieves the device's current connection status. This will most likely be overridden, -//! in case some driver communication is required to query the status. -//! -//! \param none -//! -//! \return A ConnectionStates value. -//! -//********************************************************************************************** -WCMRAudioDevice::ConnectionStates WCMRAudioDevice::ConnectionStatus () -{ - return (m_ConnectionStatus); - -} - - - - -//********************************************************************************************** -// WCMRAudioDevice::Active -// -//! Retrieves Device activation status. -//! -//! \param none -//! -//! \return true if device is active, false otherwise. -//! -//********************************************************************************************** -bool WCMRAudioDevice::Active () -{ - return (m_IsActive); - -} - - - -//********************************************************************************************** -// WCMRAudioDevice::SetActive -// -//! Sets the device's activation status. -//! -//! \param newState : Should be true to activate, false to deactivate. This roughly corresponds -//! to opening and closing the device handle/stream/audio unit. -//! -//! \return eNoErr always, the derived classes may return appropriate error code. -//! -//********************************************************************************************** -WTErr WCMRAudioDevice::SetActive (bool newState) -{ - //This will most likely be overridden, the base class simply - //changes the member. - m_IsActive = newState; - return (eNoErr); -} - - - - -//********************************************************************************************** -// WCMRAudioDevice::Streaming -// -//! Retrieves Device streaming status. -//! -//! \param none -//! -//! \return true if device is streaming, false otherwise. -//! -//********************************************************************************************** -bool WCMRAudioDevice::Streaming () -{ - return (m_IsStreaming); -} - - - -//********************************************************************************************** -// WCMRAudioDevice::SetStreaming -// -//! Sets the device's streaming status. -//! -//! \param newState : Should be true to start streaming, false to stop streaming. This roughly -//! corresponds to calling Start/Stop on the lower level interface. -//! -//! \return eNoErr always, the derived classes may return appropriate error code. -//! -//********************************************************************************************** -WTErr WCMRAudioDevice::SetStreaming (bool newState) -{ - // We must notify angine about our intention to start streming - // so Engine will provide all the initializations in the first audio callback - if (newState) { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming); - } - - //This will most likely be overridden, the base class simply - //changes the member. - m_IsStreaming = newState; - return (eNoErr); -} - - -WTErr WCMRAudioDevice::ResetDevice () -{ - // Keep device sates - bool wasStreaming = Streaming(); - bool wasActive = Active(); - - WTErr err = SetStreaming(false); - - if (err == eNoErr) - err = SetActive(false); - - if (err == eNoErr && wasActive) - err = SetActive(true); - - if (err == eNoErr && wasStreaming) - SetStreaming(true); - - return err; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -// IsProcessActive - returns true if process code is running. -// A normal audio device should return the Streaming() value -/////////////////////////////////////////////////////////////////////////////////////////////////////// -bool WCMRAudioDevice::IsProcessActive() -{ - return Streaming(); -} - - - - - -//********************************************************************************************** -// WCMRAudioDevice::DoIdle -// -//! A place for doing idle time processing. The derived classes will probably do something -//! meaningful. -//! -//! \param none -//! -//! \return eNoErr always. -//! -//********************************************************************************************** -WTErr WCMRAudioDevice::DoIdle () -{ - //We don't need to do anything here... - //the derived classes may want to use this however. - return (eNoErr); -} - - - - -//********************************************************************************************** -// WCMRAudioDevice::InputLevels -// -//! Retrieve current input levels. -//! -//! \param none -//! -//! \return A vector (the same size as input channels list) that contains current input levels. -//! -//********************************************************************************************** -const std::vector& WCMRAudioDevice::InputLevels () -{ - //The derived classes may override if they need to query - //the driver for the levels. - return (m_InputLevels); -} - - - -//********************************************************************************************** -// WCMRAudioDevice::OutputLevels -// -//! Retrieve current output levels. -//! -//! \param none -//! -//! \return A vector (the same size as output channels list) that contains current output levels. -//! -//********************************************************************************************** -const std::vector& WCMRAudioDevice::OutputLevels () -{ - //The derived classes may override if they need to query - //the driver for the levels. - return (m_OutputLevels); -} - - - -//********************************************************************************************** -// WCMRAudioDevice::GetMonitorInfo -// -//! Retrieves current monitoring information. -//! -//! \param *pLeftChannel : Pointer to receive left monitor channel index. -//! \param *pRightChannel : Pointer to receive right monitor channel index. -//! \param *pGain : Pointer to receive the gain (linear) to be applied. -//! -//! \return Nothing. -//! -//********************************************************************************************** -void WCMRAudioDevice::GetMonitorInfo (int *pLeftChannel, int *pRightChannel, float *pGain) -{ - if (pLeftChannel) - *pLeftChannel = m_LeftMonitorChannel; - if (pRightChannel) - *pRightChannel = m_RightMonitorChannel; - if (pGain) - *pGain = m_MonitorGain; - return; -} - - - -//********************************************************************************************** -// WCMRAudioDevice::SetMonitorChannels -// -//! Used to set the channels to be used for monitoring. -//! -//! \param leftChannel : Left monitor channel index. -//! \param rightChannel : Right monitor channel index. -//! -//! \return eNoErr always, the derived classes may return appropriate errors. -//! -//********************************************************************************************** -WTErr WCMRAudioDevice::SetMonitorChannels (int leftChannel, int rightChannel) -{ - //This will most likely be overridden, the base class simply - //changes the member. - m_LeftMonitorChannel = leftChannel; - m_RightMonitorChannel = rightChannel; - return (eNoErr); -} - - - -//********************************************************************************************** -// WCMRAudioDevice::SetMonitorGain -// -//! Used to set monitor gain (or atten). -//! -//! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB) -//! -//! \return eNoErr always, the derived classes may return appropriate errors. -//! -//********************************************************************************************** -WTErr WCMRAudioDevice::SetMonitorGain (float newGain) -{ - //This will most likely be overridden, the base class simply - //changes the member. - m_MonitorGain = newGain; - return (eNoErr); -} - - - - -//********************************************************************************************** -// WCMRAudioDevice::ShowConfigPanel -// -//! Used to show device specific config/control panel. Some interfaces may not support it. -//! Some interfaces may require the device to be active before it can display a panel. -//! -//! \param pParam : A device/interface specific parameter - optional. -//! -//! \return eNoErr always, the derived classes may return errors. -//! -//********************************************************************************************** -WTErr WCMRAudioDevice::ShowConfigPanel (void *WCUNUSEDPARAM(pParam)) -{ - //This will most likely be overridden... - return (eNoErr); -} - - -//********************************************************************************************** -// WCMRAudioDevice::SendCustomCommand -// -//! Used to Send a custom command to the audiodevice. Some interfaces may require the device -//! to be active before it can do anything in this. -//! -//! \param customCommand : A device/interface specific command. -//! \param pCommandParam : A device/interface/command specific parameter - optional. -//! -//! \return eNoErr always, the derived classes may return errors. -//! -//********************************************************************************************** -WTErr WCMRAudioDevice::SendCustomCommand (int WCUNUSEDPARAM(customCommand), void *WCUNUSEDPARAM(pCommandParam)) -{ - //This will most likely be overridden... - return (eNoErr); -} - -//********************************************************************************************** -// WCMRAudioDevice::GetLatency -// -//! Get Latency for device. -//! -//! Use 'kAudioDevicePropertyLatency' and 'kAudioDevicePropertySafetyOffset' + GetStreamLatencies -//! -//! \param isInput : Return latency for the input if isInput is true, otherwise the output latency -//! wiil be returned. -//! \return Latency in samples. -//! -//********************************************************************************************** -uint32_t WCMRAudioDevice::GetLatency (bool isInput) -{ - //This will most likely be overridden... - return 0; -} - - -//********************************************************************************************** -// WCMRAudioDeviceManager::WCMRAudioDeviceManager -// -//! The constructuor, most of the work will be done in the derived class' constructor. -//! -//! \param *pTheClient : -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRAudioDeviceManager::WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter) - : m_eAudioDeviceFilter(eCurAudioDeviceFilter) - , m_CurrentDevice(0) - , m_pTheClient (pTheClient) -{ -} - - -//********************************************************************************************** -// WCMRAudioDeviceManager::~WCMRAudioDeviceManager -// -//! It clears the device list, releasing each of the device. -//! -//! \param none -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRAudioDeviceManager::~WCMRAudioDeviceManager() -{ - AUTO_FUNC_DEBUG; - - std::cout << "API::Destroying AudioDeviceManager " << std::endl; - try - { - // clean up device info list - { - wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex); - while( m_DeviceInfoVec.size() ) - { - DeviceInfo* devInfo = m_DeviceInfoVec.back(); - m_DeviceInfoVec.pop_back(); - delete devInfo; - } - } - delete m_CurrentDevice; - - } - catch (...) - { - //destructors should absorb exceptions, no harm in logging though!! - DEBUG_MSG ("Exception during destructor"); - } -} - - -WCMRAudioDevice* WCMRAudioDeviceManager::InitNewCurrentDevice(const std::string & deviceName) -{ - return initNewCurrentDeviceImpl(deviceName); -} - - -void WCMRAudioDeviceManager::DestroyCurrentDevice() -{ - return destroyCurrentDeviceImpl(); -} - - -const DeviceInfoVec WCMRAudioDeviceManager::DeviceInfoList() const -{ - wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex); - return m_DeviceInfoVec; -} - - -WTErr WCMRAudioDeviceManager::GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const -{ - wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex); - DeviceInfoVecConstIter iter = m_DeviceInfoVec.begin(); - for (; iter != m_DeviceInfoVec.end(); ++iter) - { - if (nameToMatch == (*iter)->m_DeviceName) - { - devInfo = *(*iter); - return eNoErr; - } - } - - return eRMResNotFound; -} - - -WTErr WCMRAudioDeviceManager::GetDeviceSampleRates(const std::string & nameToMatch, std::vector& sampleRates) const -{ - return getDeviceSampleRatesImpl(nameToMatch, sampleRates); -} - - - -WTErr WCMRAudioDeviceManager::GetDeviceBufferSizes(const std::string & nameToMatch, std::vector& bufferSizes) const -{ - return getDeviceBufferSizesImpl(nameToMatch, bufferSizes); -} - - -//********************************************************************************************** -// WCMRAudioDeviceManager::NotifyClient -// -//! A helper routine used to call the client for notification. -//! -//! \param forReason : The reason for notification. -//! \param *pParam : A parameter (if required) for notification. -//! -//! \return Nothing. -//! -//********************************************************************************************** -void WCMRAudioDeviceManager::NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam) -{ - if (m_pTheClient) - m_pTheClient->AudioDeviceManagerNotification (forReason, pParam); - return; -} diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h deleted file mode 100644 index b22e35263d..0000000000 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -//---------------------------------------------------------------------------------- -// -// -//! \file WCMRAudioDeviceManager.h -//! -//! WCMRAudioDeviceManager and related class declarations -//! -//---------------------------------------------------------------------------------*/ -#ifndef __WCMRAudioDeviceManager_h_ - #define __WCMRAudioDeviceManager_h_ - -/* Copy to include -#include "WCMRAudioDeviceManager.h" -*/ - -#define AUTO_FUNC_DEBUG -#define DEBUG_MSG(a) -#define ASSERT_ERROR(a, b) -#define TRACE_MSG(a) - -#include -#include -#include -#include "WCRefManager.h" -#include "BasicTypes/WUTypes.h" -#include "WUErrors.h" -#include "WCThreadSafe.h" - -#define WCUNUSEDPARAM(a) - -class WCMRAudioDevice; -class WCMRAudioDeviceManager; - -typedef unsigned int DeviceID; - -struct DeviceInfo -{ - DeviceID m_DeviceId; - std::string m_DeviceName; - std::vector m_AvailableSampleRates; - std::vector m_AvailableBufferSizes; - unsigned int m_MaxInputChannels; - unsigned int m_MaxOutputChannels; - - DeviceInfo(): - m_DeviceId(-1), m_DeviceName("Unknown"), m_MaxInputChannels(0), m_MaxOutputChannels(0) - {}; - - DeviceInfo(unsigned int deviceID, const std::string & deviceName): - m_DeviceId(deviceID), m_DeviceName(deviceName), m_MaxInputChannels(0), m_MaxOutputChannels(0) - {}; -}; - -typedef std::vector DeviceInfoVec; -typedef DeviceInfoVec::iterator DeviceInfoVecIter; -typedef DeviceInfoVec::const_iterator DeviceInfoVecConstIter; - -/// for notification... A client must derive it's class from us. -class WCMRAudioDeviceManagerClient -{ - public: - enum NotificationReason - { - DeviceListChanged, - Dropout, - RequestReset, - RequestResync, - SamplingRateChanged, //param has new SR, or -1 if not known - SamplingRateChangedSilent, //To indicate sampling rate changed but no need to notify user - BufferSizeChanged, - ClockSourceChanged, - DeviceStoppedStreaming, - DeviceStartsStreaming, - DeviceDroppedSamples, - DeviceConnectionLost, - DeviceGenericError, - DeviceStatusChanged, - DeviceStatisticsUpdated, - DeviceDebugInfo, //param has c string - DeviceProgressInfo, //param has c string - MIDIData, - MIDINodeUp, - MIDINodeDown, - DeviceSampleRateMisMatch, - SystemSamplingRateChangedInfoOnly, - LostClockSource, - IODeviceDisconnected, - ChannelCountModified, - MasterUp, - MasterDown, - AudioDropFound, - ReflasherEvent, - AGDeviceSamplingRateChangedInfoOnly, - IODeviceNameChanged, - SetDisplayNameFromIOModule, - IOMStateChanged, ///< This is used when IOM state is changed. - AudioCallback // VKamyshniy: param is AudioCallbackDataData* - }; - - WCMRAudioDeviceManagerClient () {} - virtual ~WCMRAudioDeviceManagerClient () {} - - // VKamyshniy: This is a structure to call the client's AudioDeviceManagerNotification - // every AudioCallback time - struct AudioCallbackData - { - const float *acdInputBuffer; - float *acdOutputBuffer; - size_t acdFrames; - int64_t acdSampleTime; - uint64_t acdCycleStartTimeNanos; - }; - - virtual void AudioDeviceManagerNotification (NotificationReason WCUNUSEDPARAM(reason), void *WCUNUSEDPARAM(pParam)) {} -}; - - -class WCMRAudioDevice : public WCRefManager -{ -public: - - enum ConnectionStates - { - DeviceAvailable, - DeviceDisconnected, - DeviceErrors - }; - - WCMRAudioDevice (WCMRAudioDeviceManager *pManager);///& InputChannels();///& OutputChannels();///& SamplingRates();///& BufferSizes();///& InputLevels();///& OutputLevels();/// m_InputChannels; ///< List of input channel names. - std::vector m_OutputChannels; ///< List of output channel names. - std::vector m_SamplingRates; ///< List of available sampling rates. - std::vector m_BufferSizes; ///< List of available buffer sizes. - - int m_CurrentSamplingRate; ///< Currently selected sampling rate. - int m_CurrentBufferSize; ///< Currently selected buffer size. - - ConnectionStates m_ConnectionStatus; ///< Status of device connection - bool m_IsActive; ///< Flag for teh active status. - bool m_IsStreaming; ///< Flag for streaming status. - std::vector m_InputLevels; ///< List of input levels. - std::vector m_OutputLevels; ///< List of output levels. - - int m_LeftMonitorChannel; ///< The device channel to use for monitoring left channel data. - int m_RightMonitorChannel; ///< The device channel to use for monitoring right channel data. - float m_MonitorGain; ///< Amount of gain to apply for monitoring signal. -}; - - -// This enum is for choosing filter for audio devices scan -typedef enum eAudioDeviceFilter -{ - eAllDevices = 0, // Choose all audio devices - eInputOnlyDevices, // Choose only input audio devices - eOutputOnlyDevices, // Choose only output audio devices - eFullDuplexDevices, // Choose audio devices that have both input and output channels on the same device - eMatchedDuplexDevices, // Match(aggregate) audio devices that have both input and output channels but are considered different audio devices (For mac) - eAudioDeviceFilterNum // Number of enums -} eAudioDeviceFilter; - - -class WCMRAudioDeviceManager : public WCRefManager -{ -public://< Public functions for the class. - - WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter); ///< constructor - virtual ~WCMRAudioDeviceManager(void); ///< Destructor - - //interfaces - WCMRAudioDevice* InitNewCurrentDevice(const std::string & deviceName); - void DestroyCurrentDevice(); - const DeviceInfoVec DeviceInfoList () const; - WTErr GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const; - WTErr GetDeviceSampleRates(const std::string & nameToMatch, std::vector& sampleRates) const; - WTErr GetDeviceBufferSizes(const std::string & nameToMatch, std::vector& bufferSizes) const; - - //virtual void EnableVerboseLogging(bool /*bEnable*/, const std::string& /*logFilePath*/) { }; - - //notify backend - void NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam = NULL); - -protected: - - mutable wvNS::wvThread::ThreadMutex m_AudioDeviceInfoVecMutex; // mutex to lock device info list - DeviceInfoVec m_DeviceInfoVec; - - eAudioDeviceFilter m_eAudioDeviceFilter; - WCMRAudioDevice* m_CurrentDevice; - -private: - // override in derived classes - // made private to avoid pure virtual function call - virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName) = 0; - virtual void destroyCurrentDeviceImpl() = 0; - virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector& sampleRates) const = 0; - virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector& bufferSizes) const = 0; - virtual WTErr generateDeviceListImpl() = 0; - virtual WTErr updateDeviceListImpl() = 0; - - WCMRAudioDeviceManagerClient *m_pTheClient; ///< The device manager's client, used to send notifications. -}; - -#endif //#ifndef __WCMRAudioDeviceManager_h_ diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp deleted file mode 100644 index 2a9a9ba19f..0000000000 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp +++ /dev/null @@ -1,3140 +0,0 @@ -//---------------------------------------------------------------------------------- -// -// Copyright (c) 2008 Waves Audio Ltd. All rights reserved. -// -//! \file WCMRCoreAudioDeviceManager.cpp -//! -//! WCMRCoreAudioDeviceManager and related class declarations -//! -//---------------------------------------------------------------------------------*/ -#include "WCMRCoreAudioDeviceManager.h" -#include -#include "MiscUtils/safe_delete.h" -#include -#include - -// This flag is turned to 1, but it does not work with aggregated devices. -// due to problems with aggregated devices this flag is not functional there -#define ENABLE_DEVICE_CHANGE_LISTNER 1 - -#define PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS 10 -#define PROPERTY_CHANGE_TIMEOUT_SECONDS 5 -#define USE_IOCYCLE_TIMES 1 ///< Set this to 0 to use individual thread cpu measurement - -using namespace wvNS; -///< Supported Sample rates -static const double gAllSampleRates[] = -{ - 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0, -1 /* negative terminated list */ -}; - - -///< Default Supported Buffer Sizes. -static const int gAllBufferSizes[] = -{ - 32, 64, 96, 128, 192, 256, 512, 1024, 2048, -1 /* negative terminated list */ -}; - - -///< The default SR. -static const int DEFAULT_SR = 44100; -///< The default buffer size. -static const int DEFAULT_BUFFERSIZE = 1024; - -static const int NONE_DEVICE_ID = -1; - -///< Number of stalls to wait before notifying user... -static const int NUM_STALLS_FOR_NOTIFICATION = 2 * 50; // 2*50 corresponds to 2 * 50 x 42 ms idle timer - about 4 seconds. -static const int CHANGE_CHECK_COUNTER_PERIOD = 100; // 120 corresponds to 120 x 42 ms idle timer - about 4 seconds. - -#define AUHAL_OUTPUT_ELEMENT 0 -#define AUHAL_INPUT_ELEMENT 1 - -#include - -static int getProcessorCount() -{ - int count = 1; - size_t size = sizeof(count); - - if (sysctlbyname("hw.ncpu", &count, &size, NULL, 0)) - return 1; - - //if something did not work, let's revert to a safe value... - if (count == 0) - count = 1; - - return count; -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::WCMRCoreAudioDevice -// -//! Constructor for the audio device. Opens the PA device and gets information about the device. -//! such as determining supported sampling rates, buffer sizes, and channel counts. -//! -//! \param *pManager : The audio device manager that's managing this device. -//! \param deviceID : The port audio device ID. -//! \param useMultithreading : Whether to use multi-threading for audio processing. Default is true. -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRCoreAudioDevice::WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager, AudioDeviceID deviceID, bool useMultithreading, bool bNocopy) - : WCMRNativeAudioDevice (pManager, useMultithreading, bNocopy) - , m_SampleCountAtLastIdle (0) - , m_StalledSampleCounter(0) - , m_SampleCounter(0) - , m_BufferSizeChangeRequested (0) - , m_BufferSizeChangeReported (0) - , m_ResetRequested (0) - , m_ResetReported (0) - , m_ResyncRequested (0) - , m_ResyncReported (0) - , m_SRChangeRequested (0) - , m_SRChangeReported (0) - , m_ChangeCheckCounter(0) - , m_IOProcThreadPort (0) - , m_DropsDetected(0) - , m_DropsReported(0) - , m_IgnoreThisDrop(true) - , m_LastCPULog(0) -#if WV_USE_TONE_GEN - , m_pToneData(0) - , m_ToneDataSamples (0) - , m_NextSampleToUse (0) -#endif //WV_USE_TONE_GEN -{ - AUTO_FUNC_DEBUG; - UInt32 propSize = 0; - OSStatus err = kAudioHardwareNoError; - - //Update device info... - m_DeviceID = deviceID; - - m_CurrentSamplingRate = DEFAULT_SR; - m_CurrentBufferSize = DEFAULT_BUFFERSIZE; - m_StopRequested = true; - m_pInputData = NULL; - - m_CPUCount = getProcessorCount(); - m_LastCPULog = wvThread::now() - 10 * wvThread::ktdOneSecond; - - - - /* - @constant kAudioDevicePropertyNominalSampleRate - A Float64 that indicates the current nominal sample rate of the AudioDevice. - */ - Float64 currentNominalRate; - propSize = sizeof (currentNominalRate); - err = kAudioHardwareNoError; - if (AudioDeviceGetProperty(m_DeviceID, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, ¤tNominalRate) != kAudioHardwareNoError) - err = AudioDeviceGetProperty(m_DeviceID, 0, 1, kAudioDevicePropertyNominalSampleRate, &propSize, ¤tNominalRate); - - if (err == kAudioHardwareNoError) - m_CurrentSamplingRate = (int)currentNominalRate; - - /* - @constant kAudioDevicePropertyBufferFrameSize - A UInt32 whose value indicates the number of frames in the IO buffers. - */ - - UInt32 bufferSize; - propSize = sizeof (bufferSize); - err = kAudioHardwareNoError; - if (AudioDeviceGetProperty(m_DeviceID, 0, 0, kAudioDevicePropertyBufferFrameSize, &propSize, &bufferSize) != kAudioHardwareNoError) - err = AudioDeviceGetProperty(m_DeviceID, 0, 1, kAudioDevicePropertyBufferFrameSize, &propSize, &bufferSize); - - if (err == kAudioHardwareNoError) - m_CurrentBufferSize = (int)bufferSize; - - - UpdateDeviceInfo(); - - //should use a valid current SR... - if (m_SamplingRates.size()) - { - //see if the current sr is present in the sr list, if not, use the first one! - std::vector::iterator intIter = find(m_SamplingRates.begin(), m_SamplingRates.end(), m_CurrentSamplingRate); - if (intIter == m_SamplingRates.end()) - { - //not found... use the first one - m_CurrentSamplingRate = m_SamplingRates[0]; - } - } - - //should use a valid current buffer size - if (m_BufferSizes.size()) - { - //see if the current sr is present in the buffersize list, if not, use the first one! - std::vector::iterator intIter = find(m_BufferSizes.begin(), m_BufferSizes.end(), m_CurrentBufferSize); - if (intIter == m_BufferSizes.end()) - { - //not found... use the first one - m_CurrentBufferSize = m_BufferSizes[0]; - } - } - - //build our input/output level lists - for (unsigned int currentChannel = 0; currentChannel < m_InputChannels.size(); currentChannel++) - { - m_InputLevels.push_back (0.0); - } - - //build our input/output level lists - for (unsigned int currentChannel = 0; currentChannel < m_OutputChannels.size(); currentChannel++) - { - m_OutputLevels.push_back (0.0); - } - -} - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::~WCMRCoreAudioDevice -// -//! Destructor for the audio device. The base release all the connections that were created, if -//! they have not been already destroyed! Here we simply stop streaming, and close device -//! handles if necessary. -//! -//! \param none -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRCoreAudioDevice::~WCMRCoreAudioDevice () -{ - AUTO_FUNC_DEBUG; - - try - { - //If device is streaming, need to stop it! - if (Streaming()) - { - SetStreaming (false); - } - - //If device is active (meaning stream is open) we need to close it. - if (Active()) - { - SetActive (false); - } - - } - catch (...) - { - //destructors should absorb exceptions, no harm in logging though!! - DEBUG_MSG ("Exception during destructor"); - } - -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::UpdateDeviceInfo -// -//! Updates Device Information about channels, sampling rates, buffer sizes. -//! -//! \return WTErr. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::UpdateDeviceInfo () -{ - AUTO_FUNC_DEBUG; - - WTErr retVal = eNoErr; - - // Some devices change the ID during restart - WTErr errId = UpdateDeviceId(); - - // Update all devices parts regardless of errors - WTErr errName = UpdateDeviceName(); - WTErr errIn = UpdateDeviceInputs(); - WTErr errOut = UpdateDeviceOutputs(); - WTErr errSR = eNoErr; - WTErr errBS = eNoErr; - - errSR = UpdateDeviceSampleRates(); - errBS = UpdateDeviceBufferSizes(); - - if(errId != eNoErr || errName != eNoErr || errIn != eNoErr || errOut != eNoErr || errSR != eNoErr || errBS != eNoErr) - { - retVal = eCoreAudioFailed; - } - - return retVal; -} - - -WTErr WCMRCoreAudioDevice::UpdateDeviceId() -{ - //Get device count... - UInt32 propSize = 0; - WTErr retVal = eNoErr; - OSStatus osErr = AudioHardwareGetPropertyInfo (kAudioHardwarePropertyDevices, &propSize, NULL); - ASSERT_ERROR(osErr, "AudioHardwareGetProperty 1"); - if (WUIsError(osErr)) - throw osErr; - - size_t numDevices = propSize / sizeof (AudioDeviceID); - AudioDeviceID* deviceIDs = new AudioDeviceID[numDevices]; - - //retrieve the device IDs - propSize = numDevices * sizeof (AudioDeviceID); - osErr = AudioHardwareGetProperty (kAudioHardwarePropertyDevices, &propSize, deviceIDs); - ASSERT_ERROR(osErr, "Error while getting audio devices: AudioHardwareGetProperty 2"); - if (WUIsError(osErr)) - throw osErr; - - //now add the ones that are not there... - for (size_t deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) - { - DeviceInfo* pDevInfo = 0; - - //Get device name and create new DeviceInfo entry - //Get property name size. - osErr = AudioDeviceGetPropertyInfo(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL); - if (osErr == kAudioHardwareNoError) - { - //Get property: name. - char* deviceName = new char[propSize]; - osErr = AudioDeviceGetProperty(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, deviceName); - if (osErr == kAudioHardwareNoError) - { - if ( (m_DeviceName == deviceName) && - (m_DeviceID != deviceIDs[deviceIndex]) ) { - - m_DeviceID = deviceIDs[deviceIndex]; - - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Current device has changed it's id."); - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device name. Device ID: " << m_DeviceID); - } - - delete [] deviceName; - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device name prop Info. Device ID: " << m_DeviceID); - } - } - - delete [] deviceIDs; - return retVal; -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::UpdateDeviceName -// -//! Updates Device name. -//! -//! Use 'kAudioDevicePropertyDeviceName' -//! -//! 1. Get property name size. -//! 2. Get property: name. -//! -//! \return WTErr. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::UpdateDeviceName() -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - - // Initiate name to unknown. - m_DeviceName = "Unknown"; - - //! 1. Get property name size. - err = AudioDeviceGetPropertyInfo(m_DeviceID, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL); - if (err == kAudioHardwareNoError) - { - //! 2. Get property: name. - char* deviceName = new char[propSize]; - err = AudioDeviceGetProperty(m_DeviceID, 0, 0, kAudioDevicePropertyDeviceName, &propSize, deviceName); - if (err == kAudioHardwareNoError) - { - m_DeviceName = deviceName; - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device name. Device ID: " << m_DeviceID); - } - - delete [] deviceName; - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device name property size. Device ID: " << m_DeviceID); - } - - return retVal; -} - -//********************************************************************************************** -// WCMRCoreAudioDevice::UpdateDeviceInputs -// -//! Updates Device Inputs. -//! -//! Use 'kAudioDevicePropertyStreamConfiguration' -//! This property returns the stream configuration of the device in an -//! AudioBufferList (with the buffer pointers set to NULL) which describes the -//! list of streams and the number of channels in each stream. This corresponds -//! to what will be passed into the IOProc. -//! -//! 1. Get property cannels input size. -//! 2. Get property: cannels input. -//! 3. Update input channels -//! -//! \return WTErr. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::UpdateDeviceInputs() -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - int maxInputChannels = 0; - - // 1. Get property cannels input size. - err = AudioDeviceGetPropertyInfo (m_DeviceID, 0, 1/* Input */, kAudioDevicePropertyStreamConfiguration, &propSize, NULL); - if (err == kAudioHardwareNoError) - { - //! 2. Get property: cannels input. - - // Allocate size according to the property size. Note that this is a variable sized struct... - AudioBufferList *pStreamBuffers = (AudioBufferList *)malloc(propSize); - - if (pStreamBuffers) - { - memset (pStreamBuffers, 0, propSize); - - // Get the Input channels - err = AudioDeviceGetProperty (m_DeviceID, 0, true/* Input */, kAudioDevicePropertyStreamConfiguration, &propSize, pStreamBuffers); - if (err == kAudioHardwareNoError) - { - // Calculate the number of input channels - for (UInt32 streamIndex = 0; streamIndex < pStreamBuffers->mNumberBuffers; streamIndex++) - { - maxInputChannels += pStreamBuffers->mBuffers[streamIndex].mNumberChannels; - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Input channels. Device Name: " << m_DeviceName.c_str()); - } - - free (pStreamBuffers); - } - else - { - retVal = eMemOutOfMemory; - DEBUG_MSG("Faild to allocate memory. Device Name: " << m_DeviceName.c_str()); - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Input channels property size. Device Name: " << m_DeviceName.c_str()); - } - - // Update input channels - m_InputChannels.clear(); - - for (int channel = 0; channel < maxInputChannels; channel++) - { - CFStringRef cfName; - std::stringstream chNameStream; - UInt32 nameSize = 0; - OSStatus error = kAudioHardwareNoError; - - error = AudioDeviceGetPropertyInfo (m_DeviceID, - channel + 1, - true /* Input */, - kAudioDevicePropertyChannelNameCFString, - &nameSize, - NULL); - - if (error == kAudioHardwareNoError) - { - error = AudioDeviceGetProperty (m_DeviceID, - channel + 1, - true /* Input */, - kAudioDevicePropertyChannelNameCFString, - &nameSize, - &cfName); - } - - bool decoded = false; - char* cstr_name = 0; - if (error == kAudioHardwareNoError) - { - CFIndex length = CFStringGetLength(cfName); - CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); - cstr_name = new char[maxSize]; - decoded = CFStringGetCString(cfName, cstr_name, maxSize, kCFStringEncodingUTF8); - } - - chNameStream << (channel+1) << " - "; - - if (cstr_name && decoded && (0 != std::strlen(cstr_name) ) ) { - chNameStream << cstr_name; - } - else - { - chNameStream << "Input " << (channel+1); - } - - m_InputChannels.push_back (chNameStream.str()); - - delete [] cstr_name; - } - - return retVal; -} - -//********************************************************************************************** -// WCMRCoreAudioDevice::UpdateDeviceOutputs -// -//! Updates Device Outputs. -//! -//! Use 'kAudioDevicePropertyStreamConfiguration' -//! This property returns the stream configuration of the device in an -//! AudioBufferList (with the buffer pointers set to NULL) which describes the -//! list of streams and the number of channels in each stream. This corresponds -//! to what will be passed into the IOProc. -//! -//! 1. Get property cannels output size. -//! 2. Get property: cannels output. -//! 3. Update output channels -//! -//! \return Nothing. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::UpdateDeviceOutputs() -{ - AUTO_FUNC_DEBUG; - - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - int maxOutputChannels = 0; - - //! 1. Get property cannels output size. - err = AudioDeviceGetPropertyInfo (m_DeviceID, 0, 0/* Output */, kAudioDevicePropertyStreamConfiguration, &propSize, NULL); - if (err == kAudioHardwareNoError) - { - //! 2. Get property: cannels output. - - // Allocate size according to the property size. Note that this is a variable sized struct... - AudioBufferList *pStreamBuffers = (AudioBufferList *)malloc(propSize); - if (pStreamBuffers) - { - memset (pStreamBuffers, 0, propSize); - - // Get the Output channels - err = AudioDeviceGetProperty (m_DeviceID, 0, 0/* Output */, kAudioDevicePropertyStreamConfiguration, &propSize, pStreamBuffers); - if (err == kAudioHardwareNoError) - { - // Calculate the number of output channels - for (UInt32 streamIndex = 0; streamIndex < pStreamBuffers->mNumberBuffers; streamIndex++) - { - maxOutputChannels += pStreamBuffers->mBuffers[streamIndex].mNumberChannels; - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Output channels. Device Name: " << m_DeviceName.c_str()); - } - free (pStreamBuffers); - } - else - { - retVal = eMemOutOfMemory; - DEBUG_MSG("Faild to allocate memory. Device Name: " << m_DeviceName.c_str()); - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Output channels property size. Device Name: " << m_DeviceName.c_str()); - } - - // Update output channels - m_OutputChannels.clear(); - for (int channel = 0; channel < maxOutputChannels; channel++) - { - CFStringRef cfName; - std::stringstream chNameStream; - UInt32 nameSize = 0; - OSStatus error = kAudioHardwareNoError; - - error = AudioDeviceGetPropertyInfo (m_DeviceID, - channel + 1, - false /* Output */, - kAudioDevicePropertyChannelNameCFString, - &nameSize, - NULL); - - if (error == kAudioHardwareNoError) - { - error = AudioDeviceGetProperty (m_DeviceID, - channel + 1, - false /* Output */, - kAudioDevicePropertyChannelNameCFString, - &nameSize, - &cfName); - } - - bool decoded = false; - char* cstr_name = 0; - if (error == kAudioHardwareNoError ) - { - CFIndex length = CFStringGetLength(cfName); - CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); - cstr_name = new char[maxSize]; - decoded = CFStringGetCString(cfName, cstr_name, maxSize, kCFStringEncodingUTF8); - } - - chNameStream << (channel+1) << " - "; - - if (cstr_name && decoded && (0 != std::strlen(cstr_name) ) ) { - chNameStream << cstr_name; - } - else - { - chNameStream << "Output " << (channel+1); - } - - m_OutputChannels.push_back (chNameStream.str()); - - delete [] cstr_name; - } - - return retVal; -} - -//********************************************************************************************** -// WCMRCoreAudioDevice::UpdateDeviceSampleRates -// -//! Updates Device Sample rates. -//! -//! Use 'kAudioDevicePropertyAvailableNominalSampleRates' -//! -//! 1. Get sample rate property size. -//! 2. Get property: sample rates. -//! 3. Update sample rates -//! -//! \return Nothing. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::UpdateDeviceSampleRates() -{ - AUTO_FUNC_DEBUG; - - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - - m_SamplingRates.clear(); - - //! 1. Get sample rate property size. - err = AudioDeviceGetPropertyInfo(m_DeviceID, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, NULL); - if (err == kAudioHardwareNoError) - { - //! 2. Get property: cannels output. - - // Allocate size accrding to the number of audio values - int numRates = propSize / sizeof(AudioValueRange); - AudioValueRange* supportedRates = new AudioValueRange[numRates]; - - // Get sampling rates from Audio device - err = AudioDeviceGetProperty(m_DeviceID, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, supportedRates); - if (err == kAudioHardwareNoError) - { - //! 3. Update sample rates - - // now iterate through our standard SRs - for(int ourSR=0; gAllSampleRates[ourSR] > 0; ourSR++) - { - //check to see if our SR is in the supported rates... - for (int deviceSR = 0; deviceSR < numRates; deviceSR++) - { - if ((supportedRates[deviceSR].mMinimum <= gAllSampleRates[ourSR]) && - (supportedRates[deviceSR].mMaximum >= gAllSampleRates[ourSR])) - { - m_SamplingRates.push_back ((int)gAllSampleRates[ourSR]); - break; - } - } - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Sample rates. Device Name: " << m_DeviceName.c_str()); - } - - delete [] supportedRates; - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Sample rates property size. Device Name: " << m_DeviceName.c_str()); - } - - return retVal; -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::UpdateDeviceBufferSizes_Simple -// -// Use kAudioDevicePropertyBufferFrameSizeRange -// -// in case of 'eMatchedDuplexDevices' and a matching device exists return common device name -// in all other cases retur base class function implementation -// -// 1. Get buffer size range -// 2. Run on all ranges and add them to the list -// -// \return error code -// -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::UpdateDeviceBufferSizes () -{ - AUTO_FUNC_DEBUG; - - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - - // Clear buffer sizes - m_BufferSizes.clear(); - - // 1. Get buffer size range - AudioValueRange bufferSizesRange; - propSize = sizeof (AudioValueRange); - err = AudioDeviceGetProperty (m_DeviceID, 0, 0, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &bufferSizesRange); - if(err == kAudioHardwareNoError) - { - // 2. Run on all ranges and add them to the list - for(int bsize=0; gAllBufferSizes[bsize] > 0; bsize++) - { - if ((bufferSizesRange.mMinimum <= gAllBufferSizes[bsize]) && (bufferSizesRange.mMaximum >= gAllBufferSizes[bsize])) - { - m_BufferSizes.push_back (gAllBufferSizes[bsize]); - } - } - - //if we didn't get a single hit, let's simply add the min. and the max... - if (m_BufferSizes.empty()) - { - m_BufferSizes.push_back ((int)bufferSizesRange.mMinimum); - m_BufferSizes.push_back ((int)bufferSizesRange.mMaximum); - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device buffer sizes range. Device Name: " << m_DeviceName.c_str()); - } - - return retVal; -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::DeviceName -// -//! in case of 'eMatchedDuplexDevices' and a matching device exists return common device name -//! in all other cases retur base class function implementation -//! -//! \param none -//! -//! \return current device name -//! -//********************************************************************************************** -const std::string& WCMRCoreAudioDevice::DeviceName() const -{ - return WCMRAudioDevice::DeviceName(); -} - -//********************************************************************************************** -// WCMRCoreAudioDevice::InputChannels -// -//! return base class function implementation -//! -//! \param none -//! -//! \return base class function implementation -//! -//********************************************************************************************** -const std::vector& WCMRCoreAudioDevice::InputChannels() -{ - return WCMRAudioDevice::InputChannels(); -} - -//********************************************************************************************** -// WCMRCoreAudioDevice::OutputChannels -// -//! in case of 'eMatchedDuplexDevices' return matching device output channel if there is one -//! in all other cases retur base class function implementation -//! -//! \param none -//! -//! \return list of output channels of current device -//! -//********************************************************************************************** -const std::vector& WCMRCoreAudioDevice::OutputChannels() -{ - return WCMRAudioDevice::OutputChannels(); -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::SamplingRates -// -//! in case of 'eMatchedDuplexDevices' and a matching device exists return common sample rate -//! in all other cases retur base class function implementation -//! -//! \param none -//! -//! \return current sample rate -//! -//********************************************************************************************** -const std::vector& WCMRCoreAudioDevice::SamplingRates() -{ - return WCMRAudioDevice::SamplingRates(); -} - -//********************************************************************************************** -// WCMRCoreAudioDevice::CurrentSamplingRate -// -//! The device's current sampling rate. This may be overridden, if the device needs to -//! query the driver for the current rate. -//! -//! \param none -//! -//! \return The device's current sampling rate. -1 on error. -//! -//********************************************************************************************** -int WCMRCoreAudioDevice::CurrentSamplingRate () -{ - AUTO_FUNC_DEBUG; - //ToDo: Perhaps for ASIO devices that are active, we should retrive the SR from the device... - UInt32 propSize = 0; - OSStatus err = kAudioHardwareNoError; - - Float64 currentNominalRate; - propSize = sizeof (currentNominalRate); - err = kAudioHardwareNoError; - if (AudioDeviceGetProperty(m_DeviceID, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, ¤tNominalRate) != kAudioHardwareNoError) - err = AudioDeviceGetProperty(m_DeviceID, 0, 1, kAudioDevicePropertyNominalSampleRate, &propSize, ¤tNominalRate); - - if (err == kAudioHardwareNoError) - m_CurrentSamplingRate = (int)currentNominalRate; - else - { - DEBUG_MSG("Unable to get sampling rate!"); - } - - return (m_CurrentSamplingRate); -} - - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::SetCurrentSamplingRate -// -//! Change the sampling rate to be used by the device. -//! -//! \param newRate : The rate to use (samples per sec). -//! -//! \return eNoErr always. The derived classes may return error codes. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::SetCurrentSamplingRate (int newRate) -{ - AUTO_FUNC_DEBUG; - std::vector::iterator intIter; - WTErr retVal = eNoErr; - - //changes the status. - int oldRate = CurrentSamplingRate(); - bool oldActive = Active(); - - //no change, nothing to do - if (oldRate == newRate) - goto Exit; - - //see if this is one of our supported rates... - intIter = find(m_SamplingRates.begin(), m_SamplingRates.end(), newRate); - if (intIter == m_SamplingRates.end()) - { - //Can't change, perhaps use an "invalid param" type of error - retVal = eCommandLineParameter; - goto Exit; - } - - if (Streaming()) - { - //Can't change, perhaps use an "in use" type of error - retVal = eGenericErr; - goto Exit; - } - - if (oldActive) - { - //Deactivate it for the change... - SetActive (false); - } - - retVal = SetAndCheckCurrentSamplingRate (newRate); - if(retVal == eNoErr) - { - retVal = UpdateDeviceInfo (); - } - - //reactivate it. - if (oldActive) - { - retVal = SetActive (true); - } - -Exit: - - return (retVal); - -} - -//********************************************************************************************** -// WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate -// -//! Change the sampling rate to be used by the device. -//! -//! \param newRate : The rate to use (samples per sec). -//! -//! \return eNoErr always. The derived classes may return error codes. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::SetAndCheckCurrentSamplingRate (int newRate) -{ - AUTO_FUNC_DEBUG; - std::vector::iterator intIter; - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - - // 1. Set new sampling rate - Float64 newNominalRate = newRate; - propSize = sizeof (Float64); - err = AudioDeviceSetProperty(m_DeviceID, NULL, 0, 0, kAudioDevicePropertyNominalSampleRate, propSize, &newNominalRate); - - if (err != kAudioHardwareNoError) - { - retVal = eCoreAudioFailed; - DEBUG_MSG ("Unable to set SR! Device name: " << m_DeviceName.c_str()); - } - else - { - // 2. wait for the SR to actually change... - - // Set total time out time - int tryAgain = ((PROPERTY_CHANGE_TIMEOUT_SECONDS * 1000) / PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS) ; - int actualWait = 0; - Float64 actualSamplingRate = 0.0; - - // Run as ling as time out is not finished - while (tryAgain) - { - // Get current sampling rate - err = AudioDeviceGetProperty(m_DeviceID, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &actualSamplingRate); - if (err == kAudioHardwareNoError) - { - if (actualSamplingRate == newNominalRate) - { - //success, let's get out! - break; - } - } - else - { - //error reading rate, but let's not complain too much! - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Could not read Sampling Rate for verification."); - DEBUG_MSG ("Unable to get SR. Device name: " << m_DeviceName.c_str()); - } - - // oh well...there's always another millisecond... - wvThread::sleep_milliseconds (PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS); - tryAgain--; - actualWait++; - } - - // If sample rate actually changed - if (tryAgain != 0) - { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Changed the Sampling Rate."); - - // Update member with new rate - m_CurrentSamplingRate = newRate; - - char debugMsg[128]; - snprintf (debugMsg, sizeof(debugMsg), "Actual Wait for SR Change was %d milliseconds", actualWait * PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS); - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)debugMsg); - } - // If sample rate did not change after time out - else - { - // Check if current device sample rate is supported - bool found = false; - for(int i = 0; gAllSampleRates[i] > 0; i++) - { - if (fabs(gAllSampleRates[i] - actualSamplingRate) < 0.01) { - found = true; - } - } - - if (found) { - // Update member with last read value - m_CurrentSamplingRate = static_cast(actualSamplingRate); - - char debugMsg[128]; - snprintf (debugMsg, sizeof(debugMsg), "Unable to change SR, even after waiting for %d milliseconds", actualWait * PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS); - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)debugMsg); - - float sample_rate_update = actualSamplingRate; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::SamplingRateChanged, (void *)&sample_rate_update); - } else { - retVal = eGenericErr; - } - } - } - - return (retVal); -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::BufferSizes -// -//! in case of 'eMatchedDuplexDevices' and a matching device exists return common buffer sizes -//! in all other cases retur base class function implementation -//! -//! \param none -//! -//! \return current sample rate -//! -//********************************************************************************************** -const std::vector& WCMRCoreAudioDevice::BufferSizes() -{ - return WCMRAudioDevice::BufferSizes(); -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::CurrentBufferSize -// -//! The device's current buffer size in use. This may be overridden, if the device needs to -//! query the driver for the current size. -//! -//! \param none -//! -//! \return The device's current buffer size. 0 on error. -//! -//********************************************************************************************** -int WCMRCoreAudioDevice::CurrentBufferSize () -{ - AUTO_FUNC_DEBUG; - - return (m_CurrentBufferSize); -} - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::SetCurrentBufferSize -// -//! Change the buffer size to be used by the device. This will most likely be overridden, -//! the base class simply updates the member variable. -//! -//! \param newSize : The buffer size to use (in sample-frames) -//! -//! \return eNoErr always. The derived classes may return error codes. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::SetCurrentBufferSize (int newSize) -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - std::vector::iterator intIter; - - //changes the status. - int oldSize = CurrentBufferSize(); - bool oldActive = Active(); - - //same size, nothing to do. - if (oldSize == newSize) - goto Exit; - - if (Streaming()) - { - //Can't change, perhaps use an "in use" type of error - retVal = eGenericErr; - goto Exit; - } - - if (oldActive) - { - //Deactivate it for the change... - SetActive (false); - } - - // when audio device is inactive it is safe to set a working buffer size according to new buffer size - // if 'newSize' is not a valid buffer size, another valid buffer size will be set - retVal = SetWorkingBufferSize(newSize); - if(retVal != eNoErr) - { - DEBUG_MSG("Unable to set a working buffer size. Device Name: " << DeviceName().c_str()); - goto Exit; - } - - //reactivate it. - if (oldActive) - { - retVal = SetActive (true); - if(retVal != eNoErr) - { - DEBUG_MSG("Unable to activate device. Device Name: " << DeviceName().c_str()); - goto Exit; - } - } - -Exit: - - return (retVal); -} - -WTErr WCMRCoreAudioDevice::SetWorkingBufferSize(int newSize) -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - - // 1. Set new buffer size - err = SetBufferSizesByIO(newSize); - - // If there's no error it means this buffer size is supported - if(err == kAudioHardwareNoError) - { - m_CurrentBufferSize = newSize; - } - // If there was an error it means that this buffer size was not supported - else - { - // In case the new buffer size could not be set, set another working buffer size - - // Run on all buffer sizes: - - // Try setting buffer sizes that are bigger then selected buffer size first, - // Since bigger buffer sizes usually work safer - for(std::vector::const_iterator iter = m_BufferSizes.begin();iter != m_BufferSizes.end();++iter) - { - int nCurBS = *iter; - - if(nCurBS > newSize) - { - // Try setting current buffer size - err = SetBufferSizesByIO(nCurBS); - - // in case buffer size is valid - if(err == kAudioHardwareNoError) - { - // Set current buffer size - m_CurrentBufferSize = nCurBS; - break; - } - } - } - - // If bigger buffer sizes failed, go to smaller buffer sizes - if(err != kAudioHardwareNoError) - { - for(std::vector::const_iterator iter = m_BufferSizes.begin();iter != m_BufferSizes.end();++iter) - { - int nCurBS = *iter; - - if(nCurBS < newSize) - { - // Try setting current buffer size - err = SetBufferSizesByIO(*iter); - - // in case buffer size is valid - if(err == kAudioHardwareNoError) - { - // Set current buffer size - m_CurrentBufferSize = *iter; - break; - } - } - } - } - - // Check if a valid buffer size was found - if(err == kAudioHardwareNoError) - { - // Notify that a different sample rate is set - char debugMsg[256]; - snprintf (debugMsg, sizeof(debugMsg), "Could not set buffer size: %d, Set buffer size to: %d.", newSize, m_CurrentBufferSize); - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)debugMsg); - } - // if there was no buffer size that could be set - else - { - // Set the parameter buffer size by default, set a debug message - m_CurrentBufferSize = newSize; - DEBUG_MSG("Unable to set any buffer size. Device Name: " << m_DeviceName.c_str()); - } - } - - return retVal; -} - -OSStatus WCMRCoreAudioDevice::SetBufferSizesByIO(int newSize) -{ - OSStatus err = kAudioHardwareNoError; - - // 1. Set new buffer size - UInt32 bufferSize = (UInt32)newSize; - UInt32 propSize = sizeof (UInt32); - - // Set new buffer size to input - if (!m_InputChannels.empty()) - { - err = AudioDeviceSetProperty(m_DeviceID, NULL, 0, 1, kAudioDevicePropertyBufferFrameSize, propSize, &bufferSize); - } - else - { - err = AudioDeviceSetProperty(m_DeviceID, NULL, 0, 0, kAudioDevicePropertyBufferFrameSize, propSize, &bufferSize); - } - - return err; -} - -//********************************************************************************************** -// WCMRCoreAudioDevice::ConnectionStatus -// -//! Retrieves the device's current connection status. This will most likely be overridden, -//! in case some driver communication is required to query the status. -//! -//! \param none -//! -//! \return A ConnectionStates value. -//! -//********************************************************************************************** -WCMRCoreAudioDevice::ConnectionStates WCMRCoreAudioDevice::ConnectionStatus () -{ - AUTO_FUNC_DEBUG; - //ToDo: May want to do something more to extract the actual status! - return (m_ConnectionStatus); - -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::EnableAudioUnitIO -// -//! Sets up the AUHAL for IO, allowing changes to the devices to be used by the AudioUnit. -//! -//! \param none -//! -//! \return eNoErr on success, an error code on failure. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::EnableAudioUnitIO() -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - - UInt32 enableIO = 1; - if (!m_InputChannels.empty()) - { - /////////////// - //ENABLE IO (INPUT) - //You must enable the Audio Unit (AUHAL) for input - - //Enable input on the AUHAL - err = AudioUnitSetProperty(m_AUHALAudioUnit, - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, - AUHAL_INPUT_ELEMENT, - &enableIO, sizeof(enableIO)); - - if (err) - { - DEBUG_MSG("Couldn't Enable IO on input scope of input element, error = " << err); - retVal = eGenericErr; - goto Exit; - } - } - - //disable Output on the AUHAL if there's no output - if (m_OutputChannels.empty()) - enableIO = 0; - else - enableIO = 1; - - err = AudioUnitSetProperty(m_AUHALAudioUnit, - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, - AUHAL_OUTPUT_ELEMENT, - &enableIO, sizeof(enableIO)); - - if (err) - { - DEBUG_MSG("Couldn't Enable/Disable IO on output scope of output element, error = " << err); - retVal = eGenericErr; - goto Exit; - } - -Exit: - return retVal; -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::EnableListeners -// -//! Sets up listeners to listen for Audio Device property changes, so that app can be notified. -//! -//! \param none -//! -//! \return eNoErr on success, an error code on failure. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::EnableListeners() -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - - //listner for SR change... - err = AudioDeviceAddPropertyListener(m_DeviceID, 0, 0, kAudioDevicePropertyNominalSampleRate, - StaticPropertyChangeProc, this); - - if (err) - { - DEBUG_MSG("Couldn't Setup SR Property Listner, error = " << err); - retVal = eGenericErr; - goto Exit; - } - -#if ENABLE_DEVICE_CHANGE_LISTNER - { - //listner for device change... - - err = AudioDeviceAddPropertyListener (m_DeviceID, - kAudioPropertyWildcardChannel, - true, - kAudioDevicePropertyDeviceHasChanged, - StaticPropertyChangeProc, - this); - - if (err) - { - DEBUG_MSG("Couldn't Setup device change Property Listner, error = " << err); - retVal = eGenericErr; - goto Exit; - } - } -#endif //ENABLE_DEVICE_CHANGE_LISTNER - - //listner for dropouts... - err = AudioDeviceAddPropertyListener(m_DeviceID, 0, 0, kAudioDeviceProcessorOverload, - StaticPropertyChangeProc, this); - - if (err) - { - DEBUG_MSG("Couldn't Setup Processor Overload Property Listner, error = " << err); - retVal = eGenericErr; - goto Exit; - } - - -Exit: - return retVal; -} - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::DisableListeners -// -//! Undoes the work done by EnableListeners -//! -//! \param none -//! -//! \return eNoErr on success, an error code on failure. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::DisableListeners() -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - - //listner for SR change... - err = AudioDeviceRemovePropertyListener(m_DeviceID, 0, 0, kAudioDevicePropertyNominalSampleRate, - StaticPropertyChangeProc); - - if (err) - { - DEBUG_MSG("Couldn't Cleanup SR Property Listner, error = " << err); - //not sure if we need to report this... - } - -#if ENABLE_DEVICE_CHANGE_LISTNER - { - err = AudioDeviceRemovePropertyListener (m_DeviceID, - kAudioPropertyWildcardChannel, - true/* Input */, - kAudioDevicePropertyDeviceHasChanged, - StaticPropertyChangeProc); - - if (err) - { - DEBUG_MSG("Couldn't Cleanup device input stream change Property Listner, error = " << err); - //not sure if we need to report this... - } - - } -#endif //ENABLE_DEVICE_CHANGE_LISTNER - - err = AudioDeviceRemovePropertyListener(m_DeviceID, 0, 0, kAudioDeviceProcessorOverload, - StaticPropertyChangeProc); - - if (err) - { - DEBUG_MSG("Couldn't Cleanup device change Property Listner, error = " << err); - //not sure if we need to report this... - } - - - return retVal; -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::StaticPropertyChangeProc -// -//! The property change function called (as a result of EnableListeners) when device properties change. -//! It calls upon the non-static PropertyChangeProc to do the work. -//! -//! \param inDevice : The audio device in question. -//! \param inChannel : The channel on which the property has change. -//! \param isInput : If the change is for Input. -//! \param inPropertyID : The property that has changed. -//! \param inClientData: What was passed when listener was enabled, in our case teh WCMRCoreAudioDevice object. -//! -//! \return 0 always. -//! -//********************************************************************************************** -OSStatus WCMRCoreAudioDevice::StaticPropertyChangeProc (AudioDeviceID /*inDevice*/, UInt32 /*inChannel*/, Boolean /*isInput*/, - AudioDevicePropertyID inPropertyID, void *inClientData) -{ - if (inClientData) - { - WCMRCoreAudioDevice* pCoreDevice = (WCMRCoreAudioDevice *)inClientData; - pCoreDevice->PropertyChangeProc (inPropertyID); - } - - return 0; -} - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::PropertyChangeProc -// -//! The non-static property change proc. Gets called when properties change. Since this gets called -//! on an arbitrary thread, we simply update the request counters and return. -//! -//! \param none -//! -//! \return nothing. -//! -//********************************************************************************************** -void WCMRCoreAudioDevice::PropertyChangeProc (AudioDevicePropertyID inPropertyID) -{ - switch (inPropertyID) - { - case kAudioDevicePropertyNominalSampleRate: - m_SRChangeRequested++; - break; -#if ENABLE_DEVICE_CHANGE_LISTNER - case kAudioDevicePropertyDeviceHasChanged: - { - m_ResetRequested++; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); - } - break; -#endif //ENABLE_DEVICE_CHANGE_LISTNER - case kAudioDeviceProcessorOverload: - { - if (m_IgnoreThisDrop) - m_IgnoreThisDrop = false; //We'll ignore once, just once! - else - m_DropsDetected++; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::Dropout ); - break; - } - default: - break; - } -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::SetupAUHAL -// -//! Sets up the AUHAL AudioUnit for device IO. -//! -//! \param none -//! -//! \return eNoErr on success, an error code on failure. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::SetupAUHAL() -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - Component comp; - ComponentDescription desc; - AudioStreamBasicDescription streamFormatToUse, auhalStreamFormat; - - //There are several different types of Audio Units. - //Some audio units serve as Outputs, Mixers, or DSP - //units. See AUComponent.h for listing - desc.componentType = kAudioUnitType_Output; - - //Every Component has a subType, which will give a clearer picture - //of what this components function will be. - desc.componentSubType = kAudioUnitSubType_HALOutput; - - //all Audio Units in AUComponent.h must use - //"kAudioUnitManufacturer_Apple" as the Manufacturer - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - - //Finds a component that meets the desc spec's - comp = FindNextComponent(NULL, &desc); - if (comp == NULL) - { - DEBUG_MSG("Couldn't find AUHAL Component"); - retVal = eGenericErr; - goto Exit; - } - - //gains access to the services provided by the component - OpenAComponent(comp, &m_AUHALAudioUnit); - - - retVal = EnableAudioUnitIO(); - if (retVal != eNoErr) - goto Exit; - - //Now setup the device to use by the audio unit... - - //input - if (!m_InputChannels.empty()) - { - err = AudioUnitSetProperty(m_AUHALAudioUnit, kAudioOutputUnitProperty_CurrentDevice, - kAudioUnitScope_Global, AUHAL_INPUT_ELEMENT, - &m_DeviceID, sizeof(m_DeviceID)); - - if (err) - { - DEBUG_MSG("Couldn't Set the audio device property for Input Element Global scope, error = " << err); - retVal = eGenericErr; - goto Exit; - } - } - - //output - if (!m_OutputChannels.empty()) - { - err = AudioUnitSetProperty(m_AUHALAudioUnit, kAudioOutputUnitProperty_CurrentDevice, - kAudioUnitScope_Global, AUHAL_OUTPUT_ELEMENT, - &m_DeviceID, sizeof(m_DeviceID)); - - if (err) - { - DEBUG_MSG("Couldn't Set the audio device property for Output Element Global scope, error = " << err); - retVal = eGenericErr; - goto Exit; - } - } - - //also set Sample Rate... - { - retVal = SetAndCheckCurrentSamplingRate(m_CurrentSamplingRate); - if(retVal != eNoErr) - { - DEBUG_MSG ("Unable to set SR, error = " << err); - goto Exit; - } - } - - //now set the buffer size... - { - err = SetWorkingBufferSize(m_CurrentBufferSize); - if (err) - { - DEBUG_MSG("Couldn't Set the buffer size property, error = " << err); - //we don't really quit here..., just keep going even if this does not work, - //the AUHAL is supposed to take care of this by way of slicing... - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Could not set buffer size."); - - } - } - - //convertor quality - { - UInt32 quality = kAudioConverterQuality_Max; - propSize = sizeof (quality); - err = AudioUnitSetProperty(m_AUHALAudioUnit, - kAudioUnitProperty_RenderQuality, kAudioUnitScope_Global, - AUHAL_OUTPUT_ELEMENT, - &quality, sizeof (quality)); - - if (err != kAudioHardwareNoError) - { - DEBUG_MSG ("Unable to set Convertor Quality, error = " << err); - retVal = eGenericErr; - goto Exit; - } - } - - memset (&auhalStreamFormat, 0, sizeof (auhalStreamFormat)); - propSize = sizeof (auhalStreamFormat); - err = AudioUnitGetProperty(m_AUHALAudioUnit, - kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, - AUHAL_INPUT_ELEMENT, - &auhalStreamFormat, &propSize); - if (err != kAudioHardwareNoError) - { - DEBUG_MSG ("Unable to get Input format, error = " << err); - retVal = eGenericErr; - goto Exit; - } - - if (auhalStreamFormat.mSampleRate != (Float64)m_CurrentSamplingRate) - { - TRACE_MSG ("AUHAL's Input SR differs from expected SR, expected = " << m_CurrentSamplingRate << ", AUHAL's = " << (UInt32)auhalStreamFormat.mSampleRate); - } - - //format, and slice size... - memset (&streamFormatToUse, 0, sizeof (streamFormatToUse)); - streamFormatToUse.mFormatID = kAudioFormatLinearPCM; - streamFormatToUse.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; - streamFormatToUse.mFramesPerPacket = 1; - streamFormatToUse.mBitsPerChannel = sizeof (float) * 8; - streamFormatToUse.mSampleRate = auhalStreamFormat.mSampleRate; - - if (!m_InputChannels.empty()) - { - streamFormatToUse.mChannelsPerFrame = m_InputChannels.size(); - streamFormatToUse.mBytesPerFrame = sizeof (float)*streamFormatToUse.mChannelsPerFrame; - streamFormatToUse.mBytesPerPacket = streamFormatToUse.mBytesPerFrame; - propSize = sizeof (streamFormatToUse); - err = AudioUnitSetProperty(m_AUHALAudioUnit, - kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, - AUHAL_INPUT_ELEMENT, - &streamFormatToUse, sizeof (streamFormatToUse)); - - if (err != kAudioHardwareNoError) - { - DEBUG_MSG ("Unable to set Input format, error = " << err); - retVal = eGenericErr; - goto Exit; - } - - UInt32 bufferSize = m_CurrentBufferSize; - err = AudioUnitSetProperty(m_AUHALAudioUnit, - kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Output, - AUHAL_INPUT_ELEMENT, - &bufferSize, sizeof (bufferSize)); - - if (err != kAudioHardwareNoError) - { - DEBUG_MSG ("Unable to set Input frames, error = " << err); - retVal = eGenericErr; - goto Exit; - } - - } - - if (!m_OutputChannels.empty()) - { - err = AudioUnitGetProperty(m_AUHALAudioUnit, - kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, - AUHAL_OUTPUT_ELEMENT, - &auhalStreamFormat, &propSize); - if (err != kAudioHardwareNoError) - { - DEBUG_MSG ("Unable to get Output format, error = " << err); - retVal = eGenericErr; - goto Exit; - } - - if (auhalStreamFormat.mSampleRate != (Float64)m_CurrentSamplingRate) - { - TRACE_MSG ("AUHAL's Output SR differs from expected SR, expected = " << m_CurrentSamplingRate << ", AUHAL's = " << (UInt32)auhalStreamFormat.mSampleRate); - } - - - streamFormatToUse.mChannelsPerFrame = m_OutputChannels.size(); - streamFormatToUse.mBytesPerFrame = sizeof (float)*streamFormatToUse.mChannelsPerFrame; - streamFormatToUse.mBytesPerPacket = streamFormatToUse.mBytesPerFrame; - streamFormatToUse.mSampleRate = auhalStreamFormat.mSampleRate; - propSize = sizeof (streamFormatToUse); - err = AudioUnitSetProperty(m_AUHALAudioUnit, - kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, - AUHAL_OUTPUT_ELEMENT, - &streamFormatToUse, sizeof (streamFormatToUse)); - - if (err != kAudioHardwareNoError) - { - DEBUG_MSG ("Unable to set Output format, error = " << err); - retVal = eGenericErr; - goto Exit; - } - - UInt32 bufferSize = m_CurrentBufferSize; - err = AudioUnitSetProperty(m_AUHALAudioUnit, - kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Input, - AUHAL_OUTPUT_ELEMENT, - &bufferSize, sizeof (bufferSize)); - - if (err != kAudioHardwareNoError) - { - DEBUG_MSG ("Unable to set Output frames, error = " << err); - retVal = eGenericErr; - goto Exit; - } - - } - - //setup callback (IOProc) - { - AURenderCallbackStruct renderCallback; - memset (&renderCallback, 0, sizeof (renderCallback)); - propSize = sizeof (renderCallback); - renderCallback.inputProc = StaticAudioIOProc; - renderCallback.inputProcRefCon = this; - - err = AudioUnitSetProperty(m_AUHALAudioUnit, - (m_OutputChannels.empty() ? (AudioUnitPropertyID)kAudioOutputUnitProperty_SetInputCallback : (AudioUnitPropertyID)kAudioUnitProperty_SetRenderCallback), - kAudioUnitScope_Output, - m_OutputChannels.empty() ? AUHAL_INPUT_ELEMENT : AUHAL_OUTPUT_ELEMENT, - &renderCallback, sizeof (renderCallback)); - - if (err != kAudioHardwareNoError) - { - DEBUG_MSG ("Unable to set callback, error = " << err); - retVal = eGenericErr; - goto Exit; - } - } - - retVal = EnableListeners(); - if (retVal != eNoErr) - goto Exit; - - //initialize the audio-unit now! - err = AudioUnitInitialize(m_AUHALAudioUnit); - if (err != kAudioHardwareNoError) - { - DEBUG_MSG ("Unable to Initialize AudioUnit = " << err); - retVal = eGenericErr; - goto Exit; - } - -Exit: - if (retVal != eNoErr) - TearDownAUHAL(); - - return retVal; -} - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::TearDownAUHAL -// -//! Undoes the work done by SetupAUHAL -//! -//! \param none -//! -//! \return eNoErr on success, an error code on failure. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::TearDownAUHAL() -{ - WTErr retVal = eNoErr; - - if (m_AUHALAudioUnit) - { - DisableListeners (); - AudioUnitUninitialize(m_AUHALAudioUnit); - CloseComponent(m_AUHALAudioUnit); - m_AUHALAudioUnit = NULL; - } - - return retVal; -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::SetActive -// -//! Sets the device's activation status. Essentially, opens or closes the PA device. -//! If it's an ASIO device it may result in buffer size change in some cases. -//! -//! \param newState : Should be true to activate, false to deactivate. This roughly corresponds -//! to opening and closing the device handle/stream/audio unit. -//! -//! \return eNoErr on success, an error code otherwise. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::SetActive (bool newState) -{ - AUTO_FUNC_DEBUG; - - WTErr retVal = eNoErr; - - if (Active() == newState) - goto Exit; - - - if (newState) - { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Setting up AUHAL."); - retVal = SetupAUHAL(); - - if (retVal != eNoErr) - goto Exit; - - m_BufferSizeChangeRequested = 0; - m_BufferSizeChangeReported = 0; - m_ResetRequested = 0; - m_ResetReported = 0; - m_ResyncRequested = 0; - m_ResyncReported = 0; - m_SRChangeRequested = 0; - m_SRChangeReported = 0; - m_DropsDetected = 0; - m_DropsReported = 0; - m_IgnoreThisDrop = true; - } - else - { - if (Streaming()) - { - SetStreaming (false); - } - - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Tearing down AUHAL."); - retVal = TearDownAUHAL(); - if (retVal != eNoErr) - goto Exit; - - m_BufferSizeChangeRequested = 0; - m_BufferSizeChangeReported = 0; - m_ResetRequested = 0; - m_ResetReported = 0; - m_ResyncRequested = 0; - m_ResyncReported = 0; - m_SRChangeRequested = 0; - m_SRChangeReported = 0; - m_DropsDetected = 0; - m_DropsReported = 0; - m_IgnoreThisDrop = true; - - UpdateDeviceInfo(); - } - - m_IsActive = newState; - -Exit: - return (retVal); -} - - -#if WV_USE_TONE_GEN -//********************************************************************************************** -// WCMRCoreAudioDevice::SetupToneGenerator -// -//! Sets up the Tone generator - only if a file /tmp/tonegen.txt is present. If the file is -//! present, it reads the value in the file and uses that as the frequency for the tone. This -//! code attempts to create an array of samples that would constitute an integral number of -//! cycles - for the currently active sampling rate. If tonegen is active, then the input -//! from the audio device is ignored, instead a data is supplied from the tone generator's -//! array - for all channels. The array is in m_pToneData, the size of the array is in -//! m_ToneDataSamples, and m_NextSampleToUse holds the index in the array from where -//! the next sample is going to be taken. -//! -//! -//! \return : Nothing -//! -//********************************************************************************************** -void WCMRCoreAudioDevice::SetupToneGenerator () -{ - safe_delete_array(m_pToneData); - m_ToneDataSamples = 0; - - //if tonegen exists? - FILE *toneGenHandle = fopen ("/tmp/tonegen.txt", "r"); - if (toneGenHandle) - { - int toneFreq = 0; - fscanf(toneGenHandle, "%d", &toneFreq); - if ((toneFreq <= 0) || (toneFreq > (m_CurrentSamplingRate/2))) - { - toneFreq = 1000; - } - - - m_ToneDataSamples = m_CurrentSamplingRate / toneFreq; - int toneDataSamplesFrac = m_CurrentSamplingRate % m_ToneDataSamples; - int powerOfTen = 1; - while (toneDataSamplesFrac) - { - m_ToneDataSamples = (uint32_t)((pow(10, powerOfTen) * m_CurrentSamplingRate) / toneFreq); - toneDataSamplesFrac = m_CurrentSamplingRate % m_ToneDataSamples; - powerOfTen++; - } - - //allocate - m_pToneData = new float_t[m_ToneDataSamples]; - - //fill with a -6dB Sine Tone - uint32_t numSamplesLeft = m_ToneDataSamples; - float_t *pNextSample = m_pToneData; - double phase = 0; - double phaseIncrement = (M_PI * 2.0 * toneFreq ) / ((double)m_CurrentSamplingRate); - while (numSamplesLeft) - { - *pNextSample = (float_t)(0.5 * sin(phase)); - phase += phaseIncrement; - pNextSample++; - numSamplesLeft--; - } - - m_NextSampleToUse = 0; - - fclose(toneGenHandle); - } -} -#endif //WV_USE_TONE_GEN - - -//********************************************************************************************** -// WCMRCoreAudioDevice::SetStreaming -// -//! Sets the device's streaming status. Calls PA's Start/Stop stream routines. -//! -//! \param newState : Should be true to start streaming, false to stop streaming. This roughly -//! corresponds to calling Start/Stop on the lower level interface. -//! -//! \return eNoErr always, the derived classes may return appropriate error code. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::SetStreaming (bool newState) -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - ComponentResult err = 0; - - if (Streaming () == newState) - goto Exit; - - if (newState) - { -#if WV_USE_TONE_GEN - SetupToneGenerator (); -#endif //WV_USE_TONE_GEN - - m_SampleCountAtLastIdle = 0; - m_StalledSampleCounter = 0; - m_SampleCounter = 0; - m_IOProcThreadPort = 0; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Starting AUHAL."); - - // Prepare for streaming - tell Engine to do the initialization for process callback - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming); - - if (m_UseMultithreading) - { - //set thread constraints... - unsigned int periodAndConstraintUS = (unsigned int)((1000000.0 * m_CurrentBufferSize) / m_CurrentSamplingRate); - unsigned int computationUS = (unsigned int)(0.8 * periodAndConstraintUS); //assuming we may want to use up to 80% CPU - //ErrandManager().SetRealTimeConstraintsForAllThreads (periodAndConstraintUS, computationUS, periodAndConstraintUS); - } - - err = AudioOutputUnitStart (m_AUHALAudioUnit); - - m_StopRequested = false; - - if(err) - { - DEBUG_MSG( "Failed to start AudioUnit, err " << err ); - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Failed to start AudioUnit."); - retVal = eGenericErr; - goto Exit; - } - } - else - { - m_StopRequested = true; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDebugInfo, (void *)"Stopping AUHAL."); - err = AudioOutputUnitStop (m_AUHALAudioUnit); - if (!err) - { - //if (!m_InputChannels.empty()); - { - err = AudioUnitReset (m_AUHALAudioUnit, kAudioUnitScope_Global, AUHAL_INPUT_ELEMENT); - } - //if (!m_OutputChannels.empty()); - { - err = AudioUnitReset (m_AUHALAudioUnit, kAudioUnitScope_Global, AUHAL_OUTPUT_ELEMENT); - } - } - - if(err) - { - DEBUG_MSG( "Failed to stop AudioUnit " << err ); - retVal = eGenericErr; - goto Exit; - } - m_IOProcThreadPort = 0; - } - - // After units restart, reset request for reset and SR change - m_SRChangeReported = m_SRChangeRequested; - m_ResetReported = m_ResetRequested; - - m_IsStreaming = newState; - -Exit: - return (retVal); -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::DoIdle -// -//! A place for doing idle time processing. The other derived classes will probably do something -//! meaningful. -//! -//! \param none -//! -//! \return eNoErr always. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::DoIdle () -{ - /* - if (m_BufferSizeChangeRequested != m_BufferSizeChangeReported) - { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged); - m_BufferSizeChangeReported = m_BufferSizeChangeRequested; - } - - if (m_ResetRequested != m_ResetReported) - { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); - m_ResetReported = m_ResetRequested; - } - - - if (m_ResyncRequested != m_ResyncReported) - { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestResync); - m_ResyncReported = m_ResyncRequested; - } - - if (m_SRChangeReported != m_SRChangeRequested) - { - m_SRChangeReported = m_SRChangeRequested; - int newSR = CurrentSamplingRate(); - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::SamplingRateChanged, (void *)newSR); - } - - if (m_DropsReported != m_DropsDetected) - { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceDroppedSamples); - m_DropsReported = m_DropsDetected; - } - - - //Perhaps add checks to make sure a stream counter is incrementing if - //stream is supposed to be streaming! - if (Streaming()) - { - //latch the value - int64_t currentSampleCount = m_SampleCounter; - if (m_SampleCountAtLastIdle == currentSampleCount) - m_StalledSampleCounter++; - else - { - m_SampleCountAtLastIdle = (int)currentSampleCount; - m_StalledSampleCounter = 0; - } - - if (m_StalledSampleCounter > NUM_STALLS_FOR_NOTIFICATION) - { - m_StalledSampleCounter = 0; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStoppedStreaming, (void *)currentSampleCount); - } - }*/ - - - return (eNoErr); -} - - - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::SetMonitorChannels -// -//! Used to set the channels to be used for monitoring. -//! -//! \param leftChannel : Left monitor channel index. -//! \param rightChannel : Right monitor channel index. -//! -//! \return eNoErr always, the derived classes may return appropriate errors. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::SetMonitorChannels (int leftChannel, int rightChannel) -{ - AUTO_FUNC_DEBUG; - //This will most likely be overridden, the base class simply - //changes the member. - m_LeftMonitorChannel = leftChannel; - m_RightMonitorChannel = rightChannel; - return (eNoErr); -} - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::SetMonitorGain -// -//! Used to set monitor gain (or atten). -//! -//! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB) -//! -//! \return eNoErr always, the derived classes may return appropriate errors. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::SetMonitorGain (float newGain) -{ - AUTO_FUNC_DEBUG; - //This will most likely be overridden, the base class simply - //changes the member. - - - m_MonitorGain = newGain; - return (eNoErr); -} - - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::ShowConfigPanel -// -//! Used to show device specific config/control panel. Some interfaces may not support it. -//! Some interfaces may require the device to be active before it can display a panel. -//! -//! \param pParam : A device/interface specific parameter, should be the app window handle for ASIO. -//! -//! \return eNoErr always, the derived classes may return errors. -//! -//********************************************************************************************** -WTErr WCMRCoreAudioDevice::ShowConfigPanel (void */*pParam*/) -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - - CFStringRef configAP; - UInt32 propSize = sizeof (configAP); - /* - @constant kAudioDevicePropertyConfigurationApplication - A CFString that contains the bundle ID for an application that provides a - GUI for configuring the AudioDevice. By default, the value of this property - is the bundle ID for Audio MIDI Setup. The caller is responsible for - releasing the returned CFObject. - */ - - if (AudioDeviceGetProperty(m_DeviceID, 0, 0, kAudioDevicePropertyConfigurationApplication, &propSize, &configAP) == kAudioHardwareNoError) - { - // get the FSRef of the config app - FSRef theAppFSRef; - OSStatus theError = LSFindApplicationForInfo(kLSUnknownCreator, configAP, NULL, &theAppFSRef, NULL); - if (!theError) - { - LSOpenFSRef(&theAppFSRef, NULL); - } - else - { - // open default AudioMIDISetup if device app is not found - CFStringRef audiMidiSetupApp = CFStringCreateWithCString(kCFAllocatorDefault, "com.apple.audio.AudioMIDISetup", kCFStringEncodingMacRoman); - theError = LSFindApplicationForInfo(kLSUnknownCreator, audiMidiSetupApp, NULL, &theAppFSRef, NULL); - - if (!theError) - { - LSOpenFSRef(&theAppFSRef, NULL); - } - } - - CFRelease (configAP); - } - - return (retVal); -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::StaticAudioIOProc -// -//! The AudioIOProc that gets called when the AudioUnit is ready with recorded audio, and wants to get audio. -//! This one simply calls the non-static member. -//! -//! \param inRefCon : What was passed when setting up the Callback (in our case a pointer to teh WCMRCoreAudioDevice object). -//! \param ioActionFlags : What actios has to be taken. -//! \param inTimeStamp: When the data will be played back. -//! \param inBusNumber : The AU element. -//! \param inNumberFrames: Number af Audio frames that are requested. -//! \param ioData : Where the playback data is to be placed. -//! -//! \return 0 always -//! -//********************************************************************************************** -OSStatus WCMRCoreAudioDevice::StaticAudioIOProc(void *inRefCon, AudioUnitRenderActionFlags * ioActionFlags, - const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, - AudioBufferList *ioData) -{ - WCMRCoreAudioDevice *pMyDevice = (WCMRCoreAudioDevice *)inRefCon; - if (pMyDevice) - return pMyDevice->AudioIOProc (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); - else - return 0; -} - - - - -//********************************************************************************************** -// WCMRCoreAudioDevice::AudioIOProc -// -//! The non-static AudioIOProc that gets called when the AudioUnit is ready with recorded audio, and wants to get audio. -//! We retrieve the recorded audio, and then do our processing, to generate audio to be played back. -//! -//! \param ioActionFlags : What actios has to be taken. -//! \param inTimeStamp: When the data will be played back. -//! \param inBusNumber : The AU element. -//! \param inNumberFrames: Number af Audio frames that are requested. -//! \param ioData : Where the playback data is to be placed. -//! -//! \return 0 always -//! -//********************************************************************************************** -OSStatus WCMRCoreAudioDevice::AudioIOProc(AudioUnitRenderActionFlags * ioActionFlags, - const AudioTimeStamp *inTimeStamp, UInt32 /*inBusNumber*/, UInt32 inNumberFrames, - AudioBufferList *ioData) -{ - UInt64 theStartTime = AudioGetCurrentHostTime(); - - OSStatus retVal = 0; - - if (m_StopRequested) - return retVal; - - if (m_IOProcThreadPort == 0) - m_IOProcThreadPort = mach_thread_self (); - - //cannot really deal with it unless the number of frames are the same as our buffer size! - if (inNumberFrames != (UInt32)m_CurrentBufferSize) - return retVal; - - //Retrieve the input data... - if (!m_InputChannels.empty()) - { - UInt32 expectedDataSize = m_InputChannels.size() * m_CurrentBufferSize * sizeof(float); - AudioBufferList inputAudioBufferList; - inputAudioBufferList.mNumberBuffers = 1; - inputAudioBufferList.mBuffers[0].mNumberChannels = m_InputChannels.size(); - inputAudioBufferList.mBuffers[0].mDataByteSize = expectedDataSize; - inputAudioBufferList.mBuffers[0].mData = NULL;//new float[expectedDataSize]; // we are going to get buffer from CoreAudio - - retVal = AudioUnitRender(m_AUHALAudioUnit, ioActionFlags, inTimeStamp, AUHAL_INPUT_ELEMENT, inNumberFrames, &inputAudioBufferList); - - if (retVal == kAudioHardwareNoError && - inputAudioBufferList.mBuffers[0].mNumberChannels == m_InputChannels.size() && - inputAudioBufferList.mBuffers[0].mDataByteSize == expectedDataSize ) - { - m_pInputData = (float*)inputAudioBufferList.mBuffers[0].mData; - } - else - { - m_pInputData = NULL; - return retVal; - } - } - - //is this an input only device? - if (m_OutputChannels.empty()) - AudioCallback (NULL, inNumberFrames, (int64_t)inTimeStamp->mSampleTime, theStartTime); - else if ((!m_OutputChannels.empty()) && (ioData->mBuffers[0].mNumberChannels == m_OutputChannels.size())) - AudioCallback ((float *)ioData->mBuffers[0].mData, inNumberFrames, (int64_t)inTimeStamp->mSampleTime, theStartTime); - - return retVal; -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::AudioCallback -// -//! Here's where the actual audio processing happens. We call upon all the active connections' -//! sinks to provide data to us which can be put/mixed in the output buffer! Also, we make the -//! input data available to any sources that may call upon us during this time! -//! -//! \param *pOutputBuffer : Points to a buffer to receive playback data. For Input only devices, this will be NULL -//! \param framesPerBuffer : Number of sample frames in input and output buffers. Number of channels, -//! which are interleaved, is fixed at Device Open (Active) time. In this implementation, -//! the number of channels are fixed to use the maximum available. -//! -//! \return true -//! -//********************************************************************************************** -int WCMRCoreAudioDevice::AudioCallback (float *pOutputBuffer, unsigned long framesPerBuffer, int64_t inSampleTime, uint64_t inCycleStartTime) -{ - struct WCMRAudioDeviceManagerClient::AudioCallbackData audioCallbackData = - { - m_pInputData, - pOutputBuffer, - framesPerBuffer, - inSampleTime, - AudioConvertHostTimeToNanos(inCycleStartTime) - }; - - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::AudioCallback, (void *)&audioCallbackData); - - m_SampleCounter += framesPerBuffer; - return m_StopRequested; -} - - -//********************************************************************************************** -// WCMRCoreAudioDevice::GetLatency -// -//! Get Latency for device. -//! -//! Use 'kAudioDevicePropertyLatency' and 'kAudioDevicePropertySafetyOffset' + GetStreamLatencies -//! -//! \param isInput : Return latency for the input if isInput is true, otherwise the output latency -//! wiil be returned. -//! \return Latency in samples. -//! -//********************************************************************************************** -uint32_t WCMRCoreAudioDevice::GetLatency(bool isInput) -{ - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - - UInt32 propSize = sizeof(UInt32); - UInt32 value1 = 0; - UInt32 value2 = 0; - - UInt32 latency = 0; - std::vector streamLatencies; - - - err = AudioDeviceGetProperty(m_DeviceID, 0, isInput, kAudioDevicePropertyLatency, &propSize, &value1); - if (err != kAudioHardwareNoError) - { - DEBUG_MSG("GetLatency kAudioDevicePropertyLatency err = " << err); - } - - err = AudioDeviceGetProperty(m_DeviceID, 0, isInput, kAudioDevicePropertySafetyOffset, &propSize, &value2); - if (err != kAudioHardwareNoError) - { - DEBUG_MSG("GetLatency kAudioDevicePropertySafetyOffset err = " << err); - } - - latency = value1 + value2; - - err = GetStreamLatency(m_DeviceID, isInput, streamLatencies); - if (err == kAudioHardwareNoError) - { - for ( int i = 0; i < streamLatencies.size(); i++) { - latency += streamLatencies[i]; - } - } - - return latency; -} - -//********************************************************************************************** -// WCMRCoreAudioDevice::GetStreamLatency -// -//! Get stream latency for device. -//! -//! \param deviceID : The audio device ID. -//! -//! \param isInput : Return latency for the input if isInput is true, otherwise the output latency -//! wiil be returned. -//********************************************************************************************** -OSStatus WCMRCoreAudioDevice::GetStreamLatency(AudioDeviceID device, bool isInput, std::vector& latencies) -{ - OSStatus err = kAudioHardwareNoError; - UInt32 outSize1, outSize2, outSize3; - Boolean outWritable; - - err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, &outWritable); - if (err == noErr) { - int stream_count = outSize1 / sizeof(UInt32); - AudioStreamID streamIDs[stream_count]; - AudioBufferList bufferList[stream_count]; - UInt32 streamLatency; - outSize2 = sizeof(UInt32); - - err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, streamIDs); - if (err != noErr) { - DEBUG_MSG("GetStreamLatencies kAudioDevicePropertyStreams err = " << err); - return err; - } - - err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, &outWritable); - if (err != noErr) { - DEBUG_MSG("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = " << err); - return err; - } - - for (int i = 0; i < stream_count; i++) { - err = AudioStreamGetProperty(streamIDs[i], 0, kAudioStreamPropertyLatency, &outSize2, &streamLatency); - if (err != noErr) { - DEBUG_MSG("GetStreamLatencies kAudioStreamPropertyLatency err = " << err); - return err; - } - err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, bufferList); - if (err != noErr) { - DEBUG_MSG("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = " << err); - return err; - } - latencies.push_back(streamLatency); - } - } - return err; -} - - -//********************************************************************************************** -// WCMRCoreAudioDeviceManager::WCMRCoreAudioDeviceManager -// -//! The constructuor, we initialize PA, and build the device list. -//! -//! \param *pTheClient : The manager's client object (which receives notifications). -//! \param useMultithreading : Whether to use multi-threading for audio processing. Default is true. -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRCoreAudioDeviceManager::WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, - eAudioDeviceFilter eCurAudioDeviceFilter, bool useMultithreading, bool bNocopy) - : WCMRAudioDeviceManager (pTheClient, eCurAudioDeviceFilter) - , m_UseMultithreading (useMultithreading) - , m_bNoCopyAudioBuffer(bNocopy) -{ - AUTO_FUNC_DEBUG; - - //first of all, tell HAL to use it's own run loop, not to wait for our runloop to do - //it's dirty work... - //Essentially, this makes the HAL on Snow Leopard behave like Leopard. - //It's not yet (as of October 2009 documented), but the following discussion - //has the information provided by Jeff Moore @ Apple: - // http://lists.apple.com/archives/coreaudio-api/2009/Oct/msg00214.html - // - // As per Jeff's suggestion, opened an Apple Bug on this - ID# 7364011 - - CFRunLoopRef nullRunLoop = 0; - OSStatus err = AudioHardwareSetProperty (kAudioHardwarePropertyRunLoop, sizeof(CFRunLoopRef), &nullRunLoop); - - if (err != kAudioHardwareNoError) - { - syslog (LOG_NOTICE, "Unable to set RunLoop for Audio Hardware"); - } - - //add a listener to find out when devices change... - AudioHardwareAddPropertyListener (kAudioHardwarePropertyDevices, HardwarePropertyChangeCallback, this); - - //Always add the None device first... - m_NoneDevice = new WCMRNativeAudioNoneDevice(this); - - //prepare our initial list... - generateDeviceListImpl(); - - return; -} - - - -//********************************************************************************************** -// WCMRCoreAudioDeviceManager::~WCMRCoreAudioDeviceManager -// -//! It clears the device list, releasing each of the device. -//! -//! \param none -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRCoreAudioDeviceManager::~WCMRCoreAudioDeviceManager() -{ - AUTO_FUNC_DEBUG; - - try - { - delete m_NoneDevice; - } - catch (...) - { - //destructors should absorb exceptions, no harm in logging though!! - DEBUG_MSG ("Exception during destructor"); - } - -} - - -WCMRAudioDevice* WCMRCoreAudioDeviceManager::initNewCurrentDeviceImpl(const std::string & deviceName) -{ - destroyCurrentDeviceImpl(); - - std::cout << "API::PortAudioDeviceManager::initNewCurrentDevice " << deviceName << std::endl; - if (deviceName == m_NoneDevice->DeviceName() ) - { - m_CurrentDevice = m_NoneDevice; - return m_CurrentDevice; - } - - DeviceInfo devInfo; - WTErr err = GetDeviceInfoByName(deviceName, devInfo); - - if (eNoErr == err) - { - try - { - std::cout << "API::PortAudioDeviceManager::Creating PA device: " << devInfo.m_DeviceId << ", Device Name: " << devInfo.m_DeviceName << std::endl; - TRACE_MSG ("API::PortAudioDeviceManager::Creating PA device: " << devInfo.m_DeviceId << ", Device Name: " << devInfo.m_DeviceName); - - m_CurrentDevice = new WCMRCoreAudioDevice (this, devInfo.m_DeviceId, m_UseMultithreading, m_bNoCopyAudioBuffer); - } - catch (...) - { - std::cout << "Unabled to create PA Device: " << devInfo.m_DeviceId << std::endl; - DEBUG_MSG ("Unabled to create PA Device: " << devInfo.m_DeviceId); - } - } - - return m_CurrentDevice; -} - - -void WCMRCoreAudioDeviceManager::destroyCurrentDeviceImpl() -{ - if (m_CurrentDevice != m_NoneDevice) - delete m_CurrentDevice; - - m_CurrentDevice = 0; -} - - -WTErr WCMRCoreAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceId, std::vector& sampleRates) -{ - AUTO_FUNC_DEBUG; - - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - - sampleRates.clear(); - - //! 1. Get sample rate property size. - err = AudioDeviceGetPropertyInfo(deviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, NULL); - if (err == kAudioHardwareNoError) - { - //! 2. Get property: cannels output. - - // Allocate size according to the number of audio values - int numRates = propSize / sizeof(AudioValueRange); - AudioValueRange* supportedRates = new AudioValueRange[numRates]; - - // Get sampling rates from Audio device - err = AudioDeviceGetProperty(deviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, supportedRates); - if (err == kAudioHardwareNoError) - { - //! 3. Update sample rates - - // now iterate through our standard SRs - for(int ourSR=0; gAllSampleRates[ourSR] > 0; ourSR++) - { - //check to see if our SR is in the supported rates... - for (int deviceSR = 0; deviceSR < numRates; deviceSR++) - { - if ((supportedRates[deviceSR].mMinimum <= gAllSampleRates[ourSR]) && - (supportedRates[deviceSR].mMaximum >= gAllSampleRates[ourSR])) - { - sampleRates.push_back ((int)gAllSampleRates[ourSR]); - break; - } - } - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Sample rates. Device Name: " << m_DeviceName.c_str()); - } - - delete [] supportedRates; - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Sample rates property size. Device Name: " << m_DeviceName.c_str()); - } - - return retVal; -} - - -WTErr WCMRCoreAudioDeviceManager::getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels) -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - inputChannels = 0; - - // 1. Get property cannels input size. - err = AudioDeviceGetPropertyInfo (deviceId, 0, 1/* Input */, kAudioDevicePropertyStreamConfiguration, &propSize, NULL); - if (err == kAudioHardwareNoError) - { - //! 2. Get property: cannels input. - - // Allocate size according to the property size. Note that this is a variable sized struct... - AudioBufferList *pStreamBuffers = (AudioBufferList *)malloc(propSize); - - if (pStreamBuffers) - { - memset (pStreamBuffers, 0, propSize); - - // Get the Input channels - err = AudioDeviceGetProperty (deviceId, 0, 1/* Input */, kAudioDevicePropertyStreamConfiguration, &propSize, pStreamBuffers); - if (err == kAudioHardwareNoError) - { - // Calculate the number of input channels - for (UInt32 streamIndex = 0; streamIndex < pStreamBuffers->mNumberBuffers; streamIndex++) - { - inputChannels += pStreamBuffers->mBuffers[streamIndex].mNumberChannels; - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Input channels. Device Name: " << m_DeviceName.c_str()); - } - - free (pStreamBuffers); - } - else - { - retVal = eMemOutOfMemory; - DEBUG_MSG("Faild to allocate memory. Device Name: " << m_DeviceName.c_str()); - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Input channels property size. Device Name: " << m_DeviceName.c_str()); - } - - return retVal; -} - - -WTErr WCMRCoreAudioDeviceManager::getDeviceMaxOutputChannels(DeviceID deviceId, unsigned int& outputChannels) -{ - AUTO_FUNC_DEBUG; - - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - outputChannels = 0; - - //! 1. Get property cannels output size. - err = AudioDeviceGetPropertyInfo (deviceId, 0, 0/* Output */, kAudioDevicePropertyStreamConfiguration, &propSize, NULL); - if (err == kAudioHardwareNoError) - { - //! 2. Get property: cannels output. - - // Allocate size according to the property size. Note that this is a variable sized struct... - AudioBufferList *pStreamBuffers = (AudioBufferList *)malloc(propSize); - if (pStreamBuffers) - { - memset (pStreamBuffers, 0, propSize); - - // Get the Output channels - err = AudioDeviceGetProperty (deviceId, 0, 0/* Output */, kAudioDevicePropertyStreamConfiguration, &propSize, pStreamBuffers); - if (err == kAudioHardwareNoError) - { - // Calculate the number of output channels - for (UInt32 streamIndex = 0; streamIndex < pStreamBuffers->mNumberBuffers; streamIndex++) - { - outputChannels += pStreamBuffers->mBuffers[streamIndex].mNumberChannels; - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Output channels. Device Name: " << m_DeviceName.c_str()); - } - free (pStreamBuffers); - } - else - { - retVal = eMemOutOfMemory; - DEBUG_MSG("Faild to allocate memory. Device Name: " << m_DeviceName.c_str()); - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Output channels property size. Device Name: " << m_DeviceName.c_str()); - } - - return retVal; -} - - -WTErr WCMRCoreAudioDeviceManager::generateDeviceListImpl() -{ - AUTO_FUNC_DEBUG; - - // lock the list first - wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex); - m_DeviceInfoVec.clear(); - - //First, get info from None device which is always present - if (m_NoneDevice) - { - DeviceInfo *pDevInfo = new DeviceInfo(NONE_DEVICE_ID, m_NoneDevice->DeviceName() ); - pDevInfo->m_AvailableSampleRates = m_NoneDevice->SamplingRates(); - m_DeviceInfoVec.push_back(pDevInfo); - } - - WTErr retVal = eNoErr; - OSStatus osErr = noErr; - AudioDeviceID* deviceIDs = 0; - - openlog("WCMRCoreAudioDeviceManager", LOG_PID | LOG_CONS, LOG_USER); - - try - { - //Get device count... - UInt32 propSize = 0; - osErr = AudioHardwareGetPropertyInfo (kAudioHardwarePropertyDevices, &propSize, NULL); - ASSERT_ERROR(osErr, "AudioHardwareGetProperty 1"); - if (WUIsError(osErr)) - throw osErr; - - size_t numDevices = propSize / sizeof (AudioDeviceID); - deviceIDs = new AudioDeviceID[numDevices]; - - //retrieve the device IDs - propSize = numDevices * sizeof (AudioDeviceID); - osErr = AudioHardwareGetProperty (kAudioHardwarePropertyDevices, &propSize, deviceIDs); - ASSERT_ERROR(osErr, "Error while getting audio devices: AudioHardwareGetProperty 2"); - if (WUIsError(osErr)) - throw osErr; - - //now add the ones that are not there... - for (size_t deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) - { - DeviceInfo* pDevInfo = 0; - - //Get device name and create new DeviceInfo entry - //Get property name size. - osErr = AudioDeviceGetPropertyInfo(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL); - if (osErr == kAudioHardwareNoError) - { - //Get property: name. - char* deviceName = new char[propSize]; - osErr = AudioDeviceGetProperty(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, deviceName); - if (osErr == kAudioHardwareNoError) - { - pDevInfo = new DeviceInfo(deviceIDs[deviceIndex], deviceName); - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device name. Device ID: " << m_DeviceID); - } - - delete [] deviceName; - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device name property size. Device ID: " << m_DeviceID); - } - - if (pDevInfo) - { - //Retrieve all the information we need for the device - WTErr wErr = eNoErr; - - //Get available sample rates for the device - std::vector availableSampleRates; - wErr = getDeviceAvailableSampleRates(pDevInfo->m_DeviceId, availableSampleRates); - - if (wErr != eNoErr) - { - DEBUG_MSG ("Failed to get device available sample rates. Device ID: " << m_DeviceID); - delete pDevInfo; - continue; //proceed to the next device - } - - pDevInfo->m_AvailableSampleRates = availableSampleRates; - - //Get max input channels - uint32_t maxInputChannels; - wErr = getDeviceMaxInputChannels(pDevInfo->m_DeviceId, maxInputChannels); - - if (wErr != eNoErr) - { - DEBUG_MSG ("Failed to get device max input channels count. Device ID: " << m_DeviceID); - delete pDevInfo; - continue; //proceed to the next device - } - - pDevInfo->m_MaxInputChannels = maxInputChannels; - - //Get max output channels - uint32_t maxOutputChannels; - wErr = getDeviceMaxOutputChannels(pDevInfo->m_DeviceId, maxOutputChannels); - - if (wErr != eNoErr) - { - DEBUG_MSG ("Failed to get device max output channels count. Device ID: " << m_DeviceID); - delete pDevInfo; - continue; //proceed to the next device - } - - pDevInfo->m_MaxOutputChannels = maxOutputChannels; - - //Now check if this device is acceptable according to current input/output settings - bool bRejectDevice = false; - switch(m_eAudioDeviceFilter) - { - case eInputOnlyDevices: - if (pDevInfo->m_MaxInputChannels != 0) - { - m_DeviceInfoVec.push_back(pDevInfo); - } - else - { - // Delete unnecesarry device - bRejectDevice = true; - } - break; - case eOutputOnlyDevices: - if (pDevInfo->m_MaxOutputChannels != 0) - { - m_DeviceInfoVec.push_back(pDevInfo); - } - else - { - // Delete unnecesarry device - bRejectDevice = true; - } - break; - case eFullDuplexDevices: - if (pDevInfo->m_MaxInputChannels != 0 && pDevInfo->m_MaxOutputChannels != 0) - { - m_DeviceInfoVec.push_back(pDevInfo); - } - else - { - // Delete unnecesarry device - bRejectDevice = true; - } - break; - case eAllDevices: - default: - m_DeviceInfoVec.push_back(pDevInfo); - break; - } - - if(bRejectDevice) - { - syslog (LOG_NOTICE, "%s rejected, In Channels = %d, Out Channels = %d\n", - pDevInfo->m_DeviceName.c_str(), pDevInfo->m_MaxInputChannels, pDevInfo->m_MaxOutputChannels); - // In case of Input and Output both channels being Zero, we will release memory; since we created CoreAudioDevice but we are Not adding it in list. - delete pDevInfo; - } - } - } - - - //If no devices were found, that's not a good thing! - if (m_DeviceInfoVec.empty()) - { - DEBUG_MSG ("No matching CoreAudio devices were found\n"); - } - } - catch (...) - { - if (WUNoError(retVal)) - retVal = eCoreAudioFailed; - } - - delete[] deviceIDs; - closelog(); - - return retVal; -} - - -WTErr WCMRCoreAudioDeviceManager::updateDeviceListImpl() -{ - wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex); - WTErr err = generateDeviceListImpl(); - - if (eNoErr != err) - { - std::cout << "API::PortAudioDeviceManager::updateDeviceListImpl: Device list update error: "<< err << std::endl; - } - - if (m_CurrentDevice) - { - // if we have device initialized we should find out if this device is still connected - DeviceInfo devInfo; - WTErr deviceLookUpErr = GetDeviceInfoByName(m_CurrentDevice->DeviceName(), devInfo ); - - if (eNoErr != deviceLookUpErr) - { - NotifyClient (WCMRAudioDeviceManagerClient::IODeviceDisconnected); - return err; - } - - WCMRCoreAudioDevice* current_device = dynamic_cast(m_CurrentDevice); - - if ( current_device && - (current_device->DeviceID() != devInfo.m_DeviceId ) ) - { - NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); - return err; - } - } - - NotifyClient (WCMRAudioDeviceManagerClient::DeviceListChanged); - - return err; -} - - -WTErr WCMRCoreAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & deviceName, std::vector& sampleRates) const -{ - AUTO_FUNC_DEBUG; - - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - - sampleRates.clear(); - - //first check if the request has been made for None device - if (deviceName == m_NoneDevice->DeviceName() ) - { - sampleRates = m_NoneDevice->SamplingRates(); - return retVal; - } - - if (m_CurrentDevice && m_CurrentDevice->DeviceName () == deviceName) { - sampleRates.assign(m_CurrentDevice->SamplingRates().begin(), m_CurrentDevice->SamplingRates().end() ); - return retVal; - } - - DeviceInfo devInfo; - retVal = GetDeviceInfoByName(deviceName, devInfo); - - //! 1. Get sample rate property size. - err = AudioDeviceGetPropertyInfo(devInfo.m_DeviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, NULL); - - if (err == kAudioHardwareNoError) - { - //! 2. Get property: cannels output. - - // Allocate size accrding to the number of audio values - int numRates = propSize / sizeof(AudioValueRange); - AudioValueRange* supportedRates = new AudioValueRange[numRates]; - - // Get sampling rates from Audio device - err = AudioDeviceGetProperty(devInfo.m_DeviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, supportedRates); - - if (err == kAudioHardwareNoError) - { - //! 3. Update sample rates - - // now iterate through our standard SRs - for(int ourSR=0; gAllSampleRates[ourSR] > 0; ourSR++) - { - //check to see if our SR is in the supported rates... - for (int deviceSR = 0; deviceSR < numRates; deviceSR++) - { - if ((supportedRates[deviceSR].mMinimum <= gAllSampleRates[ourSR]) && - (supportedRates[deviceSR].mMaximum >= gAllSampleRates[ourSR])) - { - sampleRates.push_back ((int)gAllSampleRates[ourSR]); - break; - } - } - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Sample rates. Device Name: " << m_DeviceName.c_str()); - } - - delete [] supportedRates; - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device Sample rates property size. Device Name: " << m_DeviceName.c_str()); - } - - devInfo.m_AvailableSampleRates.assign(sampleRates.begin(), sampleRates.end() ); - - return retVal; -} - - -WTErr WCMRCoreAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & deviceName, std::vector& bufferSizes) const -{ - AUTO_FUNC_DEBUG; - - WTErr retVal = eNoErr; - OSStatus err = kAudioHardwareNoError; - UInt32 propSize = 0; - - bufferSizes.clear(); - - //first check if the request has been made for None device - if (deviceName == m_NoneDevice->DeviceName() ) - { - bufferSizes = m_NoneDevice->BufferSizes(); - return retVal; - } - - if (m_CurrentDevice && m_CurrentDevice->DeviceName () == deviceName) { - bufferSizes.assign(m_CurrentDevice->BufferSizes().begin(), m_CurrentDevice->BufferSizes().end() ); - return retVal; - } - - DeviceInfo devInfo; - retVal = GetDeviceInfoByName(deviceName, devInfo); - - if (eNoErr == retVal) - { - // 1. Get buffer size range - AudioValueRange bufferSizesRange; - propSize = sizeof (AudioValueRange); - err = AudioDeviceGetProperty (devInfo.m_DeviceId, 0, 0, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &bufferSizesRange); - if(err == kAudioHardwareNoError) - { - // 2. Run on all ranges and add them to the list - for(int bsize=0; gAllBufferSizes[bsize] > 0; bsize++) - { - if ((bufferSizesRange.mMinimum <= gAllBufferSizes[bsize]) && (bufferSizesRange.mMaximum >= gAllBufferSizes[bsize])) - { - bufferSizes.push_back (gAllBufferSizes[bsize]); - } - } - - //if we didn't get a single hit, let's simply add the min. and the max... - if (bufferSizes.empty()) - { - bufferSizes.push_back ((int)bufferSizesRange.mMinimum); - bufferSizes.push_back ((int)bufferSizesRange.mMaximum); - } - } - else - { - retVal = eCoreAudioFailed; - DEBUG_MSG("Failed to get device buffer sizes range. Device Name: " << m_DeviceName.c_str()); - } - } - else - { - retVal = eRMResNotFound; - std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl; - } - - - return retVal; -} - - -OSStatus WCMRCoreAudioDeviceManager::HardwarePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData) -{ - switch (inPropertyID) - { - case kAudioHardwarePropertyDevices: - { - WCMRCoreAudioDeviceManager* pManager = (WCMRCoreAudioDeviceManager*)inClientData; - if (pManager) - pManager->updateDeviceListImpl(); - } - break; - - default: - break; - } - - return 0; -} diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h deleted file mode 100644 index 0d92493b51..0000000000 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -//---------------------------------------------------------------------------------- -// -// -//! \file WCMRCoreAudioDeviceManager.h -//! -//! WCMRCoreAudioDeviceManager and related class declarations -//! -//---------------------------------------------------------------------------------*/ -#ifndef __WCMRCoreAudioDeviceManager_h_ - #define __WCMRCoreAudioDeviceManager_h_ - -#include "WCMRAudioDeviceManager.h" -#include "WCMRNativeAudio.h" -#include "Threads/WCThreadSafe.h" - -#include -#include - -#include - -#include - -//forward decl. -class WCMRCoreAudioDeviceManager; - -#define WV_USE_TONE_GEN 0 ///! Set this to 1 to use a tone generator for input. See description at SetupToneGenerator for details. - -// This enum is for choosing filter for audio devices scan -typedef enum eCABS_Method -{ - eCABS_Simple = 0, - eCABS_DestructiveCache, - eCABS_CacheOnDeviceSet, - eCABS_MethodNum // Must be last -} eCABS_Method; - -//! Manages a port audio device, providing information -//! about the device, and managing audio callbacks. -class WCMRCoreAudioDevice : public WCMRNativeAudioDevice -{ -public: - - WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager, AudioDeviceID deviceID, bool useMultithreading = true, bool bNocopy = false);///& InputChannels();///& OutputChannels();///& SamplingRates();///& BufferSizes();///& latencies); - - -protected: - - AudioDeviceID m_DeviceID; ///< The CoreAudio device id - bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise. - float *m_pInputData; ///< This is what came in with the most recent callback. - int64_t m_SampleCounter; ///< The current running sample counter, updated by the audio callback. - int64_t m_SampleCountAtLastIdle; ///< What was the sample count last time we checked... - int m_StalledSampleCounter; ///< The number of idle calls with same sample count detected - int m_ChangeCheckCounter; ///< The number of idle calls passed since we checked the buffer size change. - - wvNS::wvThread::timestamp m_LastCPULog; ///< The time when the last CPU details log was sent as a notification. -// unsigned int m_IOCyclesTimesTaken[MAX_IOCYCLE_TIMES]; ///< This stores the times taken by each IOCycle, in host-time units. -// int m_CurrentIOCycle; ///< The location in m_IOCyclesTymesTaken array, where the next cycle's value will go. -// int m_CyclesToAccumulate; ///< The number of cycles to accumulate the values for - maximum for last one second. -// unsigned int m_CyclePeriod; ///< The number of host time units for a cycle period - determined by buffer size and sampling rate - - - AudioUnit m_AUHALAudioUnit;///< The AUHAL AudioUnit - - int m_BufferSizeChangeRequested; - int m_BufferSizeChangeReported; - int m_ResetRequested; - int m_ResetReported; - int m_ResyncRequested; - int m_ResyncReported; - int m_SRChangeRequested; - int m_SRChangeReported; - - int m_DropsDetected; ///< Number of times audio drops have been detected so far. - int m_DropsReported; ///< Number of times audio drops have been reported so far to the client. - bool m_IgnoreThisDrop; ///< Allows disregarding the first drop - - thread_t m_IOProcThreadPort; ///< Thread handle to calculate CPU consumption. - int m_CPUCount; ///< Number of processors/core to normalize cpu consumption calculation. - -#if WV_USE_TONE_GEN - //The Tone Generator... - float_t *m_pToneData; - uint32_t m_ToneDataSamples; - uint32_t m_NextSampleToUse; -#endif //WV_USE_TONE_GEN - - WTErr UpdateDeviceInfo (); - WTErr UpdateDeviceId (); - WTErr UpdateDeviceName(); - WTErr UpdateDeviceInputs(); - WTErr UpdateDeviceOutputs(); - WTErr UpdateDeviceSampleRates(); - WTErr UpdateDeviceBufferSizes(); - WTErr SetWorkingBufferSize(int newSize); - OSStatus SetBufferSizesByIO(int newSize); - WTErr SetAndCheckCurrentSamplingRate (int newRate); - - WTErr EnableAudioUnitIO(); - WTErr virtual EnableListeners(); - WTErr virtual DisableListeners(); - WTErr SetupAUHAL(); - WTErr TearDownAUHAL(); - -#if WV_USE_TONE_GEN - void SetupToneGenerator (); -#endif //WV_USE_TONE_GEN - - static OSStatus StaticAudioIOProc(void *inRefCon, AudioUnitRenderActionFlags * ioActionFlags, - const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, - AudioBufferList *ioData); - OSStatus AudioIOProc(AudioUnitRenderActionFlags * ioActionFlags, - const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, - AudioBufferList *ioData); - - static OSStatus StaticPropertyChangeProc (AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, - AudioDevicePropertyID inPropertyID, void *inClientData); - void PropertyChangeProc (AudioDevicePropertyID inPropertyID); - -private: - -}; - - -//! WCMRCoreAudioDeviceManager -/*! The CoreAudio Device Manager class */ -class WCMRCoreAudioDeviceManager : public WCMRAudioDeviceManager -{ -public: - - WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter, - bool useMultithreading = true, bool bNocopy = false); ///< constructor - virtual ~WCMRCoreAudioDeviceManager(void); ///< Destructor - -protected: - static OSStatus HardwarePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData); - - virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName); - virtual void destroyCurrentDeviceImpl(); - virtual WTErr generateDeviceListImpl(); - virtual WTErr updateDeviceListImpl(); - virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector& sampleRates) const; - virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector& bufferSizes) const; - - bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing. - bool m_bNoCopyAudioBuffer; - -private: - // helper functions for this class only - WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector& sampleRates); - WTErr getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels); - WTErr getDeviceMaxOutputChannels(DeviceID deviceId, unsigned int& outputChannels); - - WCMRAudioDevice* m_NoneDevice; -}; - -#endif //#ifndef __WCMRCoreAudioDeviceManager_h_ diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRNativeAudio.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRNativeAudio.cpp deleted file mode 100644 index bf5e4fbb90..0000000000 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRNativeAudio.cpp +++ /dev/null @@ -1,266 +0,0 @@ -//---------------------------------------------------------------------------------- -// -// Copyright (c) 2008 Waves Audio Ltd. All rights reserved. -// -//! \file WCMRNativeAudio.cpp -//! -//! WCMRNativeAudioConnection and related class defienitions -//! -//---------------------------------------------------------------------------------*/ -#if defined(__APPLE__) -#include -#endif - -#include "WCMRNativeAudio.h" -#include "MiscUtils/pthread_utils.h" -#include "MiscUtils/safe_delete.h" -#include -#include -#include - -#define NONE_DEVICE_NAME "None" -#define NONE_DEVICE_INPUT_NAMES "Input " -#define NONE_DEVICE_OUTPUT_NAMES "Output " - -//********************************************************************************************** -// WCMRNativeAudioNoneDevice::WCMRNativeAudioNoneDevice -// -//! Constructor for the dummy "None" device. This constructor simply adds supported SRs, -//! buffer sizes, and channels, so that it may look like a real native device to -//! the applications. -//! -//! \param pManager : The managing device manager - simply passed on to the base class. -//! -//! -//********************************************************************************************** -WCMRNativeAudioNoneDevice::WCMRNativeAudioNoneDevice (WCMRAudioDeviceManager *pManager) - : WCMRNativeAudioDevice (pManager, false /*useMultiThreading*/) -#ifndef PTW32_VERSION - , m_SilenceThread(0) -#endif -#if defined (PLATFORM_WINDOWS) - , _waitableTimerForUsleep (CreateWaitableTimer(NULL, TRUE, NULL)) -#endif -{ - mark_pthread_inactive (m_SilenceThread); - - m_DeviceName = NONE_DEVICE_NAME; - - m_SamplingRates = boost::assign::list_of (m_CurrentSamplingRate=44100)(48000)(88200)(96000)(176400)(192000); - - m_BufferSizes = boost::assign::list_of (32)(64)(128)(m_CurrentBufferSize=256)(512)(1024); - - for (int channel = 0; channel < __m_NumInputChannels; channel++) - { - std::stringstream name; - name << NONE_DEVICE_INPUT_NAMES; - name << (channel + 1); - m_InputChannels.push_back(name.str()); - } - - for (int channel = 0; channel < __m_NumOutputChannels; channel++) - { - std::stringstream name; - name << NONE_DEVICE_INPUT_NAMES; - name << (channel + 1); - m_OutputChannels.push_back(name.str()); - } - _m_inputBuffer = new float[__m_NumInputChannels * m_BufferSizes.back()]; - _m_outputBuffer = new float[__m_NumOutputChannels * m_BufferSizes.back()]; - m_CurrentBufferSize = m_BufferSizes.back(); -} - - -WCMRNativeAudioNoneDevice::~WCMRNativeAudioNoneDevice () -{ -#if defined (PLATFORM_WINDOWS) - if(_waitableTimerForUsleep) { - CloseHandle(_waitableTimerForUsleep); - } -#endif -} - -WTErr WCMRNativeAudioNoneDevice::SetActive (bool newState) -{ - //This will most likely be overridden, the base class simply - //changes the member. - if (Active() == newState) - { - return (eNoErr); - } - - if (Active() && Streaming()) - { - SetStreaming(false); - } - return WCMRAudioDevice::SetActive(newState); -} - -WTErr WCMRNativeAudioNoneDevice::SetCurrentBufferSize (int newSize) -{ - - //changes the status. - int oldSize = CurrentBufferSize(); - bool oldActive = Active(); - - //same size, nothing to do. - if (oldSize == newSize) - return eNoErr; - - //see if this is one of our supported rates... - std::vector::iterator intIter = find(m_BufferSizes.begin(), m_BufferSizes.end(), newSize); - if (intIter == m_BufferSizes.end()) - { - //Can't change, perhaps use an "invalid param" type of error - return eCommandLineParameter; - } - - if (Streaming()) - { - //Can't change, perhaps use an "in use" type of error - return eGenericErr; - } - - - return WCMRAudioDevice::SetCurrentBufferSize(newSize); -} - - -WTErr WCMRNativeAudioNoneDevice::UpdateDeviceInfo () -{ - return eNoErr; -} - - -WTErr WCMRNativeAudioNoneDevice::SetStreaming (bool newState) -{ - if (Streaming() == newState) - { - return (eNoErr); - } - - WCMRAudioDevice::SetStreaming(newState); - - if (Streaming()) - { - if (is_pthread_active (m_SilenceThread)) - std::cerr << "\t\t\t\t\t !!!!!!!!!!!!!!! Warning: the inactive NONE-DEVICE was streaming!" << std::endl; - - pthread_attr_t attributes; - size_t stack_size = 100000; -#ifdef __APPLE__ - stack_size = (((stack_size - 1) / PTHREAD_STACK_MIN) + 1) * PTHREAD_STACK_MIN; -#endif - if (pthread_attr_init (&attributes)) { - std::cerr << "WCMRNativeAudioNoneDevice::SetStreaming (): pthread_attr_init () failed!" << std::endl; - return eGenericErr; - } - - if (pthread_attr_setstacksize (&attributes, stack_size)) { - std::cerr << "WCMRNativeAudioNoneDevice::SetStreaming (): pthread_attr_setstacksize () failed!" << std::endl; - return eGenericErr; - } - - if (pthread_create (&m_SilenceThread, &attributes, __SilenceThread, this)) { - mark_pthread_inactive (m_SilenceThread); - std::cerr << "WCMRNativeAudioNoneDevice::SetStreaming (): pthread_create () failed!" << std::endl; - return eGenericErr; - } - } - else - { - if (!is_pthread_active (m_SilenceThread)) - { - std::cerr << "\t\t\t\t\t !!!!!!!!!!!!!!! Warning: the active NONE-DEVICE was NOT streaming!" << std::endl; - } - - while (is_pthread_active (m_SilenceThread)) - { - _usleep(1); //now wait for ended thread; - } - } - - return eNoErr; -} - -void WCMRNativeAudioNoneDevice::_SilenceThread() -{ -#if defined(PLATFORM_WINDOWS) - float* theInpBuffers[__m_NumInputChannels]; - for(int i = 0; i < __m_NumInputChannels; ++i) - { - theInpBuffers[i] = _m_inputBuffer + m_BufferSizes.back() * i; - } -#else - float* theInpBuffers = _m_inputBuffer; -#endif - - const size_t buffer_size = CurrentBufferSize(); - const uint64_t cyclePeriodNanos = (1000000000.0 * buffer_size) / CurrentSamplingRate(); - - struct WCMRAudioDeviceManagerClient::AudioCallbackData audioCallbackData = - { - (const float*)theInpBuffers, - _m_outputBuffer, - buffer_size, - 0, - 0 - }; - - audioCallbackData.acdCycleStartTimeNanos =__get_time_nanos(); - - // VERY ROUGH IMPLEMENTATION: - while(Streaming()) { - - uint64_t cycleEndTimeNanos = audioCallbackData.acdCycleStartTimeNanos + cyclePeriodNanos; - - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::AudioCallback, (void *)&audioCallbackData); - - audioCallbackData.acdSampleTime += buffer_size; - - int64_t timeToSleepUsecs = ((int64_t)cycleEndTimeNanos - (int64_t)__get_time_nanos())/1000; - - if (timeToSleepUsecs > 0) { - _usleep (timeToSleepUsecs); - } - audioCallbackData.acdCycleStartTimeNanos = cycleEndTimeNanos+1; - } - mark_pthread_inactive (m_SilenceThread); -} - -void* WCMRNativeAudioNoneDevice::__SilenceThread(void *This) -{ - ((WCMRNativeAudioNoneDevice*)This)->_SilenceThread(); - return 0; -} - -#if defined(PLATFORM_WINDOWS) -void WCMRNativeAudioNoneDevice::_usleep(uint64_t duration_usec) -{ - LARGE_INTEGER ft; - - ft.QuadPart = -(10*duration_usec); // Convert to 100 nanosecond interval, negative value indicates relative time - - SetWaitableTimer(_waitableTimerForUsleep, &ft, 0, NULL, NULL, 0); - WaitForSingleObject(_waitableTimerForUsleep, INFINITE); -} -#endif - -uint64_t -WCMRNativeAudioNoneDevice::__get_time_nanos () -{ -#ifdef __APPLE__ - // here we exploit the time counting API which is used by the WCMRCoreAudioDeviceManager. However, - // the API should be a part of WCMRCoreAudioDeviceManager to give a chance of being tied to the - // audio device transport timeß. - return AudioConvertHostTimeToNanos (AudioGetCurrentHostTime ()); - -#elif PLATFORM_WINDOWS - - LARGE_INTEGER Frequency, Count ; - - QueryPerformanceFrequency (&Frequency) ; - QueryPerformanceCounter (&Count); - return uint64_t ((Count.QuadPart * 1000000000.0 / Frequency.QuadPart)); -#endif -} diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRNativeAudio.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRNativeAudio.h deleted file mode 100644 index 238d36fd74..0000000000 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRNativeAudio.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -//---------------------------------------------------------------------------------- -// -// -//! \file WCMRNativeAudio.h -//! -//! WCMRNativeAudio and related class declarations -//! -//---------------------------------------------------------------------------------*/ -#ifndef __WCMRNativeAudio_h_ - #define __WCMRNativeAudio_h_ - -#if defined(PLATFORM_WINDOWS) -#include "windows.h" -#endif -#include "pthread.h" -#include "WCRefManager.h" -#include "WCMRAudioDeviceManager.h" - -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 -#include -#endif - -class WCMRNativeAudioDevice; //forward - - - -class WCMRNativeAudioDevice : public WCMRAudioDevice -{ -public: - - WCMRNativeAudioDevice (WCMRAudioDeviceManager *pManager, bool useMultithreading = true, bool bNoCopy = false) : - WCMRAudioDevice (pManager) - , m_UseMultithreading (useMultithreading) - , m_bNoCopyAudioBuffer(bNoCopy) - {} - virtual ~WCMRNativeAudioDevice () {} - -protected: - bool m_UseMultithreading; - bool m_bNoCopyAudioBuffer; ///< This flag determines whether the audio callback performs a copy of audio, or the source/sink perform the copy. It should be true to let source/sink do the copies. - -}; - - -//! A dummy device to allow apps to choose "None" in case no real device connection is required. -class WCMRNativeAudioNoneDevice : public WCMRNativeAudioDevice -{ -public: - WCMRNativeAudioNoneDevice (WCMRAudioDeviceManager *pManager); - virtual ~WCMRNativeAudioNoneDevice (); - virtual WTErr SetActive (bool newState);/// -#include -#include -#include -using namespace wvNS; -#include "IncludeWindows.h" -#include -#include "pa_asio.h" -#include "asio.h" - -#define PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS 200 -#define DEVICE_INFO_UPDATE_SLEEP_TIME_MILLISECONDS 500 -#define PROPERTY_CHANGE_TIMEOUT_SECONDS 2 -#define PROPERTY_CHANGE_RETRIES 3 - -///< Supported Sample rates -static const double gAllSampleRates[] = - { - 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0, -1 /* negative terminated list */ - }; - - - -///< Default Supported Buffer Sizes. -static const int gAllBufferSizes[] = - { - 32, 64, 96, 128, 192, 256, 512, 1024, 2048 - }; - - -///< The default SR. -static const int DEFAULT_SR = 44100; -///< The default buffer size. -static const int DEFAULT_BUFFERSIZE = 128; - -static const int NONE_DEVICE_ID = -1; - -///< Number of stalls to wait before notifying user... -static const int NUM_STALLS_FOR_NOTIFICATION = 100; // 100 corresponds to 100 x 42 ms idle timer - about 4 seconds. -static const int CHANGE_CHECK_COUNTER_PERIOD = 100; // 120 corresponds to 120 x 42 ms idle timer - about 4 seconds. - -#define HUNDRED_NANO_TO_MILLI_CONSTANT 10000 -#define CONSUMPTION_CALCULATION_INTERVAL 500 // Milli Seconds - - -// This wrapper is used to adapt device DoIdle method as entry point for MS thread -DWORD WINAPI WCMRPortAudioDevice::__DoIdle__(LPVOID lpThreadParameter) -{ - WCMRPortAudioDevice* pDevice = (WCMRPortAudioDevice*)lpThreadParameter; - pDevice->DoIdle(); - return 0; -} - -//********************************************************************************************** -// WCMRPortAudioDevice::WCMRPortAudioDevice -// -//! Constructor for the audio device. Opens the PA device -//! and gets information about the device. -//! Starts the thread which will process requests to this device -//! such as determining supported sampling rates, buffer sizes, and channel counts. -//! -//! \param *pManager : The audio device manager that's managing this device. -//! \param deviceID : The port audio device ID. -//! \param useMultithreading : Whether to use multi-threading for audio processing. Default is true. -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRPortAudioDevice::WCMRPortAudioDevice (WCMRPortAudioDeviceManager *pManager, unsigned int deviceID, bool useMultithreading, bool bNoCopy) : - WCMRNativeAudioDevice (pManager, useMultithreading, bNoCopy) - , m_SampleCounter(0) - , m_BufferSizeChangeRequested (0) - , m_BufferSizeChangeReported (0) - , m_ResetRequested (0) - , m_ResetReported (0) - , m_ResyncRequested (0) - , m_ResyncReported (0) - , m_DropsDetected(0) - , m_DropsReported(0) - , m_IgnoreThisDrop(true) - , m_hDeviceProcessingThread(NULL) - , m_DeviceProcessingThreadID(0) - , m_hUpdateDeviceInfoRequestedEvent(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hUpdateDeviceInfoDone(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hActivateRequestedEvent(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hActivationDone(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hDeActivateRequestedEvent(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hDeActivationDone(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hStartStreamingRequestedEvent(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hStartStreamingDone(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hStopStreamingRequestedEvent(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hStopStreamingDone(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hResetRequestedEvent(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hResetDone(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hResetFromDevRequestedEvent(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hBufferSizeChangedEvent(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hSampleRateChangedEvent(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hExitIdleThread(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_hDeviceInitialized(CreateEvent(NULL, FALSE, FALSE, NULL)) - , m_lastErr(eNoErr) -{ - AUTO_FUNC_DEBUG; - - //Set initial device info... - m_DeviceID = deviceID; - m_PortAudioStream = NULL; - m_CurrentSamplingRate = DEFAULT_SR; - m_CurrentBufferSize = DEFAULT_BUFFERSIZE; - m_StopRequested = true; - m_pInputData = NULL; - - //initialize device processing thread - //the divice become alive and now is able to process requests - m_hDeviceProcessingThread = CreateThread( NULL, 0, __DoIdle__, (LPVOID)this, 0, &m_DeviceProcessingThreadID ); - - if (!m_hDeviceProcessingThread) - { - DEBUG_MSG("API::Device " << m_DeviceName << " cannot create processing thread"); - throw eGenericErr; - } - - WaitForSingleObject(m_hDeviceInitialized, INFINITE); - - if (ConnectionStatus() == DeviceErrors) - { - throw m_lastErr; - } -} - - -void WCMRPortAudioDevice::initDevice() -{ - // Initialize COM for this thread - std::cout << "API::Device " << m_DeviceID << " initializing COM" << std::endl; - - if (S_OK == CoInitialize(NULL) ) - { - // Initialize PA - Pa_Initialize(); - - updateDeviceInfo(); - - //should use a valid current SR... - if (m_SamplingRates.size()) - { - //see if the current sr is present in the sr list, if not, use the first one! - std::vector::iterator intIter = find(m_SamplingRates.begin(), m_SamplingRates.end(), m_CurrentSamplingRate); - if (intIter == m_SamplingRates.end()) - { - //not found... use the first one - m_CurrentSamplingRate = m_SamplingRates[0]; - } - } - else - std::cout << "API::Device " << m_DeviceName << " Device does not support any sample rate of ours" << std::endl; - - //should use a valid current buffer size - if (m_BufferSizes.size()) - { - //see if the current sr is present in the buffersize list, if not, use the first one! - std::vector::iterator intIter = find(m_BufferSizes.begin(), m_BufferSizes.end(), m_CurrentBufferSize); - if (intIter == m_BufferSizes.end()) - { - //not found... use the first one - m_CurrentBufferSize = m_BufferSizes[0]; - } - } - - //build our input/output level lists - for (unsigned int currentChannel = 0; currentChannel < m_InputChannels.size(); currentChannel++) - { - m_InputLevels.push_back (0.0); - } - - //build our input/output level lists - for (unsigned int currentChannel = 0; currentChannel < m_OutputChannels.size(); currentChannel++) - { - m_OutputLevels.push_back (0.0); - } - - std::cout << "API::Device " << m_DeviceName << " Device has been initialized" << std::endl; - m_ConnectionStatus = DeviceDisconnected; - m_lastErr = eNoErr; - } - else - { - /*Replace with debug trace*/std::cout << "API::Device " << m_DeviceName << " cannot initialize COM" << std::endl; - DEBUG_MSG("Device " << m_DeviceName << " cannot initialize COM"); - m_ConnectionStatus = DeviceErrors; - m_lastErr = eSomeThingNotInitailzed; - SetEvent(m_hExitIdleThread); - } - - SetEvent(m_hDeviceInitialized); -} - -void WCMRPortAudioDevice::terminateDevice() -{ - std::cout << "API::Device " << m_DeviceName << " Terminating DEVICE" << std::endl; - - //If device is streaming, need to stop it! - if (Streaming()) - { - stopStreaming(); - } - - //If device is active (meaning stream is open) we need to close it. - if (Active()) - { - deactivateDevice(); - } - - std::cout << "API::Device " << m_DeviceName << " Terminating PA" << std::endl; - - //Deinitialize PA - Pa_Terminate(); -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::~WCMRPortAudioDevice -// -//! Destructor for the audio device. The base release all the connections that were created, if -//! they have not been already destroyed! Here we simply stop streaming, and close device -//! handles if necessary. -//! -//! \param none -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRPortAudioDevice::~WCMRPortAudioDevice () -{ - AUTO_FUNC_DEBUG; - - std::cout << "API::Destroying Device Instance: " << DeviceName() << std::endl; - try - { - //Stop deviceprocessing thread - SignalObjectAndWait(m_hExitIdleThread, m_hDeviceProcessingThread, INFINITE, false); - - std::cout << "API::Device " << m_DeviceName << " Processing Thread is stopped" << std::endl; - - CloseHandle(m_hDeviceProcessingThread); - - //Now it's safe to free all event handlers - CloseHandle(m_hUpdateDeviceInfoRequestedEvent); - CloseHandle(m_hUpdateDeviceInfoDone); - CloseHandle(m_hActivateRequestedEvent); - CloseHandle(m_hActivationDone); - CloseHandle(m_hDeActivateRequestedEvent); - CloseHandle(m_hDeActivationDone); - CloseHandle(m_hStartStreamingRequestedEvent); - CloseHandle(m_hStartStreamingDone); - CloseHandle(m_hStopStreamingRequestedEvent); - CloseHandle(m_hStopStreamingDone); - CloseHandle(m_hResetRequestedEvent); - CloseHandle(m_hResetDone); - CloseHandle(m_hResetFromDevRequestedEvent); - CloseHandle(m_hBufferSizeChangedEvent); - CloseHandle(m_hSampleRateChangedEvent); - CloseHandle(m_hExitIdleThread); - CloseHandle(m_hDeviceInitialized); - } - catch (...) - { - //destructors should absorb exceptions, no harm in logging though!! - DEBUG_MSG ("Exception during destructor"); - } -} - - -WTErr WCMRPortAudioDevice::UpdateDeviceInfo () -{ - std::cout << "API::Device (ID:)" << m_DeviceID << " Updating device info" << std::endl; - - SignalObjectAndWait(m_hUpdateDeviceInfoRequestedEvent, m_hUpdateDeviceInfoDone, INFINITE, false); - - return eNoErr; -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::updateDeviceInfo -// -//! Must be called be device processing thread -//! Updates Device Information about channels, sampling rates, buffer sizes. -//! -//! \return Nothing. -//! -//********************************************************************************************** -void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/) -{ - AUTO_FUNC_DEBUG; - - //get device info - const PaDeviceInfo *pDeviceInfo = Pa_GetDeviceInfo(m_DeviceID); - - //update name. - m_DeviceName = pDeviceInfo->name; - - //following parameters are needed opening test stream and for sample rates validation - PaStreamParameters inputParameters, outputParameters; - PaStreamParameters *pInS = NULL, *pOutS = NULL; - - inputParameters.device = m_DeviceID; - inputParameters.channelCount = pDeviceInfo->maxInputChannels; - inputParameters.sampleFormat = paFloat32 | paNonInterleaved; - inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ - inputParameters.hostApiSpecificStreamInfo = 0; - - if (inputParameters.channelCount) - pInS = &inputParameters; - - outputParameters.device = m_DeviceID; - outputParameters.channelCount = pDeviceInfo->maxOutputChannels; - outputParameters.sampleFormat = paFloat32; - outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ - outputParameters.hostApiSpecificStreamInfo = 0; - - if (outputParameters.channelCount) - pOutS = &outputParameters; - - //////////////////////////////////////////////////////////////////////////////////// - //update list of supported SRs... - m_SamplingRates.clear(); - - // now iterate through our standard SRs and check if they are supported by device - // store them for this device - for(int sr=0; gAllSampleRates[sr] > 0; sr++) - { - PaError err = Pa_IsFormatSupported(pInS, pOutS, gAllSampleRates[sr]); - if( err == paFormatIsSupported) - { - m_SamplingRates.push_back ((int)gAllSampleRates[sr]); - } - } - - /////////////////////////////////////////////////////////////////////////////////// - //update buffer sizes - m_BufferSizes.clear(); - bool useDefaultBuffers = true; - - // In ASIO Windows, the buffer size is set from the sound device manufacturer's control panel - long minSize, maxSize, preferredSize, granularity; - PaError err = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity); - - if (err == paNoError) - { - std::cout << "API::Device " << m_DeviceName << " Buffers: " << minSize << " " << maxSize << " " << preferredSize << std::endl; - - m_BufferSizes.push_back (preferredSize); - useDefaultBuffers = false; - } - else - { - std::cout << "API::Device" << m_DeviceName << " Preffered buffer size is not supported" << std::endl; - } - - if (useDefaultBuffers) - { - std::cout << "API::Device" << m_DeviceName << " Using default buffer sizes " <maxInputChannels; - int maxOutputChannels = pDeviceInfo->maxOutputChannels; - - //Update input channels - m_InputChannels.clear(); - for (int channel = 0; channel < maxInputChannels; channel++) - { - const char* channelName[32]; // 32 is max leth declared by PortAudio for this operation - std::stringstream chNameStream; - - PaError error = PaAsio_GetInputChannelName(m_DeviceID, channel, channelName); - - chNameStream << (channel+1) << " - "; - - if (error == paNoError) - { - chNameStream << *channelName; - } - else - { - chNameStream << "Input " << (channel+1); - } - - m_InputChannels.push_back (chNameStream.str()); - } - - - //Update output channels - m_OutputChannels.clear(); - for (int channel = 0; channel < maxOutputChannels; channel++) - { - const char* channelName[32]; // 32 is max leth declared by PortAudio for this operation - std::stringstream chNameStream; - - PaError error = PaAsio_GetOutputChannelName(m_DeviceID, channel, channelName); - - chNameStream << (channel+1) << " - "; - - if (error == paNoError) - { - chNameStream << *channelName; - } - else - { - chNameStream << "Output " << (channel+1); - } - - m_OutputChannels.push_back (chNameStream.str()); - } - } - - std::cout << "API::Device" << m_DeviceName << " Device info update has been finished" << std::endl; - - if (callerIsWaiting) - SetEvent(m_hUpdateDeviceInfoDone); -} - - -PaError WCMRPortAudioDevice::testStateValidness(int sampleRate, int bufferSize) -{ - PaError paErr = paNoError; - - //get device info - const PaDeviceInfo *pDeviceInfo = Pa_GetDeviceInfo(m_DeviceID); - - //following parameters are needed opening test stream and for sample rates validation - PaStreamParameters inputParameters, outputParameters; - PaStreamParameters *pInS = NULL, *pOutS = NULL; - - inputParameters.device = m_DeviceID; - inputParameters.channelCount = pDeviceInfo->maxInputChannels; - inputParameters.sampleFormat = paFloat32 | paNonInterleaved; - inputParameters.suggestedLatency = 0; - inputParameters.hostApiSpecificStreamInfo = 0; - - if (inputParameters.channelCount) - pInS = &inputParameters; - - outputParameters.device = m_DeviceID; - outputParameters.channelCount = pDeviceInfo->maxOutputChannels; - outputParameters.sampleFormat = paFloat32; - outputParameters.suggestedLatency = 0; - outputParameters.hostApiSpecificStreamInfo = 0; - - if (outputParameters.channelCount) - pOutS = &outputParameters; - - PaStream *portAudioStream = NULL; - - //sometimes devices change buffer size if sample rate changes - //it updates buffer size during stream opening - //we need to find out how device would behave with current sample rate - //try opening test stream to load device driver for current sample rate and buffer size - paErr = Pa_OpenStream (&portAudioStream, pInS, pOutS, sampleRate, bufferSize, paDitherOff, NULL, NULL); - - if (portAudioStream) - { - // close test stream - Pa_CloseStream (portAudioStream); - portAudioStream = NULL; - } - - return paErr; -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::CurrentSamplingRate -// -//! The device's current sampling rate. This may be overridden, if the device needs to -//! query the driver for the current rate. -//! -//! \param none -//! -//! \return The device's current sampling rate. -1 on error. -//! -//********************************************************************************************** -int WCMRPortAudioDevice::CurrentSamplingRate () -{ - AUTO_FUNC_DEBUG; - //ToDo: Perhaps for ASIO devices that are active, we should retrive the SR from the device... - - return (m_CurrentSamplingRate); -} - - -WTErr WCMRPortAudioDevice::SetActive (bool newState) -{ - if (newState == true) - { - std::cout << "API::Device " << m_DeviceName << " Activation requested" << std::endl; - SignalObjectAndWait(m_hActivateRequestedEvent, m_hActivationDone, INFINITE, false); - } - else - { - std::cout << "API::Device " << m_DeviceName << " Deactivation requested" << std::endl; - SignalObjectAndWait(m_hDeActivateRequestedEvent, m_hDeActivationDone, INFINITE, false); - } - - if (newState == Active() ) - return eNoErr; - else - return eGenericErr; -} - - -WTErr WCMRPortAudioDevice::SetStreaming (bool newState) -{ - if (newState == true) - { - std::cout << "API::Device " << m_DeviceName << " Stream start requested" << std::endl; - SignalObjectAndWait(m_hStartStreamingRequestedEvent, m_hStartStreamingDone, INFINITE, false); - } - else - { - std::cout << "API::Device " << m_DeviceName << " Stream stop requested" << std::endl; - SignalObjectAndWait(m_hStopStreamingRequestedEvent, m_hStopStreamingDone, INFINITE, false); - } - - if (newState == Streaming() ) - return eNoErr; - else - return eGenericErr; -} - - -WTErr WCMRPortAudioDevice::ResetDevice() -{ - std::cout << "API::Device: " << m_DeviceName << " Reseting device" << std::endl; - - SignalObjectAndWait(m_hResetRequestedEvent, m_hResetDone, INFINITE, false); - - if (ConnectionStatus() == DeviceErrors) - { - return m_lastErr; - } - - return eNoErr; -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::SetCurrentSamplingRate -// -//! Change the sampling rate to be used by the device. -//! -//! \param newRate : The rate to use (samples per sec). -//! -//! \return eNoErr always. The derived classes may return error codes. -//! -//********************************************************************************************** -WTErr WCMRPortAudioDevice::SetCurrentSamplingRate (int newRate) -{ - AUTO_FUNC_DEBUG; - std::vector::iterator intIter; - WTErr retVal = eNoErr; - - //changes the status. - int oldRate = CurrentSamplingRate(); - bool oldActive = Active(); - - //no change, nothing to do - if (oldRate == newRate) - return (retVal); - - //see if this is one of our supported rates... - intIter = find(m_SamplingRates.begin(), m_SamplingRates.end(), newRate); - - if (intIter == m_SamplingRates.end()) - { - //Can't change, perhaps use an "invalid param" type of error - retVal = eCommandLineParameter; - return (retVal); - } - - if (Streaming()) - { - //Can't change, perhaps use an "in use" type of error - retVal = eGenericErr; - return (retVal); - } - - //make the change... - m_CurrentSamplingRate = newRate; - PaError paErr = PaAsio_SetStreamSampleRate (m_PortAudioStream, m_CurrentSamplingRate); - Pa_Sleep(PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS); // sleep some time to make sure the change has place - - if (paErr != paNoError) - { - std::cout << "Sample rate change failed: " << Pa_GetErrorText (paErr) << std::endl; - if (paErr == paUnanticipatedHostError) - std::cout << "Details: "<< Pa_GetLastHostErrorInfo ()->errorText << "; code: " << Pa_GetLastHostErrorInfo ()->errorCode << std::endl; - - retVal = eWrongObjectState; - } - - return (retVal); -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::CurrentBufferSize -// -//! The device's current buffer size in use. This may be overridden, if the device needs to -//! query the driver for the current size. -//! -//! \param none -//! -//! \return The device's current buffer size. 0 on error. -//! -//********************************************************************************************** -int WCMRPortAudioDevice::CurrentBufferSize () -{ - return m_CurrentBufferSize; -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::SetCurrentBufferSize -// -//! Change the buffer size to be used by the device. This will most likely be overridden, -//! the base class simply updates the member variable. -//! -//! \param newSize : The buffer size to use (in sample-frames) -//! -//! \return eNoErr always. The derived classes may return error codes. -//! -//********************************************************************************************** -WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize) -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - std::vector::iterator intIter; - - if (Streaming()) - { - //Can't change, perhaps use an "in use" type of error - retVal = eGenericErr; - return (retVal); - } - - // Buffer size for ASIO devices can be changed from the control panel only - // We have driver driven logi here - if (m_CurrentBufferSize != newSize ) - { - // we have only one aloved buffer size which is preffered by PA - // this is the only value which could be set - newSize = m_BufferSizes[0]; - int bufferSize = newSize; - // notify client to update buffer size - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize); - return retVal; - } - - return (retVal); -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::ConnectionStatus -// -//! Retrieves the device's current connection status. This will most likely be overridden, -//! in case some driver communication is required to query the status. -//! -//! \param none -//! -//! \return A ConnectionStates value. -//! -//********************************************************************************************** -WCMRPortAudioDevice::ConnectionStates WCMRPortAudioDevice::ConnectionStatus () -{ - AUTO_FUNC_DEBUG; - //ToDo: May want to do something more to extract the actual status! - return (m_ConnectionStatus); - -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::activateDevice -// -//! IS CALLED BY PROCESS THREAD -//! Sets the device into "active" state. Essentially, opens the PA device. -//! If it's an ASIO device it may result in buffer size change in some cases. -//! -//********************************************************************************************** -void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/) -{ - AUTO_FUNC_DEBUG; - - PaError paErr = paNoError; - - // if device is not active activate it - if (!Active() ) - { - PaStreamParameters inputParameters, outputParameters; - PaStreamParameters *pInS = NULL, *pOutS = NULL; - - const PaDeviceInfo *pDeviceInfo = Pa_GetDeviceInfo(m_DeviceID); - const PaHostApiInfo *pHostApiInfo = Pa_GetHostApiInfo(pDeviceInfo->hostApi); - - inputParameters.device = m_DeviceID; - inputParameters.channelCount = (int)m_InputChannels.size(); - inputParameters.sampleFormat = paFloat32 | paNonInterleaved; - inputParameters.suggestedLatency = Pa_GetDeviceInfo(m_DeviceID)->defaultLowInputLatency; - inputParameters.hostApiSpecificStreamInfo = 0; - - if (inputParameters.channelCount) - pInS = &inputParameters; - - outputParameters.device = m_DeviceID; - outputParameters.channelCount = (int)m_OutputChannels.size(); - outputParameters.sampleFormat = paFloat32; - outputParameters.suggestedLatency = Pa_GetDeviceInfo(m_DeviceID)->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = 0; - - if (outputParameters.channelCount) - pOutS = &outputParameters; - - std::cout << "API::Device " << m_DeviceName << " Opening device stream " << std::endl; - std::cout << "Sample rate: " << m_CurrentSamplingRate << " buffer size: " << m_CurrentBufferSize << std::endl; - paErr = Pa_OpenStream(&m_PortAudioStream, - pInS, - pOutS, - m_CurrentSamplingRate, - m_CurrentBufferSize, - paDitherOff, - WCMRPortAudioDevice::TheCallback, - this); - - if(paErr != paNoError) - { - std::cout << "Cannot open streamm with buffer: "<< m_CurrentBufferSize << " Error: " << Pa_GetErrorText (paErr) << std::endl; - - if (paErr == paUnanticipatedHostError) - std::cout << "Error details: "<< Pa_GetLastHostErrorInfo ()->errorText << "; code: " << Pa_GetLastHostErrorInfo ()->errorCode << std::endl; - } - - if(paErr == paNoError) - { - std::cout << "Stream has been opened! "<< std::endl; - - // check for possible changes - long minSize, maxSize, preferredSize, granularity; - PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity); - - std::cout << "Checked if buffer size changed "<< std::endl; - if (paErr == paNoError && m_CurrentBufferSize != preferredSize) - { - std::cout << "Buffer size has changed "<< std::endl; - m_CurrentBufferSize = preferredSize; - m_BufferSizes.clear(); - m_BufferSizes.push_back(preferredSize); - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&preferredSize); - } - - m_DropsDetected = 0; - m_DropsReported = 0; - m_IgnoreThisDrop = true; - - if (pHostApiInfo->type == paASIO) - { - m_BufferSizeChangeRequested = 0; - m_BufferSizeChangeReported = 0; - m_ResetRequested = 0; - m_ResetReported = 0; - m_ResyncRequested = 0; - m_ResyncReported = 0; - std::cout << "Installing new mesage hook "<< std::endl; - PaAsio_SetMessageHook (StaticASIOMessageHook, this); - } - m_IsActive = true; - m_ConnectionStatus = DeviceAvailable; - m_lastErr = eNoErr; - } - else - { - //failed, do not update device state - std::cout << "Failed to open pa stream: " << Pa_GetErrorText (paErr) << std::endl; - DEBUG_MSG( "Failed to open pa stream: " << Pa_GetErrorText (paErr) ); - m_ConnectionStatus = DeviceErrors; - m_lastErr = eAsioFailed; - } - - - } - - std::cout << "Activation is DONE "<< std::endl; - - if (callerIsWaiting) - SetEvent(m_hActivationDone); -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::deactivateDevice -// -//! IS CALLED BY PROCESS THREAD -//! Sets the device into "inactive" state. Essentially, closes the PA device. -//! -//********************************************************************************************** -void WCMRPortAudioDevice::deactivateDevice (bool callerIsWaiting/*=false*/) -{ - AUTO_FUNC_DEBUG; - - PaError paErr = paNoError; - - if (Active() ) - { - if (Streaming()) - { - stopStreaming (); - } - - if (m_PortAudioStream) - { - //close the stream first - std::cout << "API::Device" << m_DeviceName << " Closing device stream" << std::endl; - paErr = Pa_CloseStream (m_PortAudioStream); - if(paErr == paNoError) - { - m_PortAudioStream = NULL; - m_DropsDetected = 0; - m_DropsReported = 0; - m_IgnoreThisDrop = true; - m_BufferSizeChangeRequested = 0; - m_BufferSizeChangeReported = 0; - m_ResetRequested = 0; - m_ResetReported = 0; - m_ResyncRequested = 0; - m_ResyncReported = 0; - PaAsio_SetMessageHook (NULL, NULL); - - //finaly set device state to "not active" - m_IsActive = false; - m_ConnectionStatus = DeviceDisconnected; - m_lastErr = eNoErr; - } - else - { - //failed, do not update device state - std::cout << "Failed to close pa stream stream " << Pa_GetErrorText (paErr) << std::endl; - DEBUG_MSG( "Failed to open pa stream stream " << Pa_GetErrorText (paErr) ); - m_ConnectionStatus = DeviceErrors; - m_lastErr = eAsioFailed; - } - } - } - - if (callerIsWaiting) - SetEvent(m_hDeActivationDone); -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::startStreaming -// -//! Sets the devices into "streaming" state. Calls PA's Start stream routines. -//! This roughly corresponds to calling Start on the lower level interface. -//! -//********************************************************************************************** -void WCMRPortAudioDevice::startStreaming (bool callerIsWaiting/*=false*/) -{ - AUTO_FUNC_DEBUG; - - // proceed if the device is not streaming - if (!Streaming () ) - { - PaError paErr = paNoError; - m_StopRequested = false; - m_SampleCounter = 0; - - std::cout << "API::Device" << m_DeviceName << " Starting device stream" << std::endl; - - //get device info - const PaDeviceInfo *pDeviceInfo = Pa_GetDeviceInfo(m_DeviceID); - - unsigned int inChannelCount = pDeviceInfo->maxInputChannels; - unsigned int outChannelCount = pDeviceInfo->maxOutputChannels; - - // Prepare for streaming - tell Engine to do the initialization for process callback - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming); - - paErr = Pa_StartStream( m_PortAudioStream ); - - if(paErr == paNoError) - { - // if the stream was started successfully - m_IsStreaming = true; - std::cout << "API::Device" << m_DeviceName << " Device is streaming" << std::endl; - } - else - { - std::cout << "Failed to start PA stream: " << Pa_GetErrorText (paErr) << std::endl; - DEBUG_MSG( "Failed to start PA stream: " << Pa_GetErrorText (paErr) ); - m_lastErr = eGenericErr; - } - } - - if (callerIsWaiting) - SetEvent(m_hStartStreamingDone); -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::stopStreaming -// -//! Sets the devices into "not streaming" state. Calls PA's Stop stream routines. -//! This roughly corresponds to calling Stop on the lower level interface. -//! -//********************************************************************************************** -void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/) -{ - AUTO_FUNC_DEBUG; - - // proceed if the device is streaming - if (Streaming () ) - { - PaError paErr = paNoError; - m_StopRequested = true; - - std::cout << "API::Device " << m_DeviceName << " Stopping device stream" << std::endl; - paErr = Pa_StopStream( m_PortAudioStream ); - - if(paErr == paNoError || paErr == paStreamIsStopped) - { - // if the stream was stopped successfully - m_IsStreaming = false; - m_pInputData = NULL; - } - else - { - std::cout << "Failed to stop PA stream normaly! Error:" << Pa_GetErrorText (paErr) << std::endl; - DEBUG_MSG( "Failed to stop PA stream normaly! Error:" << Pa_GetErrorText (paErr) ); - m_lastErr = eGenericErr; - } - } - - if (callerIsWaiting) - SetEvent(m_hStopStreamingDone); -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::resetDevice -// -//! Resets the device, updates device info. Importnat: does PA reinitialization calling -//! Pa_terminate/Pa_initialize functions. -//! -//! \param none -//! -//! \return nothing -//! -//********************************************************************************************** -void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ ) -{ - PaError paErr = paNoError; - - // Keep device sates - bool wasStreaming = Streaming(); - bool wasActive = Active(); - - // Reset the device - stopStreaming(); - deactivateDevice(); - - // Cache device buffer size as it might be changed during reset - int oldBufferSize = m_CurrentBufferSize; - - // Now, validate the state and update device info if required - unsigned int retry = PROPERTY_CHANGE_RETRIES; - while (retry-- ) - { - // Reinitialize PA - Pa_Terminate(); - Pa_Initialize(); - - std::cout << "Updating device state... " << std::endl; - // update device info - updateDeviceInfo(); - - // take up buffers - long minSize, maxSize, preferredSize, granularity; - PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity); - - if (paErr != paNoError) - { - continue; - } - m_CurrentBufferSize = preferredSize; - - paErr = testStateValidness(m_CurrentSamplingRate, m_CurrentBufferSize); - if (paNoError == paErr) - { - std::cout << "Device state is valid" << std::endl; - break; - } - - std::cout << "Cannot start with current state: sr: " << m_CurrentSamplingRate << " bs:" << m_CurrentBufferSize \ - << "\nReason: " << Pa_GetErrorText (paErr) << std::endl; - if (paErr == paUnanticipatedHostError) - std::cout << "Details: "<< Pa_GetLastHostErrorInfo ()->errorText << "; code: " << Pa_GetLastHostErrorInfo ()->errorCode << std::endl; - - std::cout << "Will try again in " << DEVICE_INFO_UPDATE_SLEEP_TIME_MILLISECONDS << "msec" << std::endl; - - Pa_Sleep(DEVICE_INFO_UPDATE_SLEEP_TIME_MILLISECONDS); - } - - if (paErr == paNoError) - { - // Notify the Application about device setting changes - if (oldBufferSize != m_CurrentBufferSize) - { - std::cout << "API::Device" << m_DeviceName << " buffer size changed" << std::endl; - int bufferSize = m_CurrentBufferSize; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize); - } - - // Activate the device if it was active before - if (wasActive) - activateDevice(); - - // Resume streaming if the device was streaming before - if(wasStreaming && m_lastErr == eNoErr && m_ConnectionStatus == DeviceAvailable) - { - // start streaming - startStreaming(); - } - } else { - m_ConnectionStatus = DeviceErrors; - m_lastErr = eWrongObjectState; - } - - if (callerIsWaiting) - SetEvent(m_hResetDone); -} - - -#ifdef PLATFORM_WINDOWS - -long WCMRPortAudioDevice::StaticASIOMessageHook (void *pRefCon, long selector, long value, void* message, double* opt) -{ - if (pRefCon) - { - return ((WCMRPortAudioDevice*)(pRefCon))->ASIOMessageHook (selector, value, message, opt); - } - else - return -1; -} - -long WCMRPortAudioDevice::ASIOMessageHook (long selector, long WCUNUSEDPARAM(value), void* WCUNUSEDPARAM(message), double* WCUNUSEDPARAM(opt)) -{ - switch(selector) - { - case kAsioResyncRequest: - m_ResyncRequested++; - std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioResyncRequest" << std::endl; - break; - - case kAsioLatenciesChanged: - m_BufferSizeChangeRequested++; - std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioLatenciesChanged" << std::endl; - if (m_ResetRequested == 0) { - m_ResetRequested++; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); - } - break; - - case kAsioBufferSizeChange: - m_BufferSizeChangeRequested++; - std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- m_BufferSizeChangeRequested" << std::endl; - if (m_ResetRequested == 0) { - m_ResetRequested++; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); - } - break; - - case kAsioResetRequest: - std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioResetRequest" << std::endl; - m_ResetRequested++; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); - break; - - case kAsioOverload: - m_DropsDetected++; - std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioOverload" << std::endl; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::Dropout); - break; - } - return 0; -} - -#endif - - -//********************************************************************************************** -// WCMRPortAudioDevice::DoIdle -// -//! A place for doing idle time processing. The other derived classes will probably do something -//! meaningful. -//! -//! \param none -//! -//! \return eNoErr always. -//! -//********************************************************************************************** -WTErr WCMRPortAudioDevice::DoIdle () -{ - WTErr retVal = eNoErr; - - std::cout << "WCMRPortAudioDevice::DoIdle ()" << std::endl; - HANDLE hEvents[] = - { - m_hUpdateDeviceInfoRequestedEvent, - m_hActivateRequestedEvent, - m_hDeActivateRequestedEvent, - m_hStartStreamingRequestedEvent, - m_hStopStreamingRequestedEvent, - m_hBufferSizeChangedEvent, - m_hSampleRateChangedEvent, - m_hResetRequestedEvent, - m_hResetFromDevRequestedEvent, - m_hExitIdleThread - }; - - const size_t hEventsSize = sizeof(hEvents)/sizeof(hEvents[0]); - - initDevice(); - - for(;;) - { - DWORD result = WaitForMultipleObjects (hEventsSize, hEvents, FALSE, INFINITE); - result = result - WAIT_OBJECT_0; - - if ((result < 0) || (result >= hEventsSize)) { - std::cout << "\t\t\t\t\t\t\tWCMRPortAudioDevice::DoIdle () -> (result < 0) || (result >= hEventsSize):" << result << std::endl; - retVal = eGenericErr; - break; - } - - if (hEvents[result] == m_hExitIdleThread) { - std::cout << "\t\t\t\t\t\t\tWCMRPortAudioDevice::DoIdle () -> m_hExitIdleThread" << result << std::endl; - retVal = eNoErr; - break; - } - - if (hEvents[result] == m_hUpdateDeviceInfoRequestedEvent) { - std::cout << "\t\t\t\t\t\tupdate requested ..." << std::endl; - updateDeviceInfo(true); - } - - if (hEvents[result] == m_hActivateRequestedEvent) { - std::cout << "\t\t\t\t\t\tactivation requested ..." << std::endl; - activateDevice(true); - } - - if (hEvents[result] == m_hDeActivateRequestedEvent) { - std::cout << "\t\t\t\t\t\tdeactivation requested ..." << std::endl; - deactivateDevice(true); - } - - if (hEvents[result] == m_hStartStreamingRequestedEvent) { - std::cout << "\t\t\t\t\t\tStart stream requested ..." << std::endl; - startStreaming(true); - } - - if (hEvents[result] == m_hStopStreamingRequestedEvent) { - std::cout << "\t\t\t\t\t\tStop stream requested ..." << std::endl; - stopStreaming(true); - } - - if (hEvents[result] == m_hResetRequestedEvent) { - std::cout << "\t\t\t\t\t\treset requested ..." << std::endl; - resetDevice(true); - } - - if (hEvents[result] == m_hResetFromDevRequestedEvent) { - std::cout << "\t\t\t\t\t\treset requested from device..." << std::endl; - resetDevice(); - } - - if (hEvents[result] == m_hBufferSizeChangedEvent) { - std::cout << "\t\t\t\t\t\tbuffer size changed from device..." << std::endl; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged); - } - - if (hEvents[result] == m_hSampleRateChangedEvent) { - std::cout << "\t\t\t\t\t\tsample rate changed from device..." << std::endl; - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::SamplingRateChanged); - } - } - - terminateDevice(); - - return retVal; -} - - -//********************************************************************************************** -// WCMRPortAudioDevice::SetMonitorChannels -// -//! Used to set the channels to be used for monitoring. -//! -//! \param leftChannel : Left monitor channel index. -//! \param rightChannel : Right monitor channel index. -//! -//! \return eNoErr always, the derived classes may return appropriate errors. -//! -//********************************************************************************************** -WTErr WCMRPortAudioDevice::SetMonitorChannels (int leftChannel, int rightChannel) -{ - AUTO_FUNC_DEBUG; - //This will most likely be overridden, the base class simply - //changes the member. - m_LeftMonitorChannel = leftChannel; - m_RightMonitorChannel = rightChannel; - return (eNoErr); -} - - - -//********************************************************************************************** -// WCMRPortAudioDevice::SetMonitorGain -// -//! Used to set monitor gain (or atten). -//! -//! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB) -//! -//! \return eNoErr always, the derived classes may return appropriate errors. -//! -//********************************************************************************************** -WTErr WCMRPortAudioDevice::SetMonitorGain (float newGain) -{ - AUTO_FUNC_DEBUG; - //This will most likely be overridden, the base class simply - //changes the member. - - m_MonitorGain = newGain; - return (eNoErr); -} - - - - -//********************************************************************************************** -// WCMRPortAudioDevice::ShowConfigPanel -// -//! Used to show device specific config/control panel. Some interfaces may not support it. -//! Some interfaces may require the device to be active before it can display a panel. -//! -//! \param pParam : A device/interface specific parameter, should be the app window handle for ASIO. -//! -//! \return eNoErr always, the derived classes may return errors. -//! -//********************************************************************************************** -WTErr WCMRPortAudioDevice::ShowConfigPanel (void *pParam) -{ - AUTO_FUNC_DEBUG; - WTErr retVal = eNoErr; - - if (Active() && !m_ResetRequested ) - { -#ifdef PLATFORM_WINDOWS - if(Pa_GetHostApiInfo(Pa_GetDeviceInfo(m_DeviceID)->hostApi)->type == paASIO) - { - // stop and deactivate the device - bool wasStreaming = Streaming(); - SetActive(false); - - // show control panel for the device - if (PaAsio_ShowControlPanel (m_DeviceID, pParam) != paNoError) - retVal = eGenericErr; - - // restore previous state for the device - SetActive(true); - if (wasStreaming) - SetStreaming(true); - - - // reset device to pick up changes - if (!m_ResetRequested) { - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset); - } - } -#else - pParam = pParam; -#endif //_windows - } - - return (retVal); -} - - -//***************************************************************************************************** -// WCMRPortAudioDevice::TheCallback -// -//! The (static) Port Audio Callback function. This is a static member. It calls on the AudioCallback in the -//! WCMRPortAudioDevice to do the real work. -//! -//! \param pInputBuffer: pointer to input buffer. -//! \param pOutputBuffer: pointer to output buffer. -//! \param framesPerBuffer: number of sample frames per buffer. -//! \param pTimeInfo: time info for PaStream callback. -//! \param statusFlags: -//! \param pUserData: pointer to user data, in our case the WCMRPortAudioDevice object. -//! -//! \return true to stop streaming else returns false. -//****************************************************************************************************** -int WCMRPortAudioDevice::TheCallback (const void *pInputBuffer, void *pOutputBuffer, unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* /*pTimeInfo*/, PaStreamCallbackFlags statusFlags, void *pUserData ) -{ - WCMRPortAudioDevice *pMyDevice = (WCMRPortAudioDevice *)pUserData; - if (pMyDevice) - return pMyDevice->AudioCallback ((float *)pInputBuffer, (float *)pOutputBuffer, framesPerBuffer, - (statusFlags & (paInputOverflow | paOutputUnderflow)) != 0); - else - return (true); - -} - - - -//********************************************************************************************** -// WCMRPortAudioDevice::AudoiCallback -// -//! Here's where the actual audio processing happens. We call upon all the active connections' -//! sinks to provide data to us which can be put/mixed in the output buffer! Also, we make the -//! input data available to any sources that may call upon us during this time! -//! -//! \param *pInputBuffer : Points to a buffer with recorded data. -//! \param *pOutputBuffer : Points to a buffer to receive playback data. -//! \param framesPerBuffer : Number of sample frames in input and output buffers. Number of channels, -//! which are interleaved, is fixed at Device Open (Active) time. In this implementation, -//! the number of channels are fixed to use the maximum available. -//! \param dropsDetected : True if dropouts were detected in input or output. Can be used to signal the GUI. -//! -//! \return true -//! -//********************************************************************************************** -int WCMRPortAudioDevice::AudioCallback( const float *pInputBuffer, float *pOutputBuffer, unsigned long framesPerBuffer, bool dropsDetected ) -{ - UMicroseconds theStartTime; - - // detect drops - if (dropsDetected) - { - if (m_IgnoreThisDrop) - m_IgnoreThisDrop = false; //We'll ignore once, just once! - else - m_DropsDetected++; - } - - m_pInputData = pInputBuffer; - - // VKamyshniy: Is this a right place to call the client???: - struct WCMRAudioDeviceManagerClient::AudioCallbackData audioCallbackData = - { - m_pInputData, - pOutputBuffer, - framesPerBuffer, - m_SampleCounter, - theStartTime.MicroSeconds()*1000 - }; - - m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::AudioCallback, (void *)&audioCallbackData ); - - //Don't try to access after this call returns! - m_pInputData = NULL; - - m_SampleCounter += framesPerBuffer; - - return m_StopRequested; -} - - - - -//********************************************************************************************** -// WCMRPortAudioDeviceManager::WCMRPortAudioDeviceManager -// -//! The constructuor, we initialize PA, and build the device list. -//! -//! \param *pTheClient : The manager's client object (which receives notifications). -//! \param interfaceType : The PortAudio interface type to use for this manager - acts as a filter. -//! \param useMultithreading : Whether to use multi-threading for audio processing. Default is true. -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRPortAudioDeviceManager::WCMRPortAudioDeviceManager (WCMRAudioDeviceManagerClient *pTheClient, - eAudioDeviceFilter eCurAudioDeviceFilter, bool useMultithreading, bool bNocopy) - : WCMRAudioDeviceManager (pTheClient, eCurAudioDeviceFilter) - , m_NoneDevice(0) - , m_UseMultithreading(useMultithreading) - , m_bNoCopyAudioBuffer(bNocopy) -{ - AUTO_FUNC_DEBUG; - std::cout << "API::PortAudioDeviceManager::PA Device manager constructor" << std::endl; - - //Always create the None device first... - m_NoneDevice = new WCMRNativeAudioNoneDevice(this); - - WTErr err = generateDeviceListImpl(); - - if (eNoErr != err) - throw err; - - timeBeginPeriod (1); -} - - -//********************************************************************************************** -// WCMRPortAudioDeviceManager::~WCMRPortAudioDeviceManager -// -//! It clears the device list, releasing each of the device. -//! -//! \param none -//! -//! \return Nothing. -//! -//********************************************************************************************** -WCMRPortAudioDeviceManager::~WCMRPortAudioDeviceManager() -{ - AUTO_FUNC_DEBUG; - - std::cout << "API::Destroying PortAudioDeviceManager " << std::endl; - - try - { - delete m_NoneDevice; - } - catch (...) - { - //destructors should absorb exceptions, no harm in logging though!! - DEBUG_MSG ("Exception during destructor"); - } - - timeEndPeriod (1); -} - - -WCMRAudioDevice* WCMRPortAudioDeviceManager::initNewCurrentDeviceImpl(const std::string & deviceName) -{ - destroyCurrentDeviceImpl(); - - std::cout << "API::PortAudioDeviceManager::initNewCurrentDevice " << deviceName << std::endl; - if (deviceName == m_NoneDevice->DeviceName() ) - { - m_CurrentDevice = m_NoneDevice; - return m_CurrentDevice; - } - - DeviceInfo devInfo; - WTErr err = GetDeviceInfoByName(deviceName, devInfo); - - if (eNoErr == err) - { - try - { - std::cout << "API::PortAudioDeviceManager::Creating PA device: " << devInfo.m_DeviceId << ", Device Name: " << devInfo.m_DeviceName << std::endl; - TRACE_MSG ("API::PortAudioDeviceManager::Creating PA device: " << devInfo.m_DeviceId << ", Device Name: " << devInfo.m_DeviceName); - - m_CurrentDevice = new WCMRPortAudioDevice (this, devInfo.m_DeviceId, m_UseMultithreading, m_bNoCopyAudioBuffer); - } - catch (...) - { - std::cout << "Unabled to create PA Device: " << devInfo.m_DeviceId << std::endl; - DEBUG_MSG ("Unabled to create PA Device: " << devInfo.m_DeviceId); - } - } - - return m_CurrentDevice; -} - - -void WCMRPortAudioDeviceManager::destroyCurrentDeviceImpl() -{ - if (m_CurrentDevice != m_NoneDevice) - delete m_CurrentDevice; - - m_CurrentDevice = 0; -} - - -WTErr WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceId, std::vector& sampleRates) -{ - WTErr retVal = eNoErr; - - sampleRates.clear(); - const PaDeviceInfo *pPaDeviceInfo = Pa_GetDeviceInfo(deviceId); - - //now find supported sample rates - //following parameters are needed for sample rates validation - PaStreamParameters inputParameters, outputParameters; - PaStreamParameters *pInS = NULL, *pOutS = NULL; - - inputParameters.device = deviceId; - inputParameters.channelCount = std::min(2, pPaDeviceInfo->maxInputChannels); - inputParameters.sampleFormat = paFloat32 | paNonInterleaved; - inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ - inputParameters.hostApiSpecificStreamInfo = 0; - - if (inputParameters.channelCount) - pInS = &inputParameters; - - outputParameters.device = deviceId; - outputParameters.channelCount = std::min(2, pPaDeviceInfo->maxOutputChannels); - outputParameters.sampleFormat = paFloat32; - outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ - outputParameters.hostApiSpecificStreamInfo = 0; - - if (outputParameters.channelCount) - pOutS = &outputParameters; - - for(int sr=0; gAllSampleRates[sr] > 0; sr++) - { - if( paFormatIsSupported == Pa_IsFormatSupported(pInS, pOutS, gAllSampleRates[sr]) ) - { - sampleRates.push_back ((int)gAllSampleRates[sr]); - } - } - - return retVal; -} - - -WTErr WCMRPortAudioDeviceManager::getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector& buffers) -{ - WTErr retVal = eNoErr; - - buffers.clear(); - - //make PA request to get actual device buffer sizes - long minSize, maxSize, preferredSize, granularity; - - PaError paErr = PaAsio_GetAvailableBufferSizes(deviceId, &minSize, &maxSize, &preferredSize, &granularity); - - //for Windows ASIO devices we always use prefferes buffer size ONLY - if (paNoError == paErr ) - { - buffers.push_back(preferredSize); - } - else - { - retVal = eAsioFailed; - std::cout << "API::PortAudioDeviceManager::GetBufferSizes: error: " << Pa_GetErrorText (paErr) << " getting buffer sizes for device: "<< deviceId << std::endl; - } - - return retVal; -} - - -WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl() -{ - std::cout << "API::PortAudioDeviceManager::Generating device list" << std::endl; - - WTErr retVal = eNoErr; - - //Initialize PortAudio and ASIO first - PaError paErr = Pa_Initialize(); - - if (paErr != paNoError) - { - //ToDo: throw an exception here! - retVal = eSomeThingNotInitailzed; - return retVal; - } - - // lock DeviceInfoVec firts - wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex); - - if (m_NoneDevice) - { - DeviceInfo *pDevInfo = new DeviceInfo(NONE_DEVICE_ID, m_NoneDevice->DeviceName() ); - pDevInfo->m_AvailableSampleRates = m_NoneDevice->SamplingRates(); - m_DeviceInfoVec.push_back(pDevInfo); - } - - //Get device count... - int numDevices = Pa_GetDeviceCount(); - - //for each device, - for (int thisDeviceID = 0; thisDeviceID < numDevices; thisDeviceID++) - { - //if it's of the required type... - const PaDeviceInfo *pPaDeviceInfo = Pa_GetDeviceInfo(thisDeviceID); - - if (Pa_GetHostApiInfo(pPaDeviceInfo->hostApi)->type == paASIO) - { - //build a device object... - try - { - std::cout << "API::PortAudioDeviceManager::DeviceID: " << thisDeviceID << ", Device Name: " << pPaDeviceInfo->name << std::endl; - TRACE_MSG ("PA DeviceID: " << thisDeviceID << ", Device Name: " << pPaDeviceInfo->name); - - DeviceInfo *pDevInfo = new DeviceInfo(thisDeviceID, pPaDeviceInfo->name); - if (pDevInfo) - { - //Get available sample rates - std::vector availableSampleRates; - WTErr wErr = WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(thisDeviceID, availableSampleRates); - - if (wErr != eNoErr) - { - DEBUG_MSG ("Failed to get device available sample rates. Device ID: " << m_DeviceID); - delete pDevInfo; - continue; //proceed to the next device - } - - pDevInfo->m_AvailableSampleRates = availableSampleRates; - pDevInfo->m_MaxInputChannels = pPaDeviceInfo->maxInputChannels; - pDevInfo->m_MaxOutputChannels = pPaDeviceInfo->maxOutputChannels; - - //Get available buffer sizes - std::vector availableBuffers; - wErr = getDeviceAvailableBufferSizes(thisDeviceID, availableBuffers); - - if (wErr != eNoErr) - { - DEBUG_MSG ("Failed to get device available buffer sizes. Device ID: " << m_DeviceID); - delete pDevInfo; - continue; //proceed to the next device - } - - pDevInfo->m_AvailableBufferSizes = availableBuffers; - - //Now check if this device is acceptable according to current input/output settings - bool bRejectDevice = false; - switch(m_eAudioDeviceFilter) - { - case eInputOnlyDevices: - if (pDevInfo->m_MaxInputChannels != 0) - { - m_DeviceInfoVec.push_back(pDevInfo); - } - else - { - // Delete unnecesarry device - bRejectDevice = true; - } - break; - case eOutputOnlyDevices: - if (pDevInfo->m_MaxOutputChannels != 0) - { - m_DeviceInfoVec.push_back(pDevInfo); - } - else - { - // Delete unnecesarry device - bRejectDevice = true; - } - break; - case eFullDuplexDevices: - if (pDevInfo->m_MaxInputChannels != 0 && pDevInfo->m_MaxOutputChannels != 0) - { - m_DeviceInfoVec.push_back(pDevInfo); - } - else - { - // Delete unnecesarry device - bRejectDevice = true; - } - break; - case eAllDevices: - default: - m_DeviceInfoVec.push_back(pDevInfo); - break; - } - - if(bRejectDevice) - { - TRACE_MSG ("API::PortAudioDeviceManager::Device " << pDevInfo->m_DeviceName << "Rejected. \ - In Channels = " << pDevInfo->m_MaxInputChannels << "Out Channels = " <m_MaxOutputChannels ); - delete pDevInfo; - } - } - } - catch (...) - { - std::cout << "API::PortAudioDeviceManager::Unabled to create PA Device: " << std::endl; - DEBUG_MSG ("Unabled to create PA Device: " << thisDeviceID); - } - } - } - - //If no devices were found, that's not a good thing! - if (m_DeviceInfoVec.empty() ) - { - std::cout << "API::PortAudioDeviceManager::No matching PortAudio devices were found, total PA devices = " << numDevices << std::endl; - DEBUG_MSG ("No matching PortAudio devices were found, total PA devices = " << numDevices); - } - - //we don't need PA initialized right now - Pa_Terminate(); - - return retVal; -} - - -WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & deviceName, std::vector& sampleRates) const -{ - sampleRates.clear (); - - WTErr retVal = eNoErr; - - if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() ) - { - sampleRates=m_CurrentDevice->SamplingRates(); - return retVal; - } - - DeviceInfo devInfo; - retVal = GetDeviceInfoByName(deviceName, devInfo); - - if (eNoErr == retVal) - { - sampleRates=devInfo.m_AvailableSampleRates; - } - else - { - std::cout << "API::PortAudioDeviceManager::GetSampleRates: Device not found: "<< deviceName << std::endl; - } - - return retVal; -} - - -WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & deviceName, std::vector& buffers) const -{ - WTErr retVal = eNoErr; - - buffers.clear(); - - //first check if the request has been made for None device - if (deviceName == m_NoneDevice->DeviceName() ) - { - buffers=m_NoneDevice->BufferSizes(); - return retVal; - } - - if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() ) - { - buffers=m_CurrentDevice->BufferSizes(); - return retVal; - } - - DeviceInfo devInfo; - retVal = GetDeviceInfoByName(deviceName, devInfo); - - if (eNoErr == retVal) - { - std::cout << "API::PortAudioDeviceManager::GetBufferSizes: got buffer :"<< devInfo.m_AvailableBufferSizes.front() << std::endl; - buffers = devInfo.m_AvailableBufferSizes; - } - else - { - std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl; - } - - return retVal; -} diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h deleted file mode 100644 index c028d09511..0000000000 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -//---------------------------------------------------------------------------------- -// -// -//! \file WCMRPortAudioDeviceManager.h -//! -//! WCMRPortAudioDeviceManager and related class declarations -//! -//---------------------------------------------------------------------------------*/ -#ifndef __WCMRPortAudioDeviceManager_h_ - #define __WCMRPortAudioDeviceManager_h_ - -#include "WCMRAudioDeviceManager.h" -#include "WCMRNativeAudio.h" -#include "portaudio.h" - -//forward decl. -class WCMRPortAudioDeviceManager; - -//! Manages a port audio device, providing information -//! about the device, and managing audio callbacks. -class WCMRPortAudioDevice : public WCMRNativeAudioDevice -{ -public: - - WCMRPortAudioDevice (WCMRPortAudioDeviceManager *pManager, unsigned int deviceID, bool useMultiThreading = true, bool bNoCopy = false);///& buffers) const; - virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector& sampleRates) const; - - bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing. - bool m_bNoCopyAudioBuffer; - -private: - // helper functions for this class only - WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector& sampleRates); - WTErr getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector& buffers); - - WCMRAudioDevice* m_NoneDevice; -}; - -#endif //#ifndef __WCMRPortAudioDeviceManager_h_ diff --git a/libs/backends/wavesaudio/wavesapi/refmanager/WCRefManager.cpp b/libs/backends/wavesaudio/wavesapi/refmanager/WCRefManager.cpp deleted file mode 100644 index 8353a758c8..0000000000 --- a/libs/backends/wavesaudio/wavesapi/refmanager/WCRefManager.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "WCRefManager.h" - -/// Construcotr. -WCRefManager::WCRefManager() -{ - m_RefCount = 1; -} - -/// Destructor. -WCRefManager::~WCRefManager() -{ -} - -/// Adds a reference to class. -void WCRefManager::AddRef() -{ - m_RefCount++; -} - -/// Decrements reference count and deletes the object if reference count becomes zero. -void WCRefManager::Release() -{ - m_RefCount--; - if( m_RefCount <= 0 ) - delete this; -} \ No newline at end of file diff --git a/libs/backends/wavesaudio/wavesapi/refmanager/WCRefManager.h b/libs/backends/wavesaudio/wavesapi/refmanager/WCRefManager.h deleted file mode 100644 index 2e56dcd99d..0000000000 --- a/libs/backends/wavesaudio/wavesapi/refmanager/WCRefManager.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (C) 2014 Waves Audio Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef WCREFMANAGER_H -#define WCREFMANAGER_H - - -#define SAFE_RELEASE(p) if (p) {p->Release(); p = NULL;} - - -//In order to use this interface, derive the Interface class -//from WCRefManager_Interface and derive the implementation class -//from WCRefManager_Impl. Further, in the implementation class -//declaration, place the macro WCREFMANAGER_IMPL. -class WCRefManager_Interface -{ -public: - /// Constructor. - WCRefManager_Interface() {}; - /// Destructor. - virtual ~WCRefManager_Interface() {}; - /// Adds a reference to class. - virtual void AddRef() = 0; - /// Decrements reference count and deletes the object if reference count becomes zero. - virtual void Release() = 0; -}; - -///! See details at WCRefManager_Interface for how to use this. -class WCRefManager_Impl -{ -public: - WCRefManager_Impl () : m_RefCount(1) {} - virtual ~WCRefManager_Impl() {} -protected: - /// Variable to store reference count. - unsigned int m_RefCount; - -/// Helper to put implementation in an interface derived class, don't forget to -/// derive the impl from WCRefManager_Impl -#define WCREFMAN_IMPL \ - public: \ - virtual void AddRef() {m_RefCount++;} \ - virtual void Release() {m_RefCount--; if (m_RefCount<=0) delete this;} - -}; - - -class WCRefManager -{ -public: - /// Construcotr. - WCRefManager(); - /// Destructor. - virtual ~WCRefManager(); - /// Adds a reference to class. - void AddRef(); - /// Decrements reference count and deletes the object if reference count becomes zero. - void Release(); - -private: - /// Variable to store reference count. - unsigned int m_RefCount; -}; - -#endif // WCREFMANAGER_H diff --git a/libs/backends/wavesaudio/wscript b/libs/backends/wavesaudio/wscript deleted file mode 100644 index 89fe65b7a0..0000000000 --- a/libs/backends/wavesaudio/wscript +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python -from waflib.extras import autowaf as autowaf -import os -import sys -import re - -I18N_PACKAGE = 'wavesaudio-backend' - -# Mandatory variables -top = '.' -out = 'build' - -def options(opt): - autowaf.set_options(opt) - -def configure(conf): - if conf.options.dist_target == 'mingw': - autowaf.check_pkg(conf, 'portaudio-2.0', uselib_store='PORTAUDIO', - atleast_version='19') - autowaf.configure(conf) - -def build(bld): - - if bld.env['build_target'] == 'mingw': - obj = bld(features = 'cxx cxxshlib') - else: - obj = bld(features = 'c cxx cxxshlib') - - if sys.platform == 'darwin': - if bld.env['build_target'] not in [ 'lion' ]: - obj.framework = 'CoreMidi' - else: - obj.framework = 'CoreMIDI' - - obj.source = [ - 'waves_audiobackend.cc', - 'waves_audiobackend.latency.cc', - 'waves_audiobackend.midi.cc', - 'waves_audiobackend.port_engine.cc', - 'waves_dataport.cc', - 'waves_audioport.cc', - 'waves_midiport.cc', - 'waves_midi_device_manager.cc', - 'waves_midi_device.cc', - 'waves_midi_event.cc', - 'waves_midi_buffer.cc', - 'wavesapi/refmanager/WCRefManager.cpp', - 'wavesapi/devicemanager/WCMRAudioDeviceManager.cpp', - 'wavesapi/devicemanager/WCMRNativeAudio.cpp', - 'wavesapi/Threads/WCThreadSafe.cpp', - 'portmidi/src/pm_common/pmutil.c', - 'portmidi/src/pm_common/portmidi.c' - ] - - if bld.env['build_target'] == 'mingw': - platform_dependent = [ - 'wavesapi/MiscUtils/UMicroseconds.cpp', - 'wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp', - 'portmidi/src/pm_win/pmwin.c', - 'portmidi/src/pm_win/pmwinmm.c', - 'portmidi/src/porttime/ptwinmm.c' - ] - else: - platform_dependent = [ - 'wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp', - 'portmidi/src/pm_mac/pmmac.c', - 'portmidi/src/pm_mac/pmmacosxcm.c', - 'portmidi/src/pm_mac/finddefault.c', - 'portmidi/src/pm_mac/readbinaryplist.c', - 'portmidi/src/porttime/ptmacosx_mach.c' - ] - - obj.source.extend(platform_dependent) - - obj.includes = ['.', - 'wavesapi', - 'wavesapi/refmanager', - 'wavesapi/WavesPublicAPI', - 'wavesapi/devicemanager', - 'wavesapi/MiscUtils', - 'wavesapi/Threads', - 'portmidi', - 'portmidi/src/pm_common' - ] - - obj.name = 'waves_audiobackend' - obj.target = 'waves_audiobackend' - obj.use = 'libardour libpbd' - if bld.env['build_target'] == 'mingw': - obj.uselib = ['PORTAUDIO'] - obj.cxxflags = [ bld.env['compiler_flags_dict']['pic'] ] - obj.cflags = [ bld.env['compiler_flags_dict']['pic'], bld.env['compiler_flags_dict']['c-anonymous-union'] ] - else: - obj.cflags = [ bld.env['compiler_flags_dict']['c-anonymous-union'] ] - obj.install_path = os.path.join(bld.env['LIBDIR'], 'backends') - - if bld.env['build_target']== 'mingw': - obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"', - 'ARDOURBACKEND_DLL_EXPORTS' - ] - else: - obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"', - 'ARDOURBACKEND_DLL_EXPORTS' - ] diff --git a/wscript b/wscript index db1a3ddbb5..d2d5f38932 100644 --- a/wscript +++ b/wscript @@ -645,7 +645,7 @@ def options(opt): opt.add_option('--arch', type='string', action='store', dest='arch', help='Architecture-specific compiler FLAGS') opt.add_option('--with-backends', type='string', action='store', default='jack', dest='with_backends', - help='Specify which backend modules are to be included(jack,alsa,wavesaudio,dummy,coreaudio)') + help='Specify which backend modules are to be included(jack,alsa,dummy,coreaudio)') opt.add_option('--backtrace', action='store_true', default=False, dest='backtrace', help='Compile with -rdynamic -- allow obtaining backtraces from within Ardour') opt.add_option('--no-carbon', action='store_true', default=False, dest='nocarbon', @@ -1095,21 +1095,12 @@ int main () { return 0; } conf.env['BUILD_JACKBACKEND'] = any('jack' in b for b in backends) conf.env['BUILD_ALSABACKEND'] = any('alsa' in b for b in backends) conf.env['BUILD_DUMMYBACKEND'] = any('dummy' in b for b in backends) - conf.env['BUILD_WAVESBACKEND'] = any('wavesaudio' in b for b in backends) conf.env['BUILD_CORECRAPPITA'] = any('coreaudio' in b for b in backends) - if conf.env['BUILD_CORECRAPPITA'] and conf.env['BUILD_WAVESBACKEND']: - print("Coreaudio + Waves Backend are mutually exclusive") - sys.exit(1) - if sys.platform != 'darwin' and conf.env['BUILD_CORECRAPPITA']: print("Coreaudio backend is only available for OSX") sys.exit(1) - if re.search ("linux", sys.platform) != None and Options.options.dist_target != 'mingw' and conf.env['BUILD_WAVESBACKEND']: - print("Waves Backend is not for Linux") - sys.exit(1) - if re.search ("linux", sys.platform) == None and conf.env['BUILD_ALSABACKEND']: print("ALSA Backend is only available on Linux") sys.exit(1) @@ -1187,7 +1178,6 @@ const char* const ardour_config_info = "\\n\\ write_config_text('Unit tests', conf.env['BUILD_TESTS']) write_config_text('Mac i386 Architecture', opts.generic) write_config_text('Mac ppc Architecture', opts.ppc) - write_config_text('Waves Backend', conf.env['BUILD_WAVESBACKEND']) write_config_text('Windows VST support', opts.windows_vst) write_config_text('Wiimote support', conf.is_defined('BUILD_WIIMOTE')) write_config_text('Windows key', opts.windows_key) -- cgit v1.2.3