Browse Source

tags/2021-05-28
jules 18 years ago
parent
commit
a9e726681c
63 changed files with 13943 additions and 5483 deletions
  1. +24
    -0
      build/linux/JUCE.make
  2. +4
    -0
      build/linux/juce_premake.lua
  3. +64
    -56
      build/macosx/Juce.xcodeproj/project.pbxproj
  4. +15
    -6
      build/macosx/juce.xcconfig
  5. +110
    -6
      build/win32/vc8/JUCE.vcproj
  6. +7
    -0
      docs/JUCE changelist.txt
  7. +0
    -72
      extras/audio plugin host/build/win32/PluginHost.vcproj
  8. +1
    -0
      extras/audio plugin host/src/HostStartup.cpp
  9. +173
    -563
      extras/audio plugin host/src/host/FilterGraph.cpp
  10. +26
    -22
      extras/audio plugin host/src/host/FilterGraph.h
  11. +147
    -45
      extras/audio plugin host/src/host/GraphEditorPanel.cpp
  12. +29
    -3
      extras/audio plugin host/src/host/GraphEditorPanel.h
  13. +9
    -306
      extras/audio plugin host/src/host/InternalFilters.cpp
  14. +1
    -1
      extras/audio plugin host/src/host/InternalFilters.h
  15. +8
    -8
      extras/audio plugin host/src/host/MainHostWindow.cpp
  16. +0
    -1
      extras/audio plugin host/src/host/MainHostWindow.h
  17. +1281
    -1269
      extras/audio plugin host/src/plugins/formats/juce_AudioUnitPluginFormat.cpp
  18. +3008
    -2998
      extras/audio plugin host/src/plugins/formats/juce_VSTPluginFormat.cpp
  19. +24
    -0
      extras/audio plugin host/src/plugins/juce_AudioPluginFormat.cpp
  20. +13
    -0
      extras/audio plugin host/src/plugins/juce_AudioPluginFormat.h
  21. +10
    -1
      extras/audio plugin host/src/plugins/juce_KnownPluginList.cpp
  22. +7
    -0
      extras/audio plugin host/src/plugins/juce_KnownPluginList.h
  23. +4
    -37
      extras/audio plugin host/src/plugins/juce_PluginDescription.cpp
  24. +12
    -11
      extras/audio plugin host/src/plugins/juce_PluginDescription.h
  25. +10
    -0
      extras/audio plugins/demo/src/DemoJuceFilter.cpp
  26. +3
    -0
      extras/audio plugins/demo/src/DemoJuceFilter.h
  27. +3
    -4
      extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.cpp
  28. +1
    -1
      extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.h
  29. +6
    -6
      extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj
  30. +58
    -56
      extras/juce demo/src/BinaryData.cpp
  31. +1
    -1
      extras/juce demo/src/BinaryData.h
  32. +4
    -4
      extras/juce demo/src/binarydata/AudioDemo.cpp
  33. +2
    -1
      extras/juce demo/src/binarydata/DragAndDropDemo.cpp
  34. +4
    -4
      extras/juce demo/src/demos/AudioDemo.cpp
  35. +2
    -1
      extras/juce demo/src/demos/DragAndDropDemo.cpp
  36. +1
    -0
      juce.h
  37. +10
    -0
      juce_Config.h
  38. +39
    -0
      src/juce_app_includes.h
  39. +1284
    -0
      src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.cpp
  40. +67
    -0
      src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.h
  41. +71
    -0
      src/juce_appframework/audio/plugins/formats/juce_DirectXPluginFormat.h
  42. +71
    -0
      src/juce_appframework/audio/plugins/formats/juce_LADSPAPluginFormat.h
  43. +3017
    -0
      src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp
  44. +68
    -0
      src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h
  45. +49
    -0
      src/juce_appframework/audio/plugins/juce_AudioPluginFormat.cpp
  46. +107
    -0
      src/juce_appframework/audio/plugins/juce_AudioPluginFormat.h
  47. +138
    -0
      src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.cpp
  48. +107
    -0
      src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.h
  49. +51
    -0
      src/juce_appframework/audio/plugins/juce_AudioPluginInstance.cpp
  50. +76
    -0
      src/juce_appframework/audio/plugins/juce_AudioPluginInstance.h
  51. +431
    -0
      src/juce_appframework/audio/plugins/juce_KnownPluginList.cpp
  52. +176
    -0
      src/juce_appframework/audio/plugins/juce_KnownPluginList.h
  53. +139
    -0
      src/juce_appframework/audio/plugins/juce_PluginDescription.cpp
  54. +140
    -0
      src/juce_appframework/audio/plugins/juce_PluginDescription.h
  55. +164
    -0
      src/juce_appframework/audio/plugins/juce_PluginDirectoryScanner.cpp
  56. +129
    -0
      src/juce_appframework/audio/plugins/juce_PluginDirectoryScanner.h
  57. +308
    -0
      src/juce_appframework/audio/plugins/juce_PluginListComponent.cpp
  58. +107
    -0
      src/juce_appframework/audio/plugins/juce_PluginListComponent.h
  59. +14
    -0
      src/juce_appframework/audio/processors/juce_AudioProcessor.h
  60. +1340
    -0
      src/juce_appframework/audio/processors/juce_AudioProcessorGraph.cpp
  61. +440
    -0
      src/juce_appframework/audio/processors/juce_AudioProcessorGraph.h
  62. +207
    -0
      src/juce_appframework/audio/processors/juce_AudioProcessorPlayer.cpp
  63. +121
    -0
      src/juce_appframework/audio/processors/juce_AudioProcessorPlayer.h

+ 24
- 0
build/linux/JUCE.make View File

@@ -109,6 +109,8 @@ OBJECTS := \
$(OBJDIR)/juce_MidiMessageSequence.o \
$(OBJDIR)/juce_AudioProcessor.o \
$(OBJDIR)/juce_AudioProcessorEditor.o \
$(OBJDIR)/juce_AudioProcessorGraph.o \
$(OBJDIR)/juce_AudioProcessorPlayer.o \
$(OBJDIR)/juce_GenericAudioProcessorEditor.o \
$(OBJDIR)/juce_AiffAudioFormat.o \
$(OBJDIR)/juce_AudioCDReader.o \
@@ -120,6 +122,8 @@ OBJECTS := \
$(OBJDIR)/juce_WavAudioFormat.o \
$(OBJDIR)/bitbuffer.o \
$(OBJDIR)/bitmath.o \
$(OBJDIR)/bitreader.o \
$(OBJDIR)/bitwriter.o \
$(OBJDIR)/cpu.o \
$(OBJDIR)/crc.o \
$(OBJDIR)/fixed.o \
@@ -801,6 +805,16 @@ $(OBJDIR)/juce_AudioProcessorEditor.o: ../../src/juce_appframework/audio/process
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/juce_AudioProcessorGraph.o: ../../src/juce_appframework/audio/processors/juce_AudioProcessorGraph.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/juce_AudioProcessorPlayer.o: ../../src/juce_appframework/audio/processors/juce_AudioProcessorPlayer.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/juce_GenericAudioProcessorEditor.o: ../../src/juce_appframework/audio/processors/juce_GenericAudioProcessorEditor.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@@ -856,6 +870,16 @@ $(OBJDIR)/bitmath.o: ../../src/juce_appframework/audio/audio_file_formats/flac/l
@echo $(notdir $<)
@$(CC) $(CFLAGS) -o $@ -c $<

$(OBJDIR)/bitreader.o: ../../src/juce_appframework/audio/audio_file_formats/flac/libFLAC/bitreader.c
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CC) $(CFLAGS) -o $@ -c $<

$(OBJDIR)/bitwriter.o: ../../src/juce_appframework/audio/audio_file_formats/flac/libFLAC/bitwriter.c
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CC) $(CFLAGS) -o $@ -c $<

$(OBJDIR)/cpu.o: ../../src/juce_appframework/audio/audio_file_formats/flac/libFLAC/cpu.c
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)


+ 4
- 0
build/linux/juce_premake.lua View File

@@ -68,6 +68,10 @@ package.files = { matchfiles (
"../../src/juce_appframework/audio/midi/*.h",
"../../src/juce_appframework/audio/processors/*.cpp",
"../../src/juce_appframework/audio/processors/*.h",
"../../src/juce_appframework/audio/plugins/*.cpp",
"../../src/juce_appframework/audio/plugins/*.h",
"../../src/juce_appframework/audio/plugins/formats/*.cpp",
"../../src/juce_appframework/audio/plugins/formats/*.h",
"../../src/juce_appframework/audio/audio_file_formats/*.cpp",
"../../src/juce_appframework/audio/audio_file_formats/*.h",
"../../src/juce_appframework/audio/audio_file_formats/flac/libFLAC/*.c",


+ 64
- 56
build/macosx/Juce.xcodeproj/project.pbxproj View File

@@ -20,6 +20,22 @@
84099CA10AE52BD000B2A05D /* juce_Synthesiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84099C9D0AE52BD000B2A05D /* juce_Synthesiser.cpp */; };
84099CA20AE52BD000B2A05D /* juce_Synthesiser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84099C9E0AE52BD000B2A05D /* juce_Synthesiser.h */; };
840F80BC092B399D005E7B4E /* juce.h in Headers */ = {isa = PBXBuildFile; fileRef = 840F80BB092B399D005E7B4E /* juce.h */; };
8416EB750D1999620094A433 /* bitbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB650D1999610094A433 /* bitbuffer.c */; };
8416EB760D1999620094A433 /* bitmath.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB660D1999610094A433 /* bitmath.c */; };
8416EB770D1999620094A433 /* bitreader.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB670D1999610094A433 /* bitreader.c */; };
8416EB780D1999620094A433 /* bitwriter.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB680D1999610094A433 /* bitwriter.c */; };
8416EB790D1999620094A433 /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB690D1999610094A433 /* cpu.c */; };
8416EB7A0D1999620094A433 /* crc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB6A0D1999610094A433 /* crc.c */; };
8416EB7B0D1999620094A433 /* fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB6B0D1999610094A433 /* fixed.c */; };
8416EB7C0D1999620094A433 /* float.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB6C0D1999610094A433 /* float.c */; };
8416EB7D0D1999620094A433 /* format.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB6D0D1999610094A433 /* format.c */; };
8416EB7E0D1999620094A433 /* lpc_flac.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB6E0D1999610094A433 /* lpc_flac.c */; };
8416EB7F0D1999620094A433 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB6F0D1999620094A433 /* md5.c */; };
8416EB800D1999620094A433 /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB700D1999620094A433 /* memory.c */; };
8416EB810D1999620094A433 /* stream_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB710D1999620094A433 /* stream_decoder.c */; };
8416EB820D1999620094A433 /* stream_encoder_framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB720D1999620094A433 /* stream_encoder_framing.c */; };
8416EB830D1999620094A433 /* stream_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB730D1999620094A433 /* stream_encoder.c */; };
8416EB840D1999620094A433 /* window_flac.c in Sources */ = {isa = PBXBuildFile; fileRef = 8416EB740D1999620094A433 /* window_flac.c */; };
8417EE530A6E7A280058E04E /* juce_TableHeaderComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8417EE4F0A6E7A270058E04E /* juce_TableHeaderComponent.cpp */; };
8417EE540A6E7A280058E04E /* juce_TableHeaderComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 8417EE500A6E7A270058E04E /* juce_TableHeaderComponent.h */; };
8417EE550A6E7A280058E04E /* juce_TableListBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8417EE510A6E7A280058E04E /* juce_TableListBox.cpp */; };
@@ -571,20 +587,6 @@
84F593AE09855679008153BA /* juce_DocumentWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F593AC09855679008153BA /* juce_DocumentWindow.cpp */; };
84F593AF09855679008153BA /* juce_DocumentWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F593AD09855679008153BA /* juce_DocumentWindow.h */; };
84F593B109855693008153BA /* juce_LassoComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F593B009855693008153BA /* juce_LassoComponent.h */; };
84F690EF0B3444E500ABAE1C /* bitbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690E10B3444E500ABAE1C /* bitbuffer.c */; };
84F690F00B3444E500ABAE1C /* bitmath.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690E20B3444E500ABAE1C /* bitmath.c */; };
84F690F10B3444E500ABAE1C /* cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690E30B3444E500ABAE1C /* cpu.c */; };
84F690F20B3444E500ABAE1C /* crc.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690E40B3444E500ABAE1C /* crc.c */; };
84F690F30B3444E500ABAE1C /* fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690E50B3444E500ABAE1C /* fixed.c */; };
84F690F40B3444E500ABAE1C /* float.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690E60B3444E500ABAE1C /* float.c */; };
84F690F50B3444E500ABAE1C /* format.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690E70B3444E500ABAE1C /* format.c */; };
84F690F60B3444E500ABAE1C /* lpc_flac.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690E80B3444E500ABAE1C /* lpc_flac.c */; };
84F690F70B3444E500ABAE1C /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690E90B3444E500ABAE1C /* md5.c */; };
84F690F80B3444E500ABAE1C /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690EA0B3444E500ABAE1C /* memory.c */; };
84F690F90B3444E500ABAE1C /* stream_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690EB0B3444E500ABAE1C /* stream_decoder.c */; };
84F690FA0B3444E500ABAE1C /* stream_encoder_framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690EC0B3444E500ABAE1C /* stream_encoder_framing.c */; };
84F690FB0B3444E500ABAE1C /* stream_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690ED0B3444E500ABAE1C /* stream_encoder.c */; };
84F690FC0B3444E500ABAE1C /* window_flac.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690EE0B3444E500ABAE1C /* window_flac.c */; };
84F690FF0B3444F800ABAE1C /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690FD0B3444F800ABAE1C /* bitwise.c */; };
84F691000B3444F800ABAE1C /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690FE0B3444F800ABAE1C /* framing.c */; };
84F691170B34453600ABAE1C /* analysis.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F691010B34453600ABAE1C /* analysis.c */; };
@@ -672,6 +674,22 @@
84099C9D0AE52BD000B2A05D /* juce_Synthesiser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_Synthesiser.cpp; sourceTree = "<group>"; };
84099C9E0AE52BD000B2A05D /* juce_Synthesiser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_Synthesiser.h; sourceTree = "<group>"; };
840F80BB092B399D005E7B4E /* juce.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce.h; path = ../../juce.h; sourceTree = SOURCE_ROOT; };
8416EB650D1999610094A433 /* bitbuffer.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bitbuffer.c; path = flac/libFLAC/bitbuffer.c; sourceTree = "<group>"; };
8416EB660D1999610094A433 /* bitmath.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bitmath.c; path = flac/libFLAC/bitmath.c; sourceTree = "<group>"; };
8416EB670D1999610094A433 /* bitreader.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bitreader.c; path = flac/libFLAC/bitreader.c; sourceTree = "<group>"; };
8416EB680D1999610094A433 /* bitwriter.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bitwriter.c; path = flac/libFLAC/bitwriter.c; sourceTree = "<group>"; };
8416EB690D1999610094A433 /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpu.c; path = flac/libFLAC/cpu.c; sourceTree = "<group>"; };
8416EB6A0D1999610094A433 /* crc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = crc.c; path = flac/libFLAC/crc.c; sourceTree = "<group>"; };
8416EB6B0D1999610094A433 /* fixed.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = fixed.c; path = flac/libFLAC/fixed.c; sourceTree = "<group>"; };
8416EB6C0D1999610094A433 /* float.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = float.c; path = flac/libFLAC/float.c; sourceTree = "<group>"; };
8416EB6D0D1999610094A433 /* format.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = format.c; path = flac/libFLAC/format.c; sourceTree = "<group>"; };
8416EB6E0D1999610094A433 /* lpc_flac.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lpc_flac.c; path = flac/libFLAC/lpc_flac.c; sourceTree = "<group>"; };
8416EB6F0D1999620094A433 /* md5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md5.c; path = flac/libFLAC/md5.c; sourceTree = "<group>"; };
8416EB700D1999620094A433 /* memory.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = memory.c; path = flac/libFLAC/memory.c; sourceTree = "<group>"; };
8416EB710D1999620094A433 /* stream_decoder.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stream_decoder.c; path = flac/libFLAC/stream_decoder.c; sourceTree = "<group>"; };
8416EB720D1999620094A433 /* stream_encoder_framing.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stream_encoder_framing.c; path = flac/libFLAC/stream_encoder_framing.c; sourceTree = "<group>"; };
8416EB730D1999620094A433 /* stream_encoder.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stream_encoder.c; path = flac/libFLAC/stream_encoder.c; sourceTree = "<group>"; };
8416EB740D1999620094A433 /* window_flac.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = window_flac.c; path = flac/libFLAC/window_flac.c; sourceTree = "<group>"; };
8417EE4F0A6E7A270058E04E /* juce_TableHeaderComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_TableHeaderComponent.cpp; sourceTree = "<group>"; };
8417EE500A6E7A270058E04E /* juce_TableHeaderComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_TableHeaderComponent.h; sourceTree = "<group>"; };
8417EE510A6E7A280058E04E /* juce_TableListBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_TableListBox.cpp; sourceTree = "<group>"; };
@@ -1226,20 +1244,6 @@
84F593AC09855679008153BA /* juce_DocumentWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_DocumentWindow.cpp; sourceTree = "<group>"; };
84F593AD09855679008153BA /* juce_DocumentWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_DocumentWindow.h; sourceTree = "<group>"; };
84F593B009855693008153BA /* juce_LassoComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_LassoComponent.h; sourceTree = "<group>"; };
84F690E10B3444E500ABAE1C /* bitbuffer.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bitbuffer.c; path = flac/libFLAC/bitbuffer.c; sourceTree = "<group>"; };
84F690E20B3444E500ABAE1C /* bitmath.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bitmath.c; path = flac/libFLAC/bitmath.c; sourceTree = "<group>"; };
84F690E30B3444E500ABAE1C /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpu.c; path = flac/libFLAC/cpu.c; sourceTree = "<group>"; };
84F690E40B3444E500ABAE1C /* crc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = crc.c; path = flac/libFLAC/crc.c; sourceTree = "<group>"; };
84F690E50B3444E500ABAE1C /* fixed.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = fixed.c; path = flac/libFLAC/fixed.c; sourceTree = "<group>"; };
84F690E60B3444E500ABAE1C /* float.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = float.c; path = flac/libFLAC/float.c; sourceTree = "<group>"; };
84F690E70B3444E500ABAE1C /* format.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = format.c; path = flac/libFLAC/format.c; sourceTree = "<group>"; };
84F690E80B3444E500ABAE1C /* lpc_flac.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lpc_flac.c; path = flac/libFLAC/lpc_flac.c; sourceTree = "<group>"; };
84F690E90B3444E500ABAE1C /* md5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md5.c; path = flac/libFLAC/md5.c; sourceTree = "<group>"; };
84F690EA0B3444E500ABAE1C /* memory.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = memory.c; path = flac/libFLAC/memory.c; sourceTree = "<group>"; };
84F690EB0B3444E500ABAE1C /* stream_decoder.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stream_decoder.c; path = flac/libFLAC/stream_decoder.c; sourceTree = "<group>"; };
84F690EC0B3444E500ABAE1C /* stream_encoder_framing.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stream_encoder_framing.c; path = flac/libFLAC/stream_encoder_framing.c; sourceTree = "<group>"; };
84F690ED0B3444E500ABAE1C /* stream_encoder.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stream_encoder.c; path = flac/libFLAC/stream_encoder.c; sourceTree = "<group>"; };
84F690EE0B3444E500ABAE1C /* window_flac.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = window_flac.c; path = flac/libFLAC/window_flac.c; sourceTree = "<group>"; };
84F690FD0B3444F800ABAE1C /* bitwise.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bitwise.c; path = oggvorbis/bitwise.c; sourceTree = "<group>"; };
84F690FE0B3444F800ABAE1C /* framing.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = framing.c; path = oggvorbis/framing.c; sourceTree = "<group>"; };
84F691010B34453600ABAE1C /* analysis.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = analysis.c; path = "oggvorbis/libvorbis-1.1.2/lib/analysis.c"; sourceTree = "<group>"; };
@@ -2364,20 +2368,22 @@
84F690DC0B3444A500ABAE1C /* flac */ = {
isa = PBXGroup;
children = (
84F690E10B3444E500ABAE1C /* bitbuffer.c */,
84F690E20B3444E500ABAE1C /* bitmath.c */,
84F690E30B3444E500ABAE1C /* cpu.c */,
84F690E40B3444E500ABAE1C /* crc.c */,
84F690E50B3444E500ABAE1C /* fixed.c */,
84F690E60B3444E500ABAE1C /* float.c */,
84F690E70B3444E500ABAE1C /* format.c */,
84F690E80B3444E500ABAE1C /* lpc_flac.c */,
84F690E90B3444E500ABAE1C /* md5.c */,
84F690EA0B3444E500ABAE1C /* memory.c */,
84F690EB0B3444E500ABAE1C /* stream_decoder.c */,
84F690EC0B3444E500ABAE1C /* stream_encoder_framing.c */,
84F690ED0B3444E500ABAE1C /* stream_encoder.c */,
84F690EE0B3444E500ABAE1C /* window_flac.c */,
8416EB650D1999610094A433 /* bitbuffer.c */,
8416EB660D1999610094A433 /* bitmath.c */,
8416EB670D1999610094A433 /* bitreader.c */,
8416EB680D1999610094A433 /* bitwriter.c */,
8416EB690D1999610094A433 /* cpu.c */,
8416EB6A0D1999610094A433 /* crc.c */,
8416EB6B0D1999610094A433 /* fixed.c */,
8416EB6C0D1999610094A433 /* float.c */,
8416EB6D0D1999610094A433 /* format.c */,
8416EB6E0D1999610094A433 /* lpc_flac.c */,
8416EB6F0D1999620094A433 /* md5.c */,
8416EB700D1999620094A433 /* memory.c */,
8416EB710D1999620094A433 /* stream_decoder.c */,
8416EB720D1999620094A433 /* stream_encoder_framing.c */,
8416EB730D1999620094A433 /* stream_encoder.c */,
8416EB740D1999620094A433 /* window_flac.c */,
);
name = flac;
sourceTree = "<group>";
@@ -3119,20 +3125,6 @@
841E06370AF8CE75005E6FCC /* juce_AudioSampleBuffer.cpp in Sources */,
841E06390AF8CE75005E6FCC /* juce_IIRFilter.cpp in Sources */,
84F525000B32A8D500597B73 /* juce_ApplicationProperties.cpp in Sources */,
84F690EF0B3444E500ABAE1C /* bitbuffer.c in Sources */,
84F690F00B3444E500ABAE1C /* bitmath.c in Sources */,
84F690F10B3444E500ABAE1C /* cpu.c in Sources */,
84F690F20B3444E500ABAE1C /* crc.c in Sources */,
84F690F30B3444E500ABAE1C /* fixed.c in Sources */,
84F690F40B3444E500ABAE1C /* float.c in Sources */,
84F690F50B3444E500ABAE1C /* format.c in Sources */,
84F690F60B3444E500ABAE1C /* lpc_flac.c in Sources */,
84F690F70B3444E500ABAE1C /* md5.c in Sources */,
84F690F80B3444E500ABAE1C /* memory.c in Sources */,
84F690F90B3444E500ABAE1C /* stream_decoder.c in Sources */,
84F690FA0B3444E500ABAE1C /* stream_encoder_framing.c in Sources */,
84F690FB0B3444E500ABAE1C /* stream_encoder.c in Sources */,
84F690FC0B3444E500ABAE1C /* window_flac.c in Sources */,
84F690FF0B3444F800ABAE1C /* bitwise.c in Sources */,
84F691000B3444F800ABAE1C /* framing.c in Sources */,
84F691170B34453600ABAE1C /* analysis.c in Sources */,
@@ -3166,6 +3158,22 @@
84BC4E2A0C8DD38C00FA249B /* juce_AudioProcessor.cpp in Sources */,
84BC4E2C0C8DD38C00FA249B /* juce_AudioProcessorEditor.cpp in Sources */,
84BC4E2F0C8DD38C00FA249B /* juce_GenericAudioProcessorEditor.cpp in Sources */,
8416EB750D1999620094A433 /* bitbuffer.c in Sources */,
8416EB760D1999620094A433 /* bitmath.c in Sources */,
8416EB770D1999620094A433 /* bitreader.c in Sources */,
8416EB780D1999620094A433 /* bitwriter.c in Sources */,
8416EB790D1999620094A433 /* cpu.c in Sources */,
8416EB7A0D1999620094A433 /* crc.c in Sources */,
8416EB7B0D1999620094A433 /* fixed.c in Sources */,
8416EB7C0D1999620094A433 /* float.c in Sources */,
8416EB7D0D1999620094A433 /* format.c in Sources */,
8416EB7E0D1999620094A433 /* lpc_flac.c in Sources */,
8416EB7F0D1999620094A433 /* md5.c in Sources */,
8416EB800D1999620094A433 /* memory.c in Sources */,
8416EB810D1999620094A433 /* stream_decoder.c in Sources */,
8416EB820D1999620094A433 /* stream_encoder_framing.c in Sources */,
8416EB830D1999620094A433 /* stream_encoder.c in Sources */,
8416EB840D1999620094A433 /* window_flac.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};


+ 15
- 6
build/macosx/juce.xcconfig View File

@@ -1,13 +1,22 @@
ARCHS = ppc i386

// For 10.2 compatibility, use these values:
// For 10.2 (and later) compatibility, use these values:
GCC_VERSION_ppc = 3.3
MACOSX_DEPLOYMENT_TARGET = 10.4
MACOSX_DEPLOYMENT_TARGET_ppc = 10.2
OTHER_LD_FLAGS_ppc = /Developer/SDKs/MacOSX10.2.8.sdk/usr/lib/gcc/darwin/3.3/libstdc++.a
SDKROOT_ppc = /Developer/SDKs/MacOSX10.2.8.sdk
OTHER_LD_FLAGS_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.2.8.sdk/usr/lib/gcc/darwin/3.3/libstdc++.a
SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.2.8.sdk

// For 10.3 compatibility, use these:
// For 10.3 (and later) compatibility, use these instead:
// MACOSX_DEPLOYMENT_TARGET = 10.4
// MACOSX_DEPLOYMENT_TARGET_ppc = 10.3
// SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk
// SDKROOT_ppc = /Developer/SDKs/MacOSX10.3.9.sdk
// SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk
// SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk

// For 10.4 (and later) compatibility, use these instead:
// MACOSX_DEPLOYMENT_TARGET = 10.4
// SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk

// For 10.5 (and later) compatibility, use these instead:
// MACOSX_DEPLOYMENT_TARGET = 10.5
// SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk

+ 110
- 6
build/win32/vc8/JUCE.vcproj View File

@@ -705,11 +705,15 @@
Name="flac"
>
<File
RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\bitbuffer.c"
RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\bitmath.c"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\bitmath.c"
RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\bitreader.c"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\bitwriter.c"
>
</File>
<File
@@ -732,10 +736,6 @@
RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\format.c"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\juce_FlacHeader.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\lpc_flac.c"
>
@@ -1189,10 +1189,26 @@
RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorEditor.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorGraph.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorGraph.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorListener.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorPlayer.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorPlayer.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_GenericAudioProcessorEditor.cpp"
>
@@ -1202,6 +1218,94 @@
>
</File>
</Filter>
<Filter
Name="plugins"
>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_AudioPluginFormat.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_AudioPluginFormat.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_AudioPluginFormatManager.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_AudioPluginFormatManager.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_AudioPluginInstance.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_AudioPluginInstance.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_KnownPluginList.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_KnownPluginList.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_PluginDescription.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_PluginDescription.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_PluginDirectoryScanner.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_PluginDirectoryScanner.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_PluginListComponent.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\juce_PluginListComponent.h"
>
</File>
<Filter
Name="formats"
>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\formats\juce_AudioUnitPluginFormat.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\formats\juce_AudioUnitPluginFormat.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\formats\juce_DirectXPluginFormat.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\formats\juce_LADSPAPluginFormat.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\formats\juce_VSTPluginFormat.cpp"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\audio\plugins\formats\juce_VSTPluginFormat.h"
>
</File>
</Filter>
</Filter>
</Filter>
<Filter
Name="events"


+ 7
- 0
docs/JUCE changelist.txt View File

@@ -6,12 +6,19 @@
==============================================================================
Changelist for version 1.46

- new class: AudioProcessorGraph: This allows AudioProcessors to be efficiently wired together and run as a graph. I've converted the plugin host demo to now use this instead of its own graph rendering code.
- new class: AudioProcessorPlayer: This allows an audio i/o device to stream through an AudioProcessor (or an AudioProcessorGraph).
- AudioProcessor now has a few more pure virtual methods that you'll need to implement: acceptsMidi(), producesMidi() and getName()
- moved all the audio plugin hosting classes into the main juce tree
- Mac: the project now requires at least XCode V2.5
- new class: ScopedTryLock
- added AudioUnit support to the audio hosting code
- any top-level components will now have their parentSizeChanged() method called when the screen res is changed (not on linux yet though..)
- jucer: added support for ImageButtons
- audio devices - a few tweaks to the various audio drivers to try to make the best possible guess at the input and output latencies that they introduce
- updated to include the latest version of Flac (1.2.1)
- added a parameter to DragAndDropTarget::isInterestedInDragSource(). This ma
- changed the parameters to AudioIODeviceCallback::audioDeviceAboutToStart(), so that it now just supplies a pointer to the device. If you need to, you can still find out the sample rate and block size by asking the device for them.

==============================================================================
Changelist for version 1.45


+ 0
- 72
extras/audio plugin host/build/win32/PluginHost.vcproj View File

@@ -214,78 +214,6 @@
>
</File>
</Filter>
<Filter
Name="plugins"
>
<File
RelativePath="..\..\src\plugins\juce_AudioPluginFormat.cpp"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_AudioPluginFormat.h"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_AudioPluginInstance.cpp"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_AudioPluginInstance.h"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_KnownPluginList.cpp"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_KnownPluginList.h"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_PluginDescription.cpp"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_PluginDescription.h"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_PluginDirectoryScanner.cpp"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_PluginDirectoryScanner.h"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_PluginListComponent.cpp"
>
</File>
<File
RelativePath="..\..\src\plugins\juce_PluginListComponent.h"
>
</File>
<Filter
Name="formats"
>
<File
RelativePath="..\..\src\plugins\formats\juce_AudioUnitPluginFormat.cpp"
>
</File>
<File
RelativePath="..\..\src\plugins\formats\juce_AudioUnitPluginFormat.h"
>
</File>
<File
RelativePath="..\..\src\plugins\formats\juce_VSTPluginFormat.cpp"
>
</File>
<File
RelativePath="..\..\src\plugins\formats\juce_VSTPluginFormat.h"
>
</File>
</Filter>
</Filter>
</Filter>
<Filter
Name="Resource Files"


+ 1
- 0
extras/audio plugin host/src/HostStartup.cpp View File

@@ -67,6 +67,7 @@ public:
AudioPluginFormatManager::getInstance()->addFormat (new InternalPluginFormat());
mainWindow = new MainHostWindow();
//mainWindow->setUsingNativeTitleBar (true);
commandManager->registerAllCommandsForTarget (this);
commandManager->registerAllCommandsForTarget (mainWindow);


+ 173
- 563
extras/audio plugin host/src/host/FilterGraph.cpp View File

@@ -32,6 +32,7 @@
#include "../../../../juce.h"
#include "FilterGraph.h"
#include "InternalFilters.h"
#include "GraphEditorPanel.h"
//==============================================================================
@@ -55,264 +56,185 @@ FilterConnection::~FilterConnection()
//==============================================================================
class PluginWindow : public DocumentWindow
{
public:
PluginWindow (Component* const uiComp,
FilterInGraph& owner_)
: DocumentWindow (uiComp->getName(), Colours::lightblue,
DocumentWindow::minimiseButton | DocumentWindow::closeButton),
owner (owner_)
{
setSize (400, 300);
setContentComponent (uiComp, true, true);
setTopLeftPosition (owner.lastX, owner.lastY);
setVisible (true);
}
~PluginWindow()
{
if (owner.activeGenericUI == this)
owner.activeGenericUI = 0;
else
owner.activeUI = 0;
const int FilterGraph::midiChannelNumber = 0x1000;
setContentComponent (0);
}
FilterGraph::FilterGraph()
: FileBasedDocument (filenameSuffix,
filenameWildcard,
"Load a filter graph",
"Save a filter graph"),
lastUID (0)
{
InternalPluginFormat internalFormat;
void moved()
{
owner.lastX = getX();
owner.lastY = getY();
}
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioInputFilter),
0.5f, 0.1f);
void closeButtonPressed()
{
delete this;
}
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::midiInputFilter),
0.25f, 0.1f);
private:
FilterInGraph& owner;
};
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioOutputFilter),
0.5f, 0.9f);
setChangedFlag (false);
}
//==============================================================================
FilterInGraph::FilterInGraph (FilterGraph& owner_, AudioPluginInstance* const filter_)
: owner (owner_),
filter (filter_),
uid (0),
processedAudio (1, 1),
activeUI (0),
activeGenericUI (0)
FilterGraph::~FilterGraph()
{
lastX = 100 + Random::getSystemRandom().nextInt (400);
lastY = 100 + Random::getSystemRandom().nextInt (400);
graph.clear();
}
FilterInGraph::~FilterInGraph()
uint32 FilterGraph::getNextUID() throw()
{
delete activeGenericUI;
delete activeUI;
delete filter;
return ++lastUID;
}
void FilterInGraph::setPosition (double newX, double newY) throw()
//==============================================================================
int FilterGraph::getNumFilters() const throw()
{
x = jlimit (0.0, 1.0, newX);
y = jlimit (0.0, 1.0, newY);
return graph.getNumNodes();
}
void FilterInGraph::showUI (bool useGenericUI)
const AudioProcessorGraph::Node::Ptr FilterGraph::getNode (const int index) const throw()
{
if (! useGenericUI)
{
if (activeUI == 0)
{
Component* ui = filter->createEditorIfNeeded();
if (ui == 0)
return showUI (true);
ui->setName (filter->getName());
activeUI = new PluginWindow (ui, *this);
}
if (activeUI != 0)
activeUI->toFront (true);
}
else
{
if (activeGenericUI == 0)
{
Component* ui = new GenericAudioProcessorEditor (filter);
ui->setName (filter->getName());
activeGenericUI = new PluginWindow (ui, *this);
}
if (activeGenericUI != 0)
activeGenericUI->toFront (true);
}
return graph.getNode (index);
}
void FilterInGraph::prepareBuffers (int blockSize)
const AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForId (const uint32 uid) const throw()
{
processedAudio.setSize (jmax (1, filter->getNumInputChannels(), filter->getNumOutputChannels()), blockSize);
processedAudio.clear();
processedMidi.clear();
return graph.getNodeForId (uid);
}
void FilterInGraph::renderBlock (int numSamples,
const ReferenceCountedArray <FilterInGraph>& filters,
const OwnedArray <FilterConnection>& connections)
void FilterGraph::addFilter (const PluginDescription* desc, double x, double y)
{
processedAudio.setSize (jmax (1, filter->getNumInputChannels(), filter->getNumOutputChannels()), numSamples);
if (desc != 0)
{
String errorMessage;
// this isn't particularly efficient - could do with some optimising here
processedAudio.clear();
processedMidi.clear();
AudioPluginInstance* instance
= AudioPluginFormatManager::getInstance()->createPluginInstance (*desc, errorMessage);
for (int i = connections.size(); --i >= 0;)
{
const FilterConnection* const fc = connections.getUnchecked(i);
AudioProcessorGraph::Node* node = 0;
if (instance != 0)
node = graph.addNode (instance);
if (fc->destFilterID == uid)
if (node != 0)
{
node->properties.setValue ("x", x);
node->properties.setValue ("y", y);
changed();
}
else
{
for (int j = filters.size(); --j >= 0;)
{
const FilterInGraph* const input = filters.getUnchecked(j);
if (filters.getUnchecked(j)->uid == fc->sourceFilterID)
{
if (fc->sourceChannel == FilterGraph::midiChannelNumber)
{
processedMidi.addEvents (input->processedMidi, 0, numSamples, 0);
}
else
{
if (fc->destChannel < filter->getNumInputChannels()
&& fc->sourceChannel < input->filter->getNumOutputChannels())
{
processedAudio.addFrom (fc->destChannel, 0, input->processedAudio,
fc->sourceChannel, 0, numSamples);
}
}
break;
}
}
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
TRANS("Couldn't create filter"),
errorMessage);
}
}
filter->processBlock (processedAudio, processedMidi);
}
XmlElement* FilterInGraph::createXml() const
void FilterGraph::removeFilter (const uint32 id)
{
XmlElement* e = new XmlElement ("FILTER");
e->setAttribute (T("uid"), (int) uid);
e->setAttribute (T("x"), x);
e->setAttribute (T("y"), y);
e->setAttribute (T("uiLastX"), lastX);
e->setAttribute (T("uiLastY"), lastY);
PluginDescription pd;
pd.fillInFromInstance (*filter);
e->addChildElement (pd.createXml());
XmlElement* state = new XmlElement ("STATE");
MemoryBlock m;
filter->getStateInformation (m);
state->addTextElement (m.toBase64Encoding());
e->addChildElement (state);
PluginWindow::closeCurrentlyOpenWindowsFor (id);
return e;
if (graph.removeNode (id))
changed();
}
FilterInGraph* FilterInGraph::createForDescription (FilterGraph& owner,
const PluginDescription& desc,
String& errorMessage)
void FilterGraph::disconnectFilter (const uint32 id)
{
AudioPluginInstance* instance = desc.createInstance (errorMessage);
if (instance != 0)
return new FilterInGraph (owner, instance);
if (graph.disconnectNode (id))
changed();
}
return 0;
void FilterGraph::removeIllegalConnections()
{
if (graph.removeIllegalConnections())
changed();
}
FilterInGraph* FilterInGraph::createFromXml (FilterGraph& owner, const XmlElement& xml)
void FilterGraph::setNodePosition (const int nodeId, double x, double y)
{
PluginDescription pd;
const AudioProcessorGraph::Node::Ptr n (graph.getNodeForId (nodeId));
forEachXmlChildElement (xml, e)
if (n != 0)
{
if (pd.loadFromXml (*e))
break;
n->properties.setValue ("x", jlimit (0.0, 1.0, x));
n->properties.setValue ("y", jlimit (0.0, 1.0, y));
}
}
String errorMessage;
FilterInGraph* const c = createForDescription (owner, pd, errorMessage);
if (c == 0)
return 0;
void FilterGraph::getNodePosition (const int nodeId, double& x, double& y) const
{
x = y = 0;
const XmlElement* const state = xml.getChildByName (T("STATE"));
const AudioProcessorGraph::Node::Ptr n (graph.getNodeForId (nodeId));
if (state != 0)
if (n != 0)
{
MemoryBlock m;
m.fromBase64Encoding (state->getAllSubText());
c->filter->setStateInformation (m.getData(), m.getSize());
x = n->properties.getDoubleValue ("x");
y = n->properties.getDoubleValue ("y");
}
}
c->uid = xml.getIntAttribute (T("uid"));
c->x = xml.getDoubleAttribute (T("x"));
c->y = xml.getDoubleAttribute (T("y"));
c->lastX = xml.getIntAttribute (T("uiLastX"), c->lastX);
c->lastY = xml.getIntAttribute (T("uiLastY"), c->lastY);
return c;
//==============================================================================
int FilterGraph::getNumConnections() const throw()
{
return graph.getNumConnections();
}
const AudioProcessorGraph::Connection* FilterGraph::getConnection (const int index) const throw()
{
return graph.getConnection (index);
}
//==============================================================================
const int FilterGraph::midiChannelNumber = 0x1000;
const AudioProcessorGraph::Connection* FilterGraph::getConnectionBetween (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel) const throw()
{
return graph.getConnectionBetween (sourceFilterUID, sourceFilterChannel,
destFilterUID, destFilterChannel);
}
FilterGraph::FilterGraph()
: FileBasedDocument (filenameSuffix,
filenameWildcard,
"Load a filter graph",
"Save a filter graph"),
lastUID (0)
bool FilterGraph::canConnect (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel) const throw()
{
InternalPluginFormat internalFormat;
return graph.canConnect (sourceFilterUID, sourceFilterChannel,
destFilterUID, destFilterChannel);
}
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioInputFilter),
0.5f, 0.1f);
bool FilterGraph::addConnection (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel)
{
const bool result = graph.addConnection (sourceFilterUID, sourceFilterChannel,
destFilterUID, destFilterChannel);
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::midiInputFilter),
0.25f, 0.1f);
if (result)
changed();
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioOutputFilter),
0.5f, 0.9f);
return result;
}
setChangedFlag (false);
void FilterGraph::removeConnection (const int index)
{
graph.removeConnection (index);
changed();
}
FilterGraph::~FilterGraph()
void FilterGraph::removeConnection (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel)
{
clear();
if (graph.removeConnection (sourceFilterUID, sourceFilterChannel,
destFilterUID, destFilterChannel))
changed();
}
uint32 FilterGraph::getNextUID() throw()
void FilterGraph::clear()
{
return ++lastUID;
PluginWindow::closeAllCurrentlyOpenWindows();
graph.clear();
changed();
}
//==============================================================================
@@ -376,224 +298,78 @@ void FilterGraph::setLastDocumentOpened (const File& file)
}
//==============================================================================
FilterInGraph* FilterGraph::getFilterForUID (const uint32 uid) const throw()
{
for (int i = filters.size(); --i >= 0;)
if (filters.getUnchecked(i)->uid == uid)
return filters.getUnchecked(i);
return 0;
}
void FilterGraph::addFilter (const FilterInGraph::Ptr& newFilter)
static XmlElement* createNodeXml (AudioProcessorGraph::Node* const node) throw()
{
if (newFilter->uid == 0)
newFilter->uid = getNextUID();
else if (newFilter->uid > lastUID)
lastUID = newFilter->uid;
AudioPluginInstance* plugin = dynamic_cast <AudioPluginInstance*> (node->processor);
filters.add (newFilter);
changed();
}
void FilterGraph::addFilter (const PluginDescription* desc, double x, double y)
{
if (desc != 0)
if (plugin == 0)
{
String errorMessage;
FilterInGraph* cf = FilterInGraph::createForDescription (*this, *desc, errorMessage);
if (cf != 0)
{
cf->setPosition (x, y);
addFilter (cf);
}
else
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
TRANS("Couldn't create filter"),
errorMessage);
}
}
}
void FilterGraph::removeFilter (const uint32 uid)
{
disconnectFilter (uid);
for (int i = filters.size(); --i >= 0;)
{
if (filters.getUnchecked(i)->uid == uid)
{
filters.remove (i);
changed();
}
jassertfalse
return 0;
}
}
void FilterGraph::disconnectFilter (const uint32 uid)
{
for (int i = connections.size(); --i >= 0;)
{
const FilterConnection* const fc = connections.getUnchecked(i);
if (fc->sourceFilterID == uid
|| fc->destFilterID == uid)
{
removeConnection (i);
}
}
}
XmlElement* e = new XmlElement ("FILTER");
e->setAttribute (T("uid"), (int) node->id);
e->setAttribute (T("x"), node->properties.getDoubleValue("x"));
e->setAttribute (T("y"), node->properties.getDoubleValue("y"));
e->setAttribute (T("uiLastX"), node->properties.getIntValue("uiLastX"));
e->setAttribute (T("uiLastY"), node->properties.getIntValue("uiLastY"));
bool FilterGraph::isAnInputTo (const uint32 possibleInput, const uint32 possibleDestination, int recursionCheck) const throw()
{
if (recursionCheck > 0)
{
for (int i = 0; i < connections.size(); ++i)
{
if (connections.getUnchecked(i)->destFilterID == possibleDestination
&& (connections.getUnchecked(i)->sourceFilterID == possibleInput
|| isAnInputTo (possibleInput, connections.getUnchecked(i)->sourceFilterID, recursionCheck - 1)))
return true;
}
}
PluginDescription pd;
return false;
}
plugin->fillInPluginDescription (pd);
bool FilterGraph::isAnInputTo (const uint32 possibleInput, const uint32 possibleDestination) const throw()
{
return isAnInputTo (possibleInput, possibleDestination, filters.size() + 1);
}
e->addChildElement (pd.createXml());
const FilterConnection* FilterGraph::getConnectionBetween (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel) const throw()
{
for (int i = connections.size(); --i >= 0;)
{
FilterConnection* const fc = connections.getUnchecked(i);
XmlElement* state = new XmlElement ("STATE");
if (fc->sourceFilterID == sourceFilterUID
&& fc->sourceChannel == sourceFilterChannel
&& fc->destFilterID == destFilterUID
&& fc->destChannel == destFilterChannel)
{
return fc;
}
}
MemoryBlock m;
node->processor->getStateInformation (m);
state->addTextElement (m.toBase64Encoding());
e->addChildElement (state);
return 0;
return e;
}
bool FilterGraph::canConnect (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel) const throw()
void FilterGraph::createNodeFromXml (const XmlElement& xml)
{
if (sourceFilterChannel < 0
|| destFilterChannel < 0
|| sourceFilterUID == destFilterUID
|| (destFilterChannel == midiChannelNumber) != (sourceFilterChannel == midiChannelNumber))
return false;
const FilterInGraph* const source = getFilterForUID (sourceFilterUID);
if (source == 0
|| (sourceFilterChannel != midiChannelNumber && (sourceFilterChannel < 0 || sourceFilterChannel >= source->filter->getNumOutputChannels()))
|| (sourceFilterChannel == midiChannelNumber && ! source->filter->producesMidi()))
return false;
const FilterInGraph* const dest = getFilterForUID (destFilterUID);
if (dest == 0
|| (destFilterChannel != midiChannelNumber && (destFilterChannel < 0 || destFilterChannel >= dest->filter->getNumInputChannels()))
|| (destFilterChannel == midiChannelNumber && ! dest->filter->acceptsMidi()))
return false;
if (getConnectionBetween (sourceFilterUID, sourceFilterChannel, destFilterUID, destFilterChannel) != 0)
return false;
return true;
}
PluginDescription pd;
bool FilterGraph::addConnection (uint32 sourceFilterUID, int sourceChannel,
uint32 destFilterUID, int destChannel)
{
if (canConnect (sourceFilterUID, sourceChannel, destFilterUID, destChannel))
forEachXmlChildElement (xml, e)
{
FilterConnection* const conn = new FilterConnection (*this);
conn->sourceFilterID = sourceFilterUID;
conn->sourceChannel = sourceChannel;
conn->destFilterID = destFilterUID;
conn->destChannel = destChannel;
connections.add (conn);
changed();
return true;
if (pd.loadFromXml (*e))
break;
}
return false;
}
String errorMessage;
void FilterGraph::removeConnection (const int index)
{
if (connections [index] != 0)
{
connections.remove (index);
changed();
}
}
AudioPluginInstance* instance
= AudioPluginFormatManager::getInstance()->createPluginInstance (pd, errorMessage);
void FilterGraph::removeIllegalConnections()
{
for (int i = connections.size(); --i >= 0;)
if (instance == 0)
{
const FilterConnection* const fc = connections.getUnchecked(i);
bool ok = true;
const FilterInGraph* const source = getFilterForUID (fc->sourceFilterID);
if (source == 0
|| (fc->sourceChannel != midiChannelNumber && (fc->sourceChannel < 0 || fc->sourceChannel >= source->filter->getNumOutputChannels()))
|| (fc->sourceChannel == midiChannelNumber && ! source->filter->producesMidi()))
ok = false;
const FilterInGraph* const dest = getFilterForUID (fc->destFilterID);
// xxx handle ins + outs
}
if (dest == 0
|| (fc->destChannel != midiChannelNumber && (fc->destChannel < 0 || fc->destChannel >= dest->filter->getNumInputChannels()))
|| (fc->destChannel == midiChannelNumber && ! dest->filter->acceptsMidi()))
ok = false;
if (instance == 0)
return;
AudioProcessorGraph::Node::Ptr node (graph.addNode (instance, xml.getIntAttribute (T("uid"))));
if (! ok)
removeConnection (i);
}
}
const XmlElement* const state = xml.getChildByName (T("STATE"));
void FilterGraph::removeConnection (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel)
{
for (int i = connections.size(); --i >= 0;)
if (state != 0)
{
const FilterConnection* const fc = connections.getUnchecked(i);
MemoryBlock m;
m.fromBase64Encoding (state->getAllSubText());
if (fc->sourceFilterID == sourceFilterUID
&& fc->sourceChannel == sourceFilterChannel
&& fc->destFilterID == destFilterUID
&& fc->destChannel == destFilterChannel)
{
removeConnection (i);
}
node->processor->setStateInformation (m.getData(), m.getSize());
}
}
void FilterGraph::clear()
{
connections.clear();
filters.clear();
changed();
node->properties.setValue ("x", xml.getDoubleAttribute (T("x")));
node->properties.setValue ("y", xml.getDoubleAttribute (T("y")));
node->properties.setValue ("uiLastX", xml.getIntAttribute (T("uiLastX")));
node->properties.setValue ("uiLastY", xml.getIntAttribute (T("uiLastY")));
}
XmlElement* FilterGraph::createXml() const
@@ -601,19 +377,21 @@ XmlElement* FilterGraph::createXml() const
XmlElement* xml = new XmlElement ("FILTERGRAPH");
int i;
for (i = 0; i < filters.size(); ++i)
xml->addChildElement (filters.getUnchecked(i)->createXml());
for (i = 0; i < graph.getNumNodes(); ++i)
{
xml->addChildElement (createNodeXml (graph.getNode (i)));
}
for (i = 0; i < connections.size(); ++i)
for (i = 0; i < graph.getNumConnections(); ++i)
{
const FilterConnection* const fc = connections.getUnchecked(i);
const AudioProcessorGraph::Connection* const fc = graph.getConnection(i);
XmlElement* e = new XmlElement ("CONNECTION");
e->setAttribute (T("srcFilter"), (int) fc->sourceFilterID);
e->setAttribute (T("srcChannel"), fc->sourceChannel);
e->setAttribute (T("dstFilter"), (int) fc->destFilterID);
e->setAttribute (T("dstChannel"), fc->destChannel);
e->setAttribute (T("srcFilter"), (int) fc->sourceNodeId);
e->setAttribute (T("srcChannel"), fc->sourceChannelIndex);
e->setAttribute (T("dstFilter"), (int) fc->destNodeId);
e->setAttribute (T("dstChannel"), fc->destChannelIndex);
xml->addChildElement (e);
}
@@ -627,10 +405,8 @@ void FilterGraph::restoreFromXml (const XmlElement& xml)
forEachXmlChildElementWithTagName (xml, e, T("FILTER"))
{
FilterInGraph* f = FilterInGraph::createFromXml (*this, *e);
if (f != 0)
addFilter (f);
createNodeFromXml (*e);
changed();
}
forEachXmlChildElementWithTagName (xml, e, T("CONNECTION"))
@@ -641,171 +417,5 @@ void FilterGraph::restoreFromXml (const XmlElement& xml)
e->getIntAttribute (T("dstChannel")));
}
removeIllegalConnections();
}
//==============================================================================
FilterGraphPlayer::FilterGraphPlayer (FilterGraph& graph_)
: graph (graph_),
sampleRate (44100.0),
blockSize (512),
deviceManager (0),
inputChannelData (0),
totalNumInputChannels (0),
outputChannelData (0),
totalNumOutputChannels (0)
{
setAudioDeviceManager (0);
keyState.addListener (&messageCollector);
graph.addChangeListener (this);
}
FilterGraphPlayer::~FilterGraphPlayer()
{
graph.removeChangeListener (this);
keyState.removeListener (&messageCollector);
}
void FilterGraphPlayer::setAudioDeviceManager (AudioDeviceManager* dm)
{
if (deviceManager != 0)
{
deviceManager->removeMidiInputCallback (this);
deviceManager->setAudioCallback (0);
}
deviceManager = dm;
if (dm != 0)
{
dm->addMidiInputCallback (String::empty, this);
dm->setAudioCallback (this);
}
}
int FilterGraphPlayer::compareElements (FilterInGraph* const first, FilterInGraph* const second) throw()
{
const bool firstIsInputToSecond = first->owner.isAnInputTo (first->uid, second->uid);
const bool secondInInputToFirst = first->owner.isAnInputTo (second->uid, first->uid);
if (firstIsInputToSecond == secondInInputToFirst)
return 0;
return firstIsInputToSecond ? -1 : 1;
}
void FilterGraphPlayer::update()
{
ReferenceCountedArray <FilterInGraph> filtersBeingRemoved (filters);
ReferenceCountedArray <FilterInGraph> newFilters (graph.filters);
int i;
for (i = newFilters.size(); --i >= 0;)
if (filters.contains (newFilters.getUnchecked(i)))
newFilters.remove (i);
for (i = filtersBeingRemoved.size(); --i >= 0;)
if (graph.filters.contains (filtersBeingRemoved.getUnchecked(i)))
filtersBeingRemoved.remove (i);
// prepare any new filters for use..
for (i = 0; i < newFilters.size(); ++i)
newFilters.getUnchecked(i)->filter->prepareToPlay (sampleRate, blockSize);
ReferenceCountedArray <FilterInGraph> sortedFilters (graph.filters);
sortedFilters.sort (*this, true);
for (i = sortedFilters.size(); --i >= 0;)
{
PlayerAwareFilter* const specialFilter = dynamic_cast <PlayerAwareFilter*> (sortedFilters.getUnchecked(i)->filter);
if (specialFilter != 0)
specialFilter->setPlayer (this);
}
{
const ScopedLock sl (processLock);
filters = sortedFilters;
connections.clear();
for (int i = 0; i < graph.connections.size(); ++i)
connections.add (new FilterConnection (*graph.connections.getUnchecked(i)));
}
// release any old ones..
for (int i = 0; i < filtersBeingRemoved.size(); ++i)
{
filtersBeingRemoved.getUnchecked(i)->filter->releaseResources();
PlayerAwareFilter* const specialFilter = dynamic_cast <PlayerAwareFilter*> (filtersBeingRemoved.getUnchecked(i)->filter);
if (specialFilter != 0)
specialFilter->setPlayer (0);
}
}
void FilterGraphPlayer::changeListenerCallback (void*)
{
update();
}
void FilterGraphPlayer::audioDeviceIOCallback (const float** inputChannelData_,
int totalNumInputChannels_,
float** outputChannelData_,
int totalNumOutputChannels_,
int numSamples)
{
incomingMidi.clear();
messageCollector.removeNextBlockOfMessages (incomingMidi, numSamples);
for (int i = 0; i < totalNumOutputChannels_; ++i)
if (outputChannelData_[i] != 0)
zeromem (outputChannelData_[i], sizeof (float) * numSamples);
const ScopedLock sl (processLock);
inputChannelData = inputChannelData_;
totalNumInputChannels = totalNumInputChannels_;
outputChannelData = outputChannelData_;
totalNumOutputChannels = totalNumOutputChannels_;
for (int i = 0; i < filters.size(); ++i)
{
FilterInGraph* const cf = filters.getUnchecked(i);
cf->renderBlock (numSamples, filters, connections);
}
}
void FilterGraphPlayer::audioDeviceAboutToStart (double sampleRate_, int numSamplesPerBlock)
{
const ScopedLock sl (processLock);
sampleRate = sampleRate_;
blockSize = numSamplesPerBlock;
messageCollector.reset (sampleRate_);
for (int i = 0; i < filters.size(); ++i)
{
filters.getUnchecked(i)->filter->prepareToPlay (sampleRate, blockSize);
filters.getUnchecked(i)->prepareBuffers (blockSize);
}
graph.sendChangeMessage (&graph);
}
void FilterGraphPlayer::audioDeviceStopped()
{
const ScopedLock sl (processLock);
for (int i = 0; i < filters.size(); ++i)
filters.getUnchecked(i)->filter->releaseResources();
}
void FilterGraphPlayer::handleIncomingMidiMessage (MidiInput*, const MidiMessage& message)
{
// keyState.processNextMidiEvent (message);
messageCollector.addMessageToQueue (message);
graph.removeIllegalConnections();
}

+ 26
- 22
extras/audio plugin host/src/host/FilterGraph.h View File

@@ -32,12 +32,8 @@
#ifndef __JUCE_FILTERGRAPH_JUCEHEADER__
#define __JUCE_FILTERGRAPH_JUCEHEADER__
#include "../plugins/juce_AudioPluginInstance.h"
#include "../plugins/juce_PluginDescription.h"
class FilterInGraph;
class FilterGraph;
class FilterGraphPlayer;
const char* const filenameSuffix = ".filtergraph";
const char* const filenameWildcard = "*.filtergraph";
@@ -75,7 +71,7 @@ private:
/**
Represents one of the filters in a FilterGraph.
*/
class FilterInGraph : public ReferenceCountedObject
/*class FilterInGraph : public ReferenceCountedObject
{
public:
//==============================================================================
@@ -129,7 +125,7 @@ private:
FilterInGraph (const FilterInGraph&);
const FilterInGraph& operator= (const FilterInGraph&);
};
*/
//==============================================================================
/**
@@ -143,11 +139,12 @@ public:
~FilterGraph();
//==============================================================================
int getNumFilters() const throw() { return filters.size(); }
FilterInGraph* getFilter (const int index) const throw() { return filters [index]; }
FilterInGraph* getFilterForUID (const uint32 uid) const throw();
AudioProcessorGraph& getGraph() throw() { return graph; }
int getNumFilters() const throw();
const AudioProcessorGraph::Node::Ptr getNode (const int index) const throw();
const AudioProcessorGraph::Node::Ptr getNodeForId (const uint32 uid) const throw();
void addFilter (const FilterInGraph::Ptr& newFilter);
void addFilter (const PluginDescription* desc, double x, double y);
void removeFilter (const uint32 filterUID);
@@ -155,14 +152,15 @@ public:
void removeIllegalConnections();
//==============================================================================
int getNumConnections() const throw() { return connections.size(); }
const FilterConnection* getConnection (const int index) const throw() { return connections [index]; }
void setNodePosition (const int nodeId, double x, double y);
void getNodePosition (const int nodeId, double& x, double& y) const;
const FilterConnection* getConnectionBetween (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel) const throw();
//==============================================================================
int getNumConnections() const throw();
const AudioProcessorGraph::Connection* getConnection (const int index) const throw();
bool isAnInputTo (const uint32 possibleInput, const uint32 possibleDestination) const throw();
const AudioProcessorGraph::Connection* getConnectionBetween (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel) const throw();
bool canConnect (uint32 sourceFilterUID, int sourceFilterChannel,
uint32 destFilterUID, int destFilterChannel) const throw();
@@ -177,6 +175,9 @@ public:
void clear();
//==============================================================================
XmlElement* createXml() const;
void restoreFromXml (const XmlElement& xml);
@@ -195,14 +196,17 @@ public:
juce_UseDebuggingNewOperator
private:
friend class FilterGraphPlayer;
ReferenceCountedArray <FilterInGraph> filters;
OwnedArray <FilterConnection> connections;
//friend class FilterGraphPlayer;
//ReferenceCountedArray <FilterInGraph> filters;
//OwnedArray <FilterConnection> connections;
AudioProcessorGraph graph;
AudioProcessorPlayer player;
uint32 lastUID;
uint32 getNextUID() throw();
bool isAnInputTo (const uint32 possibleInput, const uint32 possibleDestination, int recursionCheck) const throw();
void createNodeFromXml (const XmlElement& xml);
FilterGraph (const FilterGraph&);
const FilterGraph& operator= (const FilterGraph&);
@@ -213,7 +217,7 @@ private:
/**
*/
class FilterGraphPlayer : public AudioIODeviceCallback,
/*class FilterGraphPlayer : public AudioIODeviceCallback,
public MidiInputCallback,
public ChangeListener
@@ -274,6 +278,6 @@ private:
FilterGraphPlayer (const FilterGraphPlayer&);
const FilterGraphPlayer& operator= (const FilterGraphPlayer&);
};
*/
#endif

+ 147
- 45
extras/audio plugin host/src/host/GraphEditorPanel.cpp View File

@@ -35,6 +35,95 @@
#include "MainHostWindow.h"
//==============================================================================
class PluginWindow;
static Array <PluginWindow*> activePluginWindows;
PluginWindow::PluginWindow (Component* const uiComp,
AudioProcessorGraph::Node* owner_,
const bool isGeneric_)
: DocumentWindow (uiComp->getName(), Colours::lightblue,
DocumentWindow::minimiseButton | DocumentWindow::closeButton),
owner (owner_),
isGeneric (isGeneric_)
{
setSize (400, 300);
setContentComponent (uiComp, true, true);
setTopLeftPosition (owner->properties.getIntValue ("uiLastX", Random::getSystemRandom().nextInt (500)),
owner->properties.getIntValue ("uiLastY", Random::getSystemRandom().nextInt (500)));
setVisible (true);
activePluginWindows.add (this);
}
void PluginWindow::closeCurrentlyOpenWindowsFor (const uint32 nodeId)
{
for (int i = activePluginWindows.size(); --i >= 0;)
if (activePluginWindows.getUnchecked(i)->owner->id == nodeId)
delete activePluginWindows.getUnchecked(i);
}
void PluginWindow::closeAllCurrentlyOpenWindows()
{
for (int i = activePluginWindows.size(); --i >= 0;)
delete activePluginWindows.getUnchecked(i);
}
PluginWindow* PluginWindow::getWindowFor (AudioProcessorGraph::Node* node,
bool useGenericView)
{
for (int i = activePluginWindows.size(); --i >= 0;)
if (activePluginWindows.getUnchecked(i)->owner == node
&& activePluginWindows.getUnchecked(i)->isGeneric == useGenericView)
return activePluginWindows.getUnchecked(i);
AudioProcessorEditor* ui = 0;
if (! useGenericView)
{
ui = node->processor->createEditorIfNeeded();
if (ui == 0)
useGenericView = true;
}
if (useGenericView)
{
ui = new GenericAudioProcessorEditor (node->processor);
}
if (ui != 0)
{
AudioPluginInstance* const plugin = dynamic_cast <AudioPluginInstance*> (node->processor);
if (plugin != 0)
ui->setName (plugin->getName());
return new PluginWindow (ui, node, useGenericView);
}
return 0;
}
PluginWindow::~PluginWindow()
{
activePluginWindows.removeValue (this);
setContentComponent (0);
}
void PluginWindow::moved()
{
owner->properties.setValue ("uiLastX", getX());
owner->properties.setValue ("uiLastY", getY());
}
void PluginWindow::closeButtonPressed()
{
delete this;
}
//==============================================================================
class PinComponent : public Component,
public SettableTooltipClient
@@ -47,16 +136,16 @@ public:
index (index_),
isInput (isInput_)
{
const FilterInGraph* const f = graph.getFilterForUID (filterID_);
const AudioProcessorGraph::Node::Ptr node (graph.getNodeForId (filterID_));
if (f != 0)
if (node != 0)
{
String tip;
if (isInput)
tip = f->filter->getInputChannelName (index_);
tip = node->processor->getInputChannelName (index_);
else
tip = f->filter->getOutputChannelName (index_);
tip = node->processor->getOutputChannelName (index_);
if (tip.isEmpty())
{
@@ -185,10 +274,15 @@ public:
}
else if (r == 3 || r == 4)
{
FilterInGraph* const f = graph.getFilterForUID (filterID);
AudioProcessorGraph::Node::Ptr f (graph.getNodeForId (filterID));
if (f != 0)
f->showUI (r == 4);
{
PluginWindow* const w = PluginWindow::getWindowFor (f, r == 4);
if (w != 0)
w->toFront (true);
}
}
}
}
@@ -203,15 +297,11 @@ public:
if (getParentComponent() != 0)
getParentComponent()->globalPositionToRelative (x, y);
const FilterInGraph::Ptr f (graph.getFilterForUID (filterID));
if (f != 0)
{
f->setPosition ((x + getWidth() / 2) / (double) getParentWidth(),
(y + getHeight() / 2) / (double) getParentHeight());
graph.setNodePosition (filterID,
(x + getWidth() / 2) / (double) getParentWidth(),
(y + getHeight() / 2) / (double) getParentHeight());
getGraphPanel()->updateComponents();
}
getGraphPanel()->updateComponents();
}
}
@@ -219,10 +309,15 @@ public:
{
if (e.mouseWasClicked() && e.getNumberOfClicks() == 2)
{
const FilterInGraph::Ptr f (graph.getFilterForUID (filterID));
const AudioProcessorGraph::Node::Ptr f (graph.getNodeForId (filterID));
if (f != 0)
f->showUI (false);
{
PluginWindow* const w = PluginWindow::getWindowFor (f, false);
if (w != 0)
w->toFront (true);
}
}
else if (! e.mouseWasClicked())
{
@@ -295,7 +390,7 @@ public:
void update()
{
const FilterInGraph* const f = graph.getFilterForUID (filterID);
const AudioProcessorGraph::Node::Ptr f (graph.getNodeForId (filterID));
if (f == 0)
{
@@ -303,12 +398,12 @@ public:
return;
}
numIns = f->filter->getNumInputChannels();
if (f->filter->acceptsMidi())
numIns = f->processor->getNumInputChannels();
if (f->processor->acceptsMidi())
++numIns;
numOuts = f->filter->getNumOutputChannels();
if (f->filter->producesMidi())
numOuts = f->processor->getNumOutputChannels();
if (f->processor->producesMidi())
++numOuts;
int w = 100;
@@ -316,14 +411,20 @@ public:
w = jmax (w, (jmax (numIns, numOuts) + 1) * 20);
const int textWidth = font.getStringWidth (f->filter->getName());
const int textWidth = font.getStringWidth (f->processor->getName());
w = jmax (w, 16 + jmin (textWidth, 300));
if (textWidth > 300)
h = 100;
setSize (w, h);
setCentreRelative ((float) f->getX(), (float) f->getY());
setName (f->processor->getName());
{
double x, y;
graph.getNodePosition (filterID, x, y);
setCentreRelative ((float) x, (float) y);
}
if (numIns != numInputs || numOuts != numOutputs)
{
@@ -333,20 +434,18 @@ public:
deleteAllChildren();
int i;
for (i = 0; i < f->filter->getNumInputChannels(); ++i)
for (i = 0; i < f->processor->getNumInputChannels(); ++i)
addAndMakeVisible (new PinComponent (graph, filterID, i, true));
if (f->filter->acceptsMidi())
if (f->processor->acceptsMidi())
addAndMakeVisible (new PinComponent (graph, filterID, FilterGraph::midiChannelNumber, true));
for (i = 0; i < f->filter->getNumOutputChannels(); ++i)
for (i = 0; i < f->processor->getNumOutputChannels(); ++i)
addAndMakeVisible (new PinComponent (graph, filterID, i, false));
if (f->filter->producesMidi())
if (f->processor->producesMidi())
addAndMakeVisible (new PinComponent (graph, filterID, FilterGraph::midiChannelNumber, false));
setName (f->filter->getName());
resized();
}
}
@@ -679,17 +778,17 @@ FilterComponent* GraphEditorPanel::getComponentForFilter (const uint32 filterID)
return 0;
}
ConnectorComponent* GraphEditorPanel::getComponentForConnection (const FilterConnection& conn) const
ConnectorComponent* GraphEditorPanel::getComponentForConnection (const AudioProcessorGraph::Connection& conn) const
{
for (int i = getNumChildComponents(); --i >= 0;)
{
ConnectorComponent* const c = dynamic_cast <ConnectorComponent*> (getChildComponent (i));
if (c != 0
&& c->sourceFilterID == conn.sourceFilterID
&& c->destFilterID == conn.destFilterID
&& c->sourceFilterChannel == conn.sourceChannel
&& c->destFilterChannel == conn.destChannel)
&& c->sourceFilterID == conn.sourceNodeId
&& c->destFilterID == conn.destNodeId
&& c->sourceFilterChannel == conn.sourceChannelIndex
&& c->destFilterChannel == conn.destChannelIndex)
{
return c;
}
@@ -759,11 +858,11 @@ void GraphEditorPanel::updateComponents()
for (i = graph.getNumFilters(); --i >= 0;)
{
const FilterInGraph* const f = graph.getFilter (i);
const AudioProcessorGraph::Node::Ptr f (graph.getNode (i));
if (getComponentForFilter (f->uid) == 0)
if (getComponentForFilter (f->id) == 0)
{
FilterComponent* const comp = new FilterComponent (graph, f->uid);
FilterComponent* const comp = new FilterComponent (graph, f->id);
addAndMakeVisible (comp);
comp->update();
}
@@ -771,15 +870,15 @@ void GraphEditorPanel::updateComponents()
for (i = graph.getNumConnections(); --i >= 0;)
{
const FilterConnection* const c = graph.getConnection (i);
const AudioProcessorGraph::Connection* const c = graph.getConnection (i);
if (getComponentForConnection (*c) == 0)
{
ConnectorComponent* const comp = new ConnectorComponent (graph);
addAndMakeVisible (comp);
comp->setInput (c->sourceFilterID, c->sourceChannel);
comp->setOutput (c->destFilterID, c->destChannel);
comp->setInput (c->sourceNodeId, c->sourceChannelIndex);
comp->setOutput (c->destNodeId, c->destChannelIndex);
}
}
}
@@ -942,24 +1041,27 @@ GraphDocumentComponent::GraphDocumentComponent (AudioDeviceManager* deviceManage
{
addAndMakeVisible (graphPanel = new GraphEditorPanel (graph));
graphPlayer = new FilterGraphPlayer (graph);
graphPlayer.setProcessor (&graph.getGraph());
keyState.addListener (&graphPlayer.getMidiMessageCollector());
addAndMakeVisible (keyboardComp = new MidiKeyboardComponent (graphPlayer->keyState,
addAndMakeVisible (keyboardComp = new MidiKeyboardComponent (keyState,
MidiKeyboardComponent::horizontalKeyboard));
addAndMakeVisible (statusBar = new TooltipBar());
graphPlayer->setAudioDeviceManager (deviceManager);
deviceManager->setAudioCallback (&graphPlayer);
graphPanel->updateComponents();
}
GraphDocumentComponent::~GraphDocumentComponent()
{
deviceManager->setAudioCallback (0);
deleteAllChildren();
graphPlayer->setAudioDeviceManager (0);
deleteAndZero (graphPlayer);
graphPlayer.setProcessor (0);
keyState.removeListener (&graphPlayer.getMidiMessageCollector());
graph.clear();
}


+ 29
- 3
extras/audio plugin host/src/host/GraphEditorPanel.h View File

@@ -32,7 +32,6 @@
#ifndef __JUCE_FILTERGRAPHEDITOR_JUCEHEADER__
#define __JUCE_FILTERGRAPHEDITOR_JUCEHEADER__
#include "../plugins/juce_KnownPluginList.h"
#include "FilterGraph.h"
class FilterComponent;
@@ -57,7 +56,7 @@ public:
void createNewPlugin (const PluginDescription* desc, int x, int y);
FilterComponent* getComponentForFilter (const uint32 filterID) const;
ConnectorComponent* getComponentForConnection (const FilterConnection& conn) const;
ConnectorComponent* getComponentForConnection (const AudioProcessorGraph::Connection& conn) const;
PinComponent* findPinAt (const int x, const int y) const;
void resized();
@@ -110,12 +109,39 @@ public:
private:
AudioDeviceManager* deviceManager;
FilterGraphPlayer* graphPlayer;
AudioProcessorPlayer graphPlayer;
MidiKeyboardState keyState;
GraphEditorPanel* graphPanel;
Component* keyboardComp;
Component* statusBar;
};
//==============================================================================
/** A desktop window containing a plugin's UI.
*/
class PluginWindow : public DocumentWindow
{
PluginWindow (Component* const uiComp,
AudioProcessorGraph::Node* owner_,
const bool isGeneric_);
public:
static PluginWindow* getWindowFor (AudioProcessorGraph::Node* node,
bool useGenericView);
static void closeCurrentlyOpenWindowsFor (const uint32 nodeId);
static void closeAllCurrentlyOpenWindows();
~PluginWindow();
void moved();
void closeButtonPressed();
private:
AudioProcessorGraph::Node* owner;
bool isGeneric;
};
#endif

+ 9
- 306
extras/audio plugin host/src/host/InternalFilters.cpp View File

@@ -33,319 +33,22 @@
#include "InternalFilters.h"
#include "FilterGraph.h"
//==============================================================================
class InternalFilterBase : public AudioPluginInstance,
public FilterGraphPlayer::PlayerAwareFilter
{
public:
InternalFilterBase()
: player (0)
{
}
~InternalFilterBase()
{
}
void setPlayer (FilterGraphPlayer* p)
{
player = p;
playerChanged();
}
virtual void playerChanged() {}
const String getManufacturer() const { return "Raw Material Software"; }
const String getFormatName() const { return "Internal"; }
const File getFile() const { return File::nonexistent; }
int getUID() const { return getName().hashCode(); }
int getSamplesLatency() const { return 0; }
AudioProcessorEditor* createEditor() { return 0; }
int getNumParameters() { return 0; }
const String getParameterName (int) { return String::empty; }
float getParameter (int) { return 0; }
const String getParameterText (int) { return String::empty; }
void setParameter (int, float) {}
int getNumPrograms() { return 0; }
int getCurrentProgram() { return 0; }
void setCurrentProgram (int) {}
const String getProgramName (int) { return String::empty; }
void changeProgramName (int, const String&) {}
void getStateInformation (MemoryBlock&) {}
void setStateInformation (const void*, int) {}
protected:
FilterGraphPlayer* player;
AudioIODevice* getAudioDevice() const
{
if (player != 0)
{
AudioDeviceManager* const dm = player->getAudioDeviceManager();
jassert (dm != 0);
if (dm != 0)
return dm->getCurrentAudioDevice();
}
return 0;
}
};
//==============================================================================
class AudioInputDeviceFilter : public InternalFilterBase
{
public:
AudioInputDeviceFilter (const int numChannels)
{
setPlayConfigDetails (0, numChannels, getSampleRate(), getBlockSize());
}
~AudioInputDeviceFilter() {}
const String getName() const { return "Audio Input"; }
const String getVersion() const { return "1.0"; }
bool isInstrument() const { return true; }
const String getCategory() const { return "I/O devices"; }
bool acceptsMidi() const { return false; }
bool producesMidi() const { return false; }
void playerChanged()
{
AudioIODevice* const dev = getAudioDevice();
if (dev != 0)
setPlayConfigDetails (0, dev->getActiveInputChannels().countNumberOfSetBits(), getSampleRate(), getBlockSize());
}
void prepareToPlay (double /*sampleRate*/, int /*estimatedSamplesPerBlock*/)
{
playerChanged();
}
void releaseResources()
{
}
void processBlock (AudioSampleBuffer& buffer, MidiBuffer&)
{
int n = 0;
for (int i = 0; i < player->totalNumInputChannels; ++i)
{
if (n >= getNumOutputChannels())
break;
if (player->inputChannelData [i] != 0)
{
buffer.copyFrom (n, 0, player->inputChannelData [i], buffer.getNumSamples());
++n;
}
}
}
const String getInputChannelName (const int channelIndex) const
{
return String (channelIndex + 1);
}
const String getOutputChannelName (const int channelIndex) const
{
AudioIODevice* const dev = getAudioDevice();
if (dev != 0)
return dev->getInputChannelNames() [channelIndex];
return "Input Channel " + String (channelIndex + 1);
}
bool isInputChannelStereoPair (int) const
{
return true;
}
bool isOutputChannelStereoPair (int) const
{
return true;
}
};
//==============================================================================
class AudioOutputDeviceFilter : public InternalFilterBase
{
public:
AudioOutputDeviceFilter (const int numChannels)
{
setPlayConfigDetails (numChannels, 0, getSampleRate(), getBlockSize());
}
~AudioOutputDeviceFilter() {}
const String getName() const { return "Audio Output"; }
const String getVersion() const { return "1.0"; }
bool isInstrument() const { return false; }
const String getCategory() const { return "I/O devices"; }
bool acceptsMidi() const { return false; }
bool producesMidi() const { return false; }
void playerChanged()
{
AudioIODevice* const dev = getAudioDevice();
if (dev != 0)
setPlayConfigDetails (dev->getActiveOutputChannels().countNumberOfSetBits(), 0, getSampleRate(), getBlockSize());
}
void prepareToPlay (double /*sampleRate*/, int /*estimatedSamplesPerBlock*/)
{
playerChanged();
}
void releaseResources()
{
}
void processBlock (AudioSampleBuffer& buffer, MidiBuffer&)
{
int n = 0;
for (int i = 0; i < player->totalNumOutputChannels; ++i)
{
float* const dst = player->outputChannelData [i];
if (dst != 0)
{
if (n >= getNumInputChannels())
{
zeromem (dst, sizeof (float) * buffer.getNumSamples());
}
else
{
memcpy (dst, buffer.getSampleData (n),
sizeof (float) * buffer.getNumSamples());
}
++n;
}
}
}
const String getInputChannelName (const int channelIndex) const
{
AudioIODevice* const dev = getAudioDevice();
if (dev != 0)
return dev->getOutputChannelNames() [channelIndex];
return "Output Channel " + String (channelIndex + 1);
}
const String getOutputChannelName (const int channelIndex) const
{
return String (channelIndex + 1);
}
bool isInputChannelStereoPair (int) const
{
return true;
}
bool isOutputChannelStereoPair (int) const
{
return true;
}
};
//==============================================================================
class MidiInputDeviceFilter : public InternalFilterBase
{
public:
MidiInputDeviceFilter()
{
}
~MidiInputDeviceFilter() {}
const String getName() const { return "Midi Input"; }
const String getVersion() const { return "1.0"; }
bool isInstrument() const { return true; }
const String getCategory() const { return "I/O devices"; }
bool acceptsMidi() const { return false; }
bool producesMidi() const { return true; }
void playerChanged()
{
if (player != 0)
{
AudioDeviceManager* const dm = player->getAudioDeviceManager();
(void) dm;
jassert (dm != 0);
}
}
void prepareToPlay (double /*sampleRate*/, int /*estimatedSamplesPerBlock*/)
{
playerChanged();
}
void releaseResources()
{
}
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiBuffer)
{
midiBuffer.clear();
midiBuffer.addEvents (player->incomingMidi, 0, buffer.getNumSamples(), 0);
}
const String getInputChannelName (const int channelIndex) const
{
return String (channelIndex + 1);
}
const String getOutputChannelName (const int channelIndex) const
{
AudioIODevice* const dev = getAudioDevice();
if (dev != 0)
return dev->getInputChannelNames() [channelIndex];
return "Midi Input";
}
bool isInputChannelStereoPair (int) const
{
return true;
}
bool isOutputChannelStereoPair (int) const
{
return true;
}
};
//==============================================================================
InternalPluginFormat::InternalPluginFormat()
{
{
AudioInputDeviceFilter f (2);
audioInDesc.fillInFromInstance (f);
AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);
p.fillInPluginDescription (audioOutDesc);
}
{
AudioOutputDeviceFilter f (2);
audioOutDesc.fillInFromInstance (f);
AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);
p.fillInPluginDescription (audioInDesc);
}
{
MidiInputDeviceFilter f;
midiInDesc.fillInFromInstance (f);
AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);
p.fillInPluginDescription (midiInDesc);
}
}
@@ -353,15 +56,15 @@ AudioPluginInstance* InternalPluginFormat::createInstanceFromDescription (const
{
if (desc.name == audioOutDesc.name)
{
return new AudioOutputDeviceFilter (desc.numInputChannels);
return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);
}
else if (desc.name == audioInDesc.name)
{
return new AudioInputDeviceFilter (desc.numOutputChannels);
return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);
}
else if (desc.name == midiInDesc.name)
{
return new MidiInputDeviceFilter();
return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);
}
return 0;


+ 1
- 1
extras/audio plugin host/src/host/InternalFilters.h View File

@@ -33,7 +33,7 @@
#define __JUCE_MAINHOSTWINDOW_JUCEHEADER__xxxxx
#include "FilterGraph.h"
#include "../plugins/juce_AudioPluginFormat.h"
//==============================================================================
/**


+ 8
- 8
extras/audio plugin host/src/host/MainHostWindow.cpp View File

@@ -32,7 +32,7 @@
#include "../../../../juce.h"
#include "MainHostWindow.h"
#include "InternalFilters.h"
#include "../plugins/juce_PluginListComponent.h"
//==============================================================================
class PluginListWindow : public DocumentWindow
@@ -85,6 +85,13 @@ MainHostWindow::MainHostWindow()
: DocumentWindow (JUCEApplication::getInstance()->getApplicationName(), Colours::lightgrey,
DocumentWindow::allButtons)
{
XmlElement* const savedAudioState = ApplicationProperties::getInstance()->getUserSettings()
->getXmlValue (T("audioDeviceState"));
deviceManager.initialise (256, 256, savedAudioState, true);
delete savedAudioState;
setResizable (true, false);
setResizeLimits (500, 400, 10000, 10000);
centreWithSize (800, 600);
@@ -104,13 +111,6 @@ MainHostWindow::MainHostWindow()
InternalPluginFormat internalFormat;
internalFormat.getAllTypes (internalTypes);
XmlElement* const savedAudioState = ApplicationProperties::getInstance()->getUserSettings()
->getXmlValue (T("audioDeviceState"));
deviceManager.initialise (256, 256, savedAudioState, true);
delete savedAudioState;
XmlElement* const savedPluginList = ApplicationProperties::getInstance()
->getUserSettings()
->getXmlValue (T("pluginList"));


+ 0
- 1
extras/audio plugin host/src/host/MainHostWindow.h View File

@@ -34,7 +34,6 @@
#include "FilterGraph.h"
#include "GraphEditorPanel.h"
#include "../plugins/juce_KnownPluginList.h"
//==============================================================================


+ 1281
- 1269
extras/audio plugin host/src/plugins/formats/juce_AudioUnitPluginFormat.cpp
File diff suppressed because it is too large
View File


+ 3008
- 2998
extras/audio plugin host/src/plugins/formats/juce_VSTPluginFormat.cpp
File diff suppressed because it is too large
View File


+ 24
- 0
extras/audio plugin host/src/plugins/juce_AudioPluginFormat.cpp View File

@@ -105,3 +105,27 @@ void AudioPluginFormatManager::addFormat (AudioPluginFormat* const format) throw
{
formats.add (format);
}
AudioPluginInstance* AudioPluginFormatManager::createInstance (const PluginDescription& description,
String& errorMessage) const
{
AudioPluginInstance* result = 0;
for (int i = 0; i < formats.size(); ++i)
{
result = formats.getUnchecked(i)->createInstanceFromDescription (*this);
if (result != 0)
break;
}
if (result == 0)
{
if (file != File::nonexistent && ! file.exists())
errorMessage = TRANS ("This plug-in file no longer exists");
else
errorMessage = TRANS ("This plug-in failed to load correctly");
}
return result;
}

+ 13
- 0
extras/audio plugin host/src/plugins/juce_AudioPluginFormat.h View File

@@ -146,6 +146,19 @@ public:
*/
void addFormat (AudioPluginFormat* const format) throw();
//==============================================================================
/** Tries to load the type for this description, by trying all the formats
that this manager knows about.
The caller is responsible for deleting the object that is returned.
If it can't load the plugin, it returns 0 and leaves a message in the
errorMessage string.
*/
AudioPluginInstance* createInstance (const PluginDescription& description,
String& errorMessage) const;
//==============================================================================
juce_UseDebuggingNewOperator


+ 10
- 1
extras/audio plugin host/src/plugins/juce_KnownPluginList.cpp View File

@@ -60,6 +60,15 @@ PluginDescription* KnownPluginList::getTypeForFile (const File& file) const thro
return 0;
}
PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const throw()
{
for (int i = 0; i < types.size(); ++i)
if (types.getUnchecked(i)->createIdentifierString() == identifierString)
return types.getUnchecked(i);
return 0;
}
bool KnownPluginList::addType (const PluginDescription& type)
{
for (int i = types.size(); --i >= 0;)
@@ -341,7 +350,7 @@ public:
{
PluginDescription* const plugin = plugins.getUnchecked(i);
m.addItem (allPlugins.indexOf (plugin) + menuIdBase,
m.addItem (allPlugins.indexOf (plugin) + menuIdBase,
plugin->name, true, false);
}
}


+ 7
- 0
extras/audio plugin host/src/plugins/juce_KnownPluginList.h View File

@@ -74,6 +74,13 @@ public:
*/
PluginDescription* getTypeForFile (const File& file) const throw();
/** Looks for a type in the list which matches a plugin type ID.
The identifierString parameter must have been created by
PluginDescription::createIdentifierString().
*/
PluginDescription* getTypeForIdentifierString (const String& identifierString) const throw();
/** Adds a type manually from its description. */
bool addType (const PluginDescription& type);


+ 4
- 37
extras/audio plugin host/src/plugins/juce_PluginDescription.cpp View File

@@ -85,44 +85,11 @@ bool PluginDescription::isDuplicateOf (const PluginDescription& other) const
&& uid == other.uid;
}
void PluginDescription::fillInFromInstance (AudioPluginInstance& instance) throw()
const String PluginDescription::createIdentifierString() const throw()
{
name = instance.getName();
file = instance.getFile();
uid = instance.getUID();
lastFileModTime = file.getLastModificationTime();
pluginFormatName = instance.getFormatName();
category = instance.getCategory();
manufacturerName = instance.getManufacturer();
version = instance.getVersion();
numInputChannels = instance.getNumInputChannels();
numOutputChannels = instance.getNumOutputChannels();
isInstrument = instance.isInstrument();
}
AudioPluginInstance* PluginDescription::createInstance (String& errorMessage) const
{
AudioPluginInstance* result = 0;
for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i)
{
AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i);
result = format->createInstanceFromDescription (*this);
if (result != 0)
break;
}
if (result == 0)
{
if (file != File::nonexistent && ! file.exists())
errorMessage = TRANS ("This plug-in file no longer exists");
else
errorMessage = TRANS ("This plug-in failed to load correctly");
}
return result;
return pluginFormatName
+ T("/") + pluginName
+ T("/") + String::toHexString (file.getFileName().hashCode());
}
XmlElement* PluginDescription::createXml() const


+ 12
- 11
extras/audio plugin host/src/plugins/juce_PluginDescription.h View File

@@ -85,6 +85,8 @@ public:
Note that this might not be unique between formats, e.g. a VST and some
other format might actually have the same id.
@see createIdentifierString
*/
int uid;
@@ -111,17 +113,6 @@ public:
*/
void fillInFromInstance (AudioPluginInstance& instance) throw();
//==============================================================================
/** Tries to load the type for this description, by trying all the formats
available in the AudioPluginFormat.
The caller is responsible for deleting the object that is returned.
If it can't load the plugin, it returns 0 and leaves a message in the
errorMessage string.
*/
AudioPluginInstance* createInstance (String& errorMessage) const;
//==============================================================================
/** Creates an XML object containing these details.
@@ -136,6 +127,16 @@ public:
*/
bool loadFromXml (const XmlElement& xml);
//==============================================================================
/** Returns a string that can be saved and used to uniquely identify the
plugin again.
This contains less info than the XML encoding, and is independent of the
plugin's file location, so can be used to store a plugin ID for use
across different machines.
*/
const String createIdentifierString() const throw();
//==============================================================================
juce_UseDebuggingNewOperator


+ 10
- 0
extras/audio plugins/demo/src/DemoJuceFilter.cpp View File

@@ -124,6 +124,16 @@ bool DemoJuceFilter::isOutputChannelStereoPair (int index) const
return false;
}
bool DemoJuceFilter::acceptsMidi() const
{
return true;
}
bool DemoJuceFilter::producesMidi() const
{
return true;
}
//==============================================================================
void DemoJuceFilter::prepareToPlay (double sampleRate, int samplesPerBlock)
{


+ 3
- 0
extras/audio plugins/demo/src/DemoJuceFilter.h View File

@@ -71,6 +71,9 @@ public:
bool isInputChannelStereoPair (int index) const;
bool isOutputChannelStereoPair (int index) const;
bool acceptsMidi() const;
bool producesMidi() const;
//==============================================================================
int getNumPrograms() { return 0; }
int getCurrentProgram() { return 0; }


+ 3
- 4
extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.cpp View File

@@ -101,15 +101,14 @@ void AudioFilterStreamer::audioDeviceIOCallback (const float** inputChannelData,
zeromem (outChans[numOutsWanted++], sizeof (float) * numSamples);
}
void AudioFilterStreamer::audioDeviceAboutToStart (double sampleRate_,
int numSamplesPerBlock)
void AudioFilterStreamer::audioDeviceAboutToStart (AudioIODevice* device)
{
sampleRate = sampleRate_;
sampleRate = device->getCurrentSampleRate();
isPlaying = true;
emptyBuffer.setSize (1 + filter.getNumOutputChannels(),
jmax (2048, numSamplesPerBlock * 2));
jmax (2048, device->getCurrentBlockSizeSamples() * 2));
emptyBuffer.clear();
midiCollector.reset (sampleRate);


+ 1
- 1
extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.h View File

@@ -66,7 +66,7 @@ public:
int totalNumOutputChannels,
int numSamples);
void audioDeviceAboutToStart (double sampleRate, int numSamplesPerBlock);
void audioDeviceAboutToStart (AudioIODevice* device);
void audioDeviceStopped();
void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message);


+ 6
- 6
extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj View File

@@ -32,7 +32,7 @@
84EAE2F309DAAF0B00288D0A /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84EAE2F109DAAF0B00288D0A /* AGL.framework */; };
84EAE2F409DAAF0B00288D0A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84EAE2F209DAAF0B00288D0A /* OpenGL.framework */; };
84F8DB0B099CA8DD00E911ED /* QuickTimeDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F8DB0A099CA8DD00E911ED /* QuickTimeDemo.cpp */; };
84FDB0950C15BDDD00CD0087 /* libjucedebug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FDB0940C15BDCE00CD0087 /* libjucedebug.a */; };
84FDB0950C15BDDD00CD0087 /* libjuce.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FDB0940C15BDCE00CD0087 /* libjuce.a */; };
8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; };
8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
/* End PBXBuildFile section */
@@ -77,7 +77,7 @@
84EAE2F909DAAF2F00288D0A /* Juce.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Juce.xcodeproj; path = ../../../../build/macosx/Juce.xcodeproj; sourceTree = SOURCE_ROOT; };
84F8DB0A099CA8DD00E911ED /* QuickTimeDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = QuickTimeDemo.cpp; sourceTree = "<group>"; };
8D0C4E960486CD37000505A6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8D0C4E970486CD37000505A6 /* jucedemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = jucedemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
8D0C4E970486CD37000505A6 /* jucedemo.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = jucedemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
@@ -85,7 +85,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84FDB0950C15BDDD00CD0087 /* libjucedebug.a in Frameworks */,
84FDB0950C15BDDD00CD0087 /* libjuce.a in Frameworks */,
8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */,
84C49F2606C0F3200066071B /* CoreAudio.framework in Frameworks */,
84C4A41106C0F9A00066071B /* IOKit.framework in Frameworks */,
@@ -181,7 +181,7 @@
84FDB0900C15BDCE00CD0087 /* Products */ = {
isa = PBXGroup;
children = (
84FDB0940C15BDCE00CD0087 /* libjucedebug.a */,
84FDB0940C15BDCE00CD0087 /* libjuce.a */,
);
name = Products;
sourceTree = "<group>";
@@ -244,10 +244,10 @@
/* End PBXProject section */

/* Begin PBXReferenceProxy section */
84FDB0940C15BDCE00CD0087 /* libjucedebug.a */ = {
84FDB0940C15BDCE00CD0087 /* libjuce.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libjucedebug.a;
path = libjuce.a;
remoteRef = 84FDB0930C15BDCE00CD0087 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};


+ 58
- 56
extras/juce demo/src/BinaryData.cpp View File

@@ -2022,68 +2022,70 @@ static const unsigned char temp4[] = {47,42,13,10,32,32,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,32,32,98,
111,111,108,32,105,115,73,110,116,101,114,101,115,116,101,100,73,110,68,114,97,103,83,111,117,114,99,101,32,40,99,111,110,115,116,32,83,116,114,105,
110,103,38,32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,47,
47,32,110,111,114,109,97,108,108,121,32,121,111,117,39,100,32,99,104,101,99,107,32,116,104,101,32,115,111,117,114,99,101,68,101,115,99,114,105,112,
116,105,111,110,32,118,97,108,117,101,32,116,111,32,115,101,101,32,105,102,32,105,116,39,115,32,116,104,101,13,10,32,32,32,32,32,32,32,32,47,
47,32,115,111,114,116,32,111,102,32,111,98,106,101,99,116,32,116,104,97,116,32,121,111,117,39,114,101,32,105,110,116,101,114,101,115,116,101,100,32,
105,110,32,98,101,102,111,114,101,32,114,101,116,117,114,110,105,110,103,32,116,114,117,101,44,32,98,117,116,32,102,111,114,13,10,32,32,32,32,32,
32,32,32,47,47,32,116,104,101,32,100,101,109,111,44,32,119,101,39,108,108,32,115,97,121,32,121,101,115,32,116,111,32,97,110,121,116,104,105,110,
103,46,46,13,10,32,32,32,32,32,32,32,32,114,101,116,117,114,110,32,116,114,117,101,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,
118,111,105,100,32,105,116,101,109,68,114,97,103,69,110,116,101,114,32,40,99,111,110,115,116,32,83,116,114,105,110,103,38,32,115,111,117,114,99,101,
68,101,115,99,114,105,112,116,105,111,110,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,67,111,
109,112,111,110,101,110,116,42,32,115,111,117,114,99,101,67,111,109,112,111,110,101,110,116,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,32,32,32,32,105,110,116,32,120,44,32,105,110,116,32,121,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,
32,115,111,109,101,116,104,105,110,103,73,115,66,101,105,110,103,68,114,97,103,103,101,100,79,118,101,114,32,61,32,116,114,117,101,59,13,10,32,32,
32,32,32,32,32,32,114,101,112,97,105,110,116,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,105,116,101,109,
68,114,97,103,77,111,118,101,32,40,99,111,110,115,116,32,83,116,114,105,110,103,38,32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,
110,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,67,111,109,112,111,110,101,110,116,42,32,115,111,
117,114,99,101,67,111,109,112,111,110,101,110,116,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,
110,116,32,120,44,32,105,110,116,32,121,41,13,10,32,32,32,32,123,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,105,
116,101,109,68,114,97,103,69,120,105,116,32,40,99,111,110,115,116,32,83,116,114,105,110,103,38,32,115,111,117,114,99,101,68,101,115,99,114,105,112,
116,105,111,110,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,67,111,109,112,111,110,101,110,116,42,
32,115,111,117,114,99,101,67,111,109,112,111,110,101,110,116,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,115,111,109,101,116,104,
105,110,103,73,115,66,101,105,110,103,68,114,97,103,103,101,100,79,118,101,114,32,61,32,102,97,108,115,101,59,13,10,32,32,32,32,32,32,32,32,
114,101,112,97,105,110,116,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,105,116,101,109,68,114,111,112,112,101,
100,32,40,99,111,110,115,116,32,83,116,114,105,110,103,38,32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,44,13,10,32,32,32,
110,103,38,32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,67,111,109,112,111,110,101,110,116,42,32,115,111,117,114,99,101,67,111,109,112,
111,110,101,110,116,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,110,116,32,120,44,32,105,110,116,
32,121,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,109,101,115,115,97,103,101,32,61,32,84,40,34,108,97,115,116,32,114,111,
119,115,32,100,114,111,112,112,101,100,58,32,34,41,32,43,32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,59,13,10,13,10,32,
32,32,32,32,32,32,32,115,111,109,101,116,104,105,110,103,73,115,66,101,105,110,103,68,114,97,103,103,101,100,79,118,101,114,32,61,32,102,97,108,
115,101,59,13,10,32,32,32,32,32,32,32,32,114,101,112,97,105,110,116,40,41,59,13,10,32,32,32,32,125,13,10,125,59,13,10,13,10,13,10,
47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
111,110,101,110,116,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,47,47,32,110,111,114,109,97,108,108,121,32,121,111,117,39,100,
32,99,104,101,99,107,32,116,104,101,32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,32,118,97,108,117,101,32,116,111,32,115,101,
101,32,105,102,32,105,116,39,115,32,116,104,101,13,10,32,32,32,32,32,32,32,32,47,47,32,115,111,114,116,32,111,102,32,111,98,106,101,99,116,
32,116,104,97,116,32,121,111,117,39,114,101,32,105,110,116,101,114,101,115,116,101,100,32,105,110,32,98,101,102,111,114,101,32,114,101,116,117,114,110,
105,110,103,32,116,114,117,101,44,32,98,117,116,32,102,111,114,13,10,32,32,32,32,32,32,32,32,47,47,32,116,104,101,32,100,101,109,111,44,32,
119,101,39,108,108,32,115,97,121,32,121,101,115,32,116,111,32,97,110,121,116,104,105,110,103,46,46,13,10,32,32,32,32,32,32,32,32,114,101,116,
117,114,110,32,116,114,117,101,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,105,116,101,109,68,114,97,103,69,110,116,
101,114,32,40,99,111,110,115,116,32,83,116,114,105,110,103,38,32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,44,13,10,32,32,
32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,67,111,109,112,111,110,101,110,116,42,32,115,111,117,114,99,101,67,
111,109,112,111,110,101,110,116,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,110,116,32,120,
44,32,105,110,116,32,121,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,115,111,109,101,116,104,105,110,103,73,115,66,101,105,110,
103,68,114,97,103,103,101,100,79,118,101,114,32,61,32,116,114,117,101,59,13,10,32,32,32,32,32,32,32,32,114,101,112,97,105,110,116,40,41,59,
13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,105,116,101,109,68,114,97,103,77,111,118,101,32,40,99,111,110,115,116,32,
83,116,114,105,110,103,38,32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,32,32,32,32,67,111,109,112,111,110,101,110,116,42,32,115,111,117,114,99,101,67,111,109,112,111,110,101,110,116,44,13,10,
32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,110,116,32,120,44,32,105,110,116,32,121,41,13,10,32,32,
32,32,123,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,105,116,101,109,68,114,97,103,69,120,105,116,32,40,99,111,110,
115,116,32,83,116,114,105,110,103,38,32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,44,13,10,32,32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,32,32,32,32,32,32,32,67,111,109,112,111,110,101,110,116,42,32,115,111,117,114,99,101,67,111,109,112,111,110,101,110,116,
41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,115,111,109,101,116,104,105,110,103,73,115,66,101,105,110,103,68,114,97,103,103,101,
100,79,118,101,114,32,61,32,102,97,108,115,101,59,13,10,32,32,32,32,32,32,32,32,114,101,112,97,105,110,116,40,41,59,13,10,32,32,32,32,
125,13,10,13,10,32,32,32,32,118,111,105,100,32,105,116,101,109,68,114,111,112,112,101,100,32,40,99,111,110,115,116,32,83,116,114,105,110,103,38,
32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
32,32,32,67,111,109,112,111,110,101,110,116,42,32,115,111,117,114,99,101,67,111,109,112,111,110,101,110,116,44,13,10,32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,32,32,32,32,32,32,32,105,110,116,32,120,44,32,105,110,116,32,121,41,13,10,32,32,32,32,123,13,10,32,32,32,32,
32,32,32,32,109,101,115,115,97,103,101,32,61,32,84,40,34,108,97,115,116,32,114,111,119,115,32,100,114,111,112,112,101,100,58,32,34,41,32,43,
32,115,111,117,114,99,101,68,101,115,99,114,105,112,116,105,111,110,59,13,10,13,10,32,32,32,32,32,32,32,32,115,111,109,101,116,104,105,110,103,
73,115,66,101,105,110,103,68,114,97,103,103,101,100,79,118,101,114,32,61,32,102,97,108,115,101,59,13,10,32,32,32,32,32,32,32,32,114,101,112,
97,105,110,116,40,41,59,13,10,32,32,32,32,125,13,10,125,59,13,10,13,10,13,10,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
13,10,99,108,97,115,115,32,68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,32,32,58,32,112,117,98,108,105,99,32,67,111,109,112,111,110,
101,110,116,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,112,117,98,108,105,99,32,68,114,
97,103,65,110,100,68,114,111,112,67,111,110,116,97,105,110,101,114,13,10,123,13,10,32,32,32,32,47,47,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,99,108,97,115,115,32,68,114,97,103,65,110,100,68,
114,111,112,68,101,109,111,32,32,58,32,112,117,98,108,105,99,32,67,111,109,112,111,110,101,110,116,44,13,10,32,32,32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,112,117,98,108,105,99,32,68,114,97,103,65,110,100,68,114,111,112,67,111,110,116,97,105,110,
101,114,13,10,123,13,10,32,32,32,32,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,32,32,68,114,97,103,65,110,100,
68,114,111,112,68,101,109,111,83,111,117,114,99,101,42,32,115,111,117,114,99,101,59,13,10,32,32,32,32,68,114,97,103,65,110,100,68,114,111,112,
68,101,109,111,84,97,114,103,101,116,42,32,116,97,114,103,101,116,59,13,10,13,10,112,117,98,108,105,99,58,13,10,32,32,32,32,47,47,61,61,
61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,32,32,68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,83,111,117,114,99,101,42,32,
115,111,117,114,99,101,59,13,10,32,32,32,32,68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,84,97,114,103,101,116,42,32,116,97,114,103,
101,116,59,13,10,13,10,112,117,98,108,105,99,58,13,10,32,32,32,32,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,
32,32,68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,115,101,116,78,
97,109,101,32,40,84,40,34,68,114,97,103,45,97,110,100,45,68,114,111,112,34,41,41,59,13,10,13,10,32,32,32,32,32,32,32,32,115,111,117,
114,99,101,32,61,32,110,101,119,32,68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,83,111,117,114,99,101,40,41,59,13,10,32,32,32,32,
32,32,32,32,97,100,100,65,110,100,77,97,107,101,86,105,115,105,98,108,101,32,40,115,111,117,114,99,101,41,59,13,10,13,10,32,32,32,32,32,
32,32,32,116,97,114,103,101,116,32,61,32,110,101,119,32,68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,84,97,114,103,101,116,40,41,59,
13,10,32,32,32,32,32,32,32,32,97,100,100,65,110,100,77,97,107,101,86,105,115,105,98,108,101,32,40,116,97,114,103,101,116,41,59,13,10,32,
32,32,32,125,13,10,13,10,32,32,32,32,126,68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,40,41,13,10,32,32,32,32,123,13,10,32,
32,32,32,32,32,32,32,100,101,108,101,116,101,65,108,108,67,104,105,108,100,114,101,110,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,
32,32,118,111,105,100,32,114,101,115,105,122,101,100,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,115,111,117,114,99,101,45,
62,115,101,116,66,111,117,110,100,115,32,40,49,48,44,32,49,48,44,32,50,53,48,44,32,49,53,48,41,59,13,10,32,32,32,32,32,32,32,32,
116,97,114,103,101,116,45,62,115,101,116,66,111,117,110,100,115,32,40,103,101,116,87,105,100,116,104,40,41,32,45,32,50,54,48,44,32,103,101,116,
72,101,105,103,104,116,40,41,32,45,32,49,54,48,44,32,50,53,48,44,32,49,53,48,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,
32,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,32,32,68,114,97,103,65,110,100,68,114,111,112,68,101,109,
111,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,115,101,116,78,97,109,101,32,40,84,40,34,68,114,97,103,45,97,110,100,
45,68,114,111,112,34,41,41,59,13,10,13,10,32,32,32,32,32,32,32,32,115,111,117,114,99,101,32,61,32,110,101,119,32,68,114,97,103,65,110,
100,68,114,111,112,68,101,109,111,83,111,117,114,99,101,40,41,59,13,10,32,32,32,32,32,32,32,32,97,100,100,65,110,100,77,97,107,101,86,105,
115,105,98,108,101,32,40,115,111,117,114,99,101,41,59,13,10,13,10,32,32,32,32,32,32,32,32,116,97,114,103,101,116,32,61,32,110,101,119,32,
68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,84,97,114,103,101,116,40,41,59,13,10,32,32,32,32,32,32,32,32,97,100,100,65,110,100,
77,97,107,101,86,105,115,105,98,108,101,32,40,116,97,114,103,101,116,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,126,68,114,97,
103,65,110,100,68,114,111,112,68,101,109,111,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,100,101,108,101,116,101,65,108,108,
67,104,105,108,100,114,101,110,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,114,101,115,105,122,101,100,40,41,
13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,115,111,117,114,99,101,45,62,115,101,116,66,111,117,110,100,115,32,40,49,48,44,32,
49,48,44,32,50,53,48,44,32,49,53,48,41,59,13,10,32,32,32,32,32,32,32,32,116,97,114,103,101,116,45,62,115,101,116,66,111,117,110,100,
115,32,40,103,101,116,87,105,100,116,104,40,41,32,45,32,50,54,48,44,32,103,101,116,72,101,105,103,104,116,40,41,32,45,32,49,54,48,44,32,
50,53,48,44,32,49,53,48,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,13,10,32,32,32,32,47,47,32,40,110,101,101,100,32,116,111,32,112,117,116,32,116,104,105,115,32,105,110,32,116,111,32,100,105,115,97,109,98,
105,103,117,97,116,101,32,116,104,101,32,110,101,119,47,100,101,108,101,116,101,32,111,112,101,114,97,116,111,114,115,32,117,115,101,100,32,105,110,32,
116,104,101,13,10,32,32,32,32,47,47,32,116,119,111,32,98,97,115,101,32,99,108,97,115,115,101,115,41,46,13,10,32,32,32,32,106,117,99,101,
95,85,115,101,68,101,98,117,103,103,105,110,103,78,101,119,79,112,101,114,97,116,111,114,13,10,125,59,13,10,13,10,13,10,47,47,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,32,32,47,47,32,40,110,101,101,100,32,
116,111,32,112,117,116,32,116,104,105,115,32,105,110,32,116,111,32,100,105,115,97,109,98,105,103,117,97,116,101,32,116,104,101,32,110,101,119,47,100,
101,108,101,116,101,32,111,112,101,114,97,116,111,114,115,32,117,115,101,100,32,105,110,32,116,104,101,13,10,32,32,32,32,47,47,32,116,119,111,32,
98,97,115,101,32,99,108,97,115,115,101,115,41,46,13,10,32,32,32,32,106,117,99,101,95,85,115,101,68,101,98,117,103,103,105,110,103,78,101,119,
79,112,101,114,97,116,111,114,13,10,125,59,13,10,13,10,13,10,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,67,111,109,112,
111,110,101,110,116,42,32,99,114,101,97,116,101,68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,40,41,13,10,123,13,10,32,32,32,32,114,
101,116,117,114,110,32,110,101,119,32,68,114,97,103,65,110,100,68,114,111,112,68,101,109,111,40,41,59,13,10,125,13,10,0,0};
61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,67,111,109,112,111,110,101,110,116,42,32,99,114,101,97,116,101,68,114,97,
103,65,110,100,68,114,111,112,68,101,109,111,40,41,13,10,123,13,10,32,32,32,32,114,101,116,117,114,110,32,110,101,119,32,68,114,97,103,65,110,
100,68,114,111,112,68,101,109,111,40,41,59,13,10,125,13,10,0,0};
const char* BinaryData::draganddropdemo_cpp = (const char*) temp4;
static const unsigned char temp5[] = {47,42,13,10,32,32,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,


+ 1
- 1
extras/juce demo/src/BinaryData.h View File

@@ -15,7 +15,7 @@ namespace BinaryData
const int demo_table_data_xmlSize = 5239;
extern const char* draganddropdemo_cpp;
const int draganddropdemo_cppSize = 7873;
const int draganddropdemo_cppSize = 7937;
extern const char* fontsandtextdemo_cpp;
const int fontsandtextdemo_cppSize = 9064;


+ 4
- 4
extras/juce demo/src/binarydata/AudioDemo.cpp View File

@@ -342,7 +342,7 @@ public:
}
}
void audioDeviceAboutToStart (double sampleRate, int numSamplesPerBlock)
void audioDeviceAboutToStart (AudioIODevice*)
{
zeromem (circularBuffer, sizeof (float) * bufferSize);
}
@@ -504,10 +504,10 @@ public:
waveformComponent->audioDeviceIOCallback (inputChannelData, totalNumInputChannels, outputChannelData, totalNumOutputChannels, numSamples);
}
void audioDeviceAboutToStart (double sampleRate, int numSamplesPerBlock)
void audioDeviceAboutToStart (AudioIODevice* device)
{
audioSourcePlayer.audioDeviceAboutToStart (sampleRate, numSamplesPerBlock);
waveformComponent->audioDeviceAboutToStart (sampleRate, numSamplesPerBlock);
audioSourcePlayer.audioDeviceAboutToStart (device);
waveformComponent->audioDeviceAboutToStart (device);
}
void audioDeviceStopped()


+ 2
- 1
extras/juce demo/src/binarydata/DragAndDropDemo.cpp View File

@@ -152,7 +152,8 @@ public:
}
//==============================================================================
bool isInterestedInDragSource (const String& sourceDescription)
bool isInterestedInDragSource (const String& sourceDescription,
Component* sourceComponent)
{
// normally you'd check the sourceDescription value to see if it's the
// sort of object that you're interested in before returning true, but for


+ 4
- 4
extras/juce demo/src/demos/AudioDemo.cpp View File

@@ -342,7 +342,7 @@ public:
}
}
void audioDeviceAboutToStart (double sampleRate, int numSamplesPerBlock)
void audioDeviceAboutToStart (AudioIODevice*)
{
zeromem (circularBuffer, sizeof (float) * bufferSize);
}
@@ -504,10 +504,10 @@ public:
waveformComponent->audioDeviceIOCallback (inputChannelData, totalNumInputChannels, outputChannelData, totalNumOutputChannels, numSamples);
}
void audioDeviceAboutToStart (double sampleRate, int numSamplesPerBlock)
void audioDeviceAboutToStart (AudioIODevice* device)
{
audioSourcePlayer.audioDeviceAboutToStart (sampleRate, numSamplesPerBlock);
waveformComponent->audioDeviceAboutToStart (sampleRate, numSamplesPerBlock);
audioSourcePlayer.audioDeviceAboutToStart (device);
waveformComponent->audioDeviceAboutToStart (device);
}
void audioDeviceStopped()


+ 2
- 1
extras/juce demo/src/demos/DragAndDropDemo.cpp View File

@@ -152,7 +152,8 @@ public:
}
//==============================================================================
bool isInterestedInDragSource (const String& sourceDescription)
bool isInterestedInDragSource (const String& sourceDescription,
Component* sourceComponent)
{
// normally you'd check the sourceDescription value to see if it's the
// sort of object that you're interested in before returning true, but for


+ 1
- 0
juce.h View File

@@ -169,6 +169,7 @@ END_JUCE_NAMESPACE
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "SetupAPI.Lib")
//#pragma comment(lib, "gdiplus.lib")
#if JUCE_OPENGL


+ 10
- 0
juce_Config.h View File

@@ -137,6 +137,16 @@
#define JUCE_USE_XSHM 1
#endif
//=============================================================================
/** Enabling this builds support for VST audio plugins.
@see VSTPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_AU
*/
#define JUCE_PLUGINHOST_VST 1
/** Enabling this builds support for AudioUnit audio plugins.
@see AudioUnitPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_VST
*/
#define JUCE_PLUGINHOST_AU 1
//=============================================================================
/** Disabling this will avoid linking to any UI code. This is handy for


+ 39
- 0
src/juce_app_includes.h View File

@@ -95,9 +95,15 @@
#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__
#include "juce_appframework/audio/processors/juce_AudioProcessorEditor.h"
#endif
#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__
#include "juce_appframework/audio/processors/juce_AudioProcessorGraph.h"
#endif
#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__
#include "juce_appframework/audio/processors/juce_AudioProcessorListener.h"
#endif
#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__
#include "juce_appframework/audio/processors/juce_AudioProcessorPlayer.h"
#endif
#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__
#include "juce_appframework/audio/processors/juce_GenericAudioProcessorEditor.h"
#endif
@@ -155,6 +161,39 @@
#ifndef __JUCE_SYNTHESISER_JUCEHEADER__
#include "juce_appframework/audio/synthesisers/juce_Synthesiser.h"
#endif
#ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__
#include "juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.h"
#endif
#ifndef __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__
#include "juce_appframework/audio/plugins/formats/juce_DirectXPluginFormat.h"
#endif
#ifndef __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
#include "juce_appframework/audio/plugins/formats/juce_LADSPAPluginFormat.h"
#endif
#ifndef __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
#include "juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h"
#endif
#ifndef __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__
#include "juce_appframework/audio/plugins/juce_AudioPluginFormat.h"
#endif
#ifndef __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__
#include "juce_appframework/audio/plugins/juce_AudioPluginFormatManager.h"
#endif
#ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__
#include "juce_appframework/audio/plugins/juce_AudioPluginInstance.h"
#endif
#ifndef __JUCE_KNOWNPLUGINLIST_JUCEHEADER__
#include "juce_appframework/audio/plugins/juce_KnownPluginList.h"
#endif
#ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__
#include "juce_appframework/audio/plugins/juce_PluginDescription.h"
#endif
#ifndef __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__
#include "juce_appframework/audio/plugins/juce_PluginDirectoryScanner.h"
#endif
#ifndef __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
#include "juce_appframework/audio/plugins/juce_PluginListComponent.h"
#endif
#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__
#include "juce_appframework/audio/audio_file_formats/juce_AiffAudioFormat.h"
#endif


+ 1284
- 0
src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.cpp
File diff suppressed because it is too large
View File


+ 67
- 0
src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.h View File

@@ -0,0 +1,67 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__
#define __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__
#include "../juce_AudioPluginFormat.h"
#if JUCE_PLUGINHOST_AU && JUCE_MAC
//==============================================================================
/**
Implements a plugin format manager for AudioUnits.
*/
class JUCE_API AudioUnitPluginFormat : public AudioPluginFormat
{
public:
//==============================================================================
AudioUnitPluginFormat();
~AudioUnitPluginFormat();
//==============================================================================
const String getName() const { return "AudioUnit"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
const FileSearchPath getDefaultLocationsToSearch();
//==============================================================================
juce_UseDebuggingNewOperator
private:
AudioUnitPluginFormat (const AudioUnitPluginFormat&);
const AudioUnitPluginFormat& operator= (const AudioUnitPluginFormat&);
};
#endif
#endif // __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__

+ 71
- 0
src/juce_appframework/audio/plugins/formats/juce_DirectXPluginFormat.h View File

@@ -0,0 +1,71 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__
#define __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__
#include "../juce_AudioPluginFormat.h"
#if JUCE_PLUGINHOST_DX && JUCE_WIN32
// Sorry, this file is just a placeholder at the moment!...
//==============================================================================
/**
Implements a plugin format manager for DirectX plugins.
*/
class JUCE_API DirectXPluginFormat : public AudioPluginFormat
{
public:
//==============================================================================
DirectXPluginFormat();
~DirectXPluginFormat();
//==============================================================================
const String getName() const { return "DirectX"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
const FileSearchPath getDefaultLocationsToSearch();
//==============================================================================
juce_UseDebuggingNewOperator
private:
DirectXPluginFormat (const DirectXPluginFormat&);
const DirectXPluginFormat& operator= (const DirectXPluginFormat&);
};
#endif
#endif // __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__

+ 71
- 0
src/juce_appframework/audio/plugins/formats/juce_LADSPAPluginFormat.h View File

@@ -0,0 +1,71 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
#define __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
#include "../juce_AudioPluginFormat.h"
#if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX
// Sorry, this file is just a placeholder at the moment!...
//==============================================================================
/**
Implements a plugin format manager for DirectX plugins.
*/
class JUCE_API LADSPAPluginFormat : public AudioPluginFormat
{
public:
//==============================================================================
LADSPAPluginFormat();
~LADSPAPluginFormat();
//==============================================================================
const String getName() const { return "LADSPA"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
const FileSearchPath getDefaultLocationsToSearch();
//==============================================================================
juce_UseDebuggingNewOperator
private:
LADSPAPluginFormat (const LADSPAPluginFormat&);
const LADSPAPluginFormat& operator= (const LADSPAPluginFormat&);
};
#endif
#endif // __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__

+ 3017
- 0
src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp
File diff suppressed because it is too large
View File


+ 68
- 0
src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h View File

@@ -0,0 +1,68 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
#define __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
#include "../juce_AudioPluginFormat.h"
#if JUCE_PLUGINHOST_VST
//==============================================================================
/**
Implements a plugin format manager for VSTs.
*/
class JUCE_API VSTPluginFormat : public AudioPluginFormat
{
public:
//==============================================================================
VSTPluginFormat();
~VSTPluginFormat();
//==============================================================================
const String getName() const { return "VST"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
const FileSearchPath getDefaultLocationsToSearch();
//==============================================================================
juce_UseDebuggingNewOperator
private:
VSTPluginFormat (const VSTPluginFormat&);
const VSTPluginFormat& operator= (const VSTPluginFormat&);
};
#endif
#endif // __JUCE_VSTPLUGINFORMAT_JUCEHEADER__

+ 49
- 0
src/juce_appframework/audio/plugins/juce_AudioPluginFormat.cpp View File

@@ -0,0 +1,49 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_AudioPluginFormat.h"
//==============================================================================
AudioPluginFormat::AudioPluginFormat() throw()
{
}
AudioPluginFormat::~AudioPluginFormat() throw()
{
}
END_JUCE_NAMESPACE

+ 107
- 0
src/juce_appframework/audio/plugins/juce_AudioPluginFormat.h View File

@@ -0,0 +1,107 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__
#define __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__
#include "juce_AudioPluginInstance.h"
#include "../../../juce_core/io/files/juce_FileSearchPath.h"
class PluginDescription;
//==============================================================================
/**
The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc.
Use the static getNumFormats() and getFormat() calls to find the types
of format that are available.
*/
class JUCE_API AudioPluginFormat
{
public:
//==============================================================================
/** Destructor. */
virtual ~AudioPluginFormat();
//==============================================================================
/** Returns the format name.
E.g. "VST", "AudioUnit", etc.
*/
virtual const String getName() const = 0;
/** This tries to create descriptions for all the plugin types available in
a binary module file.
The file will be some kind of DLL or bundle.
Normally there will only be one type returned, but some plugins
(e.g. VST shells) can use a single DLL to create a set of different plugin
subtypes, so in that case, each subtype is returned as a separate object.
*/
virtual void findAllTypesForFile (OwnedArray <PluginDescription>& results,
const File& file) = 0;
/** Tries to recreate a type from a previously generated PluginDescription.
@see PluginDescription::createInstance
*/
virtual AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc) = 0;
/** Should do a quick check to see if this file or directory might be a plugin of
this format.
This is for searching for potential files, so it shouldn't actually try to
load the plugin or do anything time-consuming.
*/
virtual bool fileMightContainThisPluginType (const File& file) = 0;
/** Returns the typical places to look for this kind of plugin.
Note that if this returns no paths, it means that the format can't be scanned-for
(i.e. it's an internal format that doesn't live in files)
*/
virtual const FileSearchPath getDefaultLocationsToSearch() = 0;
//==============================================================================
juce_UseDebuggingNewOperator
protected:
AudioPluginFormat() throw();
AudioPluginFormat (const AudioPluginFormat&);
const AudioPluginFormat& operator= (const AudioPluginFormat&);
};
#endif // __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__

+ 138
- 0
src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.cpp View File

@@ -0,0 +1,138 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_AudioPluginFormatManager.h"
#include "juce_PluginDescription.h"
#include "../../../juce_core/text/juce_LocalisedStrings.h"
#include "formats/juce_VSTPluginFormat.h"
#include "formats/juce_AudioUnitPluginFormat.h"
#include "formats/juce_DirectXPluginFormat.h"
#include "formats/juce_LADSPAPluginFormat.h"
//==============================================================================
AudioPluginFormatManager::AudioPluginFormatManager() throw()
{
}
AudioPluginFormatManager::~AudioPluginFormatManager() throw()
{
}
juce_ImplementSingleton_SingleThreaded (AudioPluginFormatManager);
//==============================================================================
void AudioPluginFormatManager::addDefaultFormats()
{
#ifdef JUCE_DEBUG
// you should only call this method once!
for (int i = formats.size(); --i >= 0;)
{
#if JUCE_PLUGINHOST_VST
jassert (dynamic_cast <VSTPluginFormat*> (formats[i]) == 0);
#endif
#if JUCE_PLUGINHOST_AU && JUCE_MAC
jassert (dynamic_cast <AudioUnitPluginFormat*> (formats[i]) == 0);
#endif
#if JUCE_PLUGINHOST_DX && JUCE_WIN32
jassert (dynamic_cast <DirectXPluginFormat*> (formats[i]) == 0);
#endif
#if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX
jassert (dynamic_cast <LADSPAPluginFormat*> (formats[i]) == 0);
#endif
}
#endif
#if JUCE_PLUGINHOST_VST
formats.add (new VSTPluginFormat());
#endif
#if JUCE_PLUGINHOST_AU && JUCE_MAC
formats.add (new AudioUnitPluginFormat());
#endif
#if JUCE_PLUGINHOST_DX && JUCE_WIN32
formats.add (new DirectXPluginFormat());
#endif
#if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX
formats.add (new LADSPAPluginFormat());
#endif
}
int AudioPluginFormatManager::getNumFormats() throw()
{
return formats.size();
}
AudioPluginFormat* AudioPluginFormatManager::getFormat (const int index) throw()
{
return formats [index];
}
void AudioPluginFormatManager::addFormat (AudioPluginFormat* const format) throw()
{
formats.add (format);
}
AudioPluginInstance* AudioPluginFormatManager::createPluginInstance (const PluginDescription& description,
String& errorMessage) const
{
AudioPluginInstance* result = 0;
for (int i = 0; i < formats.size(); ++i)
{
result = formats.getUnchecked(i)->createInstanceFromDescription (description);
if (result != 0)
break;
}
if (result == 0)
{
if (description.file != File::nonexistent && ! description.file.exists())
errorMessage = TRANS ("This plug-in file no longer exists");
else
errorMessage = TRANS ("This plug-in failed to load correctly");
}
return result;
}
END_JUCE_NAMESPACE

+ 107
- 0
src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.h View File

@@ -0,0 +1,107 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__
#define __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__
#include "juce_AudioPluginFormat.h"
#include "../../application/juce_DeletedAtShutdown.h"
#include "../../../juce_core/basics/juce_Singleton.h"
//==============================================================================
/**
This maintains a list of known AudioPluginFormats.
@see AudioPluginFormat
*/
class JUCE_API AudioPluginFormatManager : public DeletedAtShutdown
{
public:
//==============================================================================
AudioPluginFormatManager() throw();
/** Destructor. */
~AudioPluginFormatManager() throw();
juce_DeclareSingleton_SingleThreaded (AudioPluginFormatManager, false);
//==============================================================================
/** Adds any formats that it knows about, e.g. VST.
*/
void addDefaultFormats();
//==============================================================================
/** Returns the number of types of format that are available.
Use getFormat() to get one of them.
*/
int getNumFormats() throw();
/** Returns one of the available formats.
@see getNumFormats
*/
AudioPluginFormat* getFormat (const int index) throw();
//==============================================================================
/** Adds a format to the list.
The object passed in will be owned and deleted by the manager.
*/
void addFormat (AudioPluginFormat* const format) throw();
//==============================================================================
/** Tries to load the type for this description, by trying all the formats
that this manager knows about.
The caller is responsible for deleting the object that is returned.
If it can't load the plugin, it returns 0 and leaves a message in the
errorMessage string.
*/
AudioPluginInstance* createPluginInstance (const PluginDescription& description,
String& errorMessage) const;
//==============================================================================
juce_UseDebuggingNewOperator
private:
OwnedArray <AudioPluginFormat> formats;
AudioPluginFormatManager (const AudioPluginFormatManager&);
const AudioPluginFormatManager& operator= (const AudioPluginFormatManager&);
};
#endif // __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__

+ 51
- 0
src/juce_appframework/audio/plugins/juce_AudioPluginInstance.cpp View File

@@ -0,0 +1,51 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#define JUCE_PLUGIN_HOST 1
#include "../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_AudioPluginInstance.h"
//==============================================================================
AudioPluginInstance::AudioPluginInstance()
{
}
AudioPluginInstance::~AudioPluginInstance()
{
}
END_JUCE_NAMESPACE

+ 76
- 0
src/juce_appframework/audio/plugins/juce_AudioPluginInstance.h View File

@@ -0,0 +1,76 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__
#define __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__
#include "../processors/juce_AudioProcessor.h"
#include "juce_PluginDescription.h"
//==============================================================================
/**
Base class for an active instance of a plugin.
This derives from the AudioProcessor class, and adds some extra functionality
that helps when wrapping dynamically loaded plugins.
@see AudioProcessor, AudioPluginFormat
*/
class JUCE_API AudioPluginInstance : public AudioProcessor
{
public:
//==============================================================================
/** Destructor.
Make sure that you delete any UI components that belong to this plugin before
deleting the plugin.
*/
virtual ~AudioPluginInstance();
//==============================================================================
/** Fills-in the appropriate parts of this plugin description object.
*/
virtual void fillInPluginDescription (PluginDescription& description) const = 0;
//==============================================================================
juce_UseDebuggingNewOperator
protected:
AudioPluginInstance();
AudioPluginInstance (const AudioPluginInstance&);
const AudioPluginInstance& operator= (const AudioPluginInstance&);
};
#endif // __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__

+ 431
- 0
src/juce_appframework/audio/plugins/juce_KnownPluginList.cpp View File

@@ -0,0 +1,431 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_KnownPluginList.h"
#include "juce_AudioPluginFormatManager.h"
//==============================================================================
KnownPluginList::KnownPluginList()
{
}
KnownPluginList::~KnownPluginList()
{
}
void KnownPluginList::clear()
{
if (types.size() > 0)
{
types.clear();
sendChangeMessage (this);
}
}
PluginDescription* KnownPluginList::getTypeForFile (const File& file) const throw()
{
for (int i = 0; i < types.size(); ++i)
if (types.getUnchecked(i)->file == file)
return types.getUnchecked(i);
return 0;
}
PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const throw()
{
for (int i = 0; i < types.size(); ++i)
if (types.getUnchecked(i)->createIdentifierString() == identifierString)
return types.getUnchecked(i);
return 0;
}
bool KnownPluginList::addType (const PluginDescription& type)
{
for (int i = types.size(); --i >= 0;)
{
if (types.getUnchecked(i)->isDuplicateOf (type))
{
// strange - found a duplicate plugin with different info..
jassert (types.getUnchecked(i)->name == type.name);
jassert (types.getUnchecked(i)->isInstrument == type.isInstrument);
*types.getUnchecked(i) = type;
return false;
}
}
types.add (new PluginDescription (type));
sendChangeMessage (this);
return true;
}
void KnownPluginList::removeType (const int index) throw()
{
types.remove (index);
sendChangeMessage (this);
}
bool KnownPluginList::isListingUpToDate (const File& possiblePluginFile) const throw()
{
if (getTypeForFile (possiblePluginFile) == 0)
return false;
for (int i = types.size(); --i >= 0;)
{
const PluginDescription* const d = types.getUnchecked(i);
if (d->file == possiblePluginFile
&& d->lastFileModTime != possiblePluginFile.getLastModificationTime())
{
return false;
}
}
return true;
}
bool KnownPluginList::scanAndAddFile (const File& possiblePluginFile,
const bool dontRescanIfAlreadyInList,
OwnedArray <PluginDescription>& typesFound)
{
bool addedOne = false;
if (dontRescanIfAlreadyInList
&& getTypeForFile (possiblePluginFile) != 0)
{
bool needsRescanning = false;
for (int i = types.size(); --i >= 0;)
{
const PluginDescription* const d = types.getUnchecked(i);
if (d->file == possiblePluginFile)
{
if (d->lastFileModTime != possiblePluginFile.getLastModificationTime())
needsRescanning = true;
else
typesFound.add (new PluginDescription (*d));
}
}
if (! needsRescanning)
return false;
}
for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i)
{
AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i);
OwnedArray <PluginDescription> found;
format->findAllTypesForFile (found, possiblePluginFile);
for (int i = 0; i < found.size(); ++i)
{
PluginDescription* const desc = found.getUnchecked(i);
jassert (desc != 0);
if (addType (*desc))
addedOne = true;
typesFound.add (new PluginDescription (*desc));
}
}
return addedOne;
}
void KnownPluginList::scanAndAddDragAndDroppedFiles (const StringArray& files,
OwnedArray <PluginDescription>& typesFound)
{
for (int i = 0; i < files.size(); ++i)
{
const File f (files [i]);
if (! scanAndAddFile (f, true, typesFound))
{
if (f.isDirectory())
{
StringArray s;
{
OwnedArray <File> subFiles;
f.findChildFiles (subFiles, File::findFilesAndDirectories, false);
for (int j = 0; j < subFiles.size(); ++j)
s.add (subFiles.getUnchecked (j)->getFullPathName());
}
scanAndAddDragAndDroppedFiles (s, typesFound);
}
}
}
}
//==============================================================================
class PluginSorter
{
public:
KnownPluginList::SortMethod method;
PluginSorter() throw() {}
int compareElements (const PluginDescription* const first,
const PluginDescription* const second) const throw()
{
int diff = 0;
if (method == KnownPluginList::sortByCategory)
diff = first->category.compareLexicographically (second->category);
else if (method == KnownPluginList::sortByManufacturer)
diff = first->manufacturerName.compareLexicographically (second->manufacturerName);
else if (method == KnownPluginList::sortByFileSystemLocation)
diff = first->file.getParentDirectory().getFullPathName().compare (second->file.getParentDirectory().getFullPathName());
if (diff == 0)
diff = first->name.compareLexicographically (second->name);
return diff;
}
};
void KnownPluginList::sort (const SortMethod method)
{
if (method != defaultOrder)
{
PluginSorter sorter;
sorter.method = method;
types.sort (sorter, true);
sendChangeMessage (this);
}
}
//==============================================================================
XmlElement* KnownPluginList::createXml() const
{
XmlElement* const e = new XmlElement (T("KNOWNPLUGINS"));
for (int i = 0; i < types.size(); ++i)
e->addChildElement (types.getUnchecked(i)->createXml());
return e;
}
void KnownPluginList::recreateFromXml (const XmlElement& xml)
{
clear();
if (xml.hasTagName (T("KNOWNPLUGINS")))
{
forEachXmlChildElement (xml, e)
{
PluginDescription info;
if (info.loadFromXml (*e))
addType (info);
}
}
}
//==============================================================================
const int menuIdBase = 0x324503f4;
// This is used to turn a bunch of paths into a nested menu structure.
struct PluginFilesystemTree
{
private:
String folder;
OwnedArray <PluginFilesystemTree> subFolders;
Array <PluginDescription*> plugins;
void addPlugin (PluginDescription* const pd, const String& path)
{
if (path.isEmpty())
{
plugins.add (pd);
}
else
{
const String firstSubFolder (path.upToFirstOccurrenceOf (T("/"), false, false));
const String remainingPath (path.fromFirstOccurrenceOf (T("/"), false, false));
for (int i = subFolders.size(); --i >= 0;)
{
if (subFolders.getUnchecked(i)->folder.equalsIgnoreCase (firstSubFolder))
{
subFolders.getUnchecked(i)->addPlugin (pd, remainingPath);
return;
}
}
PluginFilesystemTree* const newFolder = new PluginFilesystemTree();
newFolder->folder = firstSubFolder;
subFolders.add (newFolder);
newFolder->addPlugin (pd, remainingPath);
}
}
// removes any deeply nested folders that don't contain any actual plugins
void optimise()
{
for (int i = subFolders.size(); --i >= 0;)
{
PluginFilesystemTree* const sub = subFolders.getUnchecked(i);
sub->optimise();
if (sub->plugins.size() == 0)
{
for (int j = 0; j < sub->subFolders.size(); ++j)
subFolders.add (sub->subFolders.getUnchecked(j));
sub->subFolders.clear (false);
subFolders.remove (i);
}
}
}
public:
void buildTree (const Array <PluginDescription*>& allPlugins)
{
for (int i = 0; i < allPlugins.size(); ++i)
{
String path (allPlugins.getUnchecked(i)->file.getParentDirectory().getFullPathName());
if (path.substring (1, 2) == T(":"))
path = path.substring (2);
path = path.replaceCharacter (T('\\'), T('/'));
addPlugin (allPlugins.getUnchecked(i), path);
}
optimise();
}
void addToMenu (PopupMenu& m, const OwnedArray <PluginDescription>& allPlugins) const
{
int i;
for (i = 0; i < subFolders.size(); ++i)
{
const PluginFilesystemTree* const sub = subFolders.getUnchecked(i);
PopupMenu subMenu;
sub->addToMenu (subMenu, allPlugins);
m.addSubMenu (sub->folder, subMenu);
}
for (i = 0; i < plugins.size(); ++i)
{
PluginDescription* const plugin = plugins.getUnchecked(i);
m.addItem (allPlugins.indexOf (plugin) + menuIdBase,
plugin->name, true, false);
}
}
};
//==============================================================================
void KnownPluginList::addToMenu (PopupMenu& menu, const SortMethod sortMethod) const
{
Array <PluginDescription*> sorted;
{
PluginSorter sorter;
sorter.method = sortMethod;
for (int i = 0; i < types.size(); ++i)
sorted.addSorted (sorter, types.getUnchecked(i));
}
if (sortMethod == sortByCategory
|| sortMethod == sortByManufacturer)
{
String lastSubMenuName;
PopupMenu sub;
for (int i = 0; i < sorted.size(); ++i)
{
const PluginDescription* const pd = sorted.getUnchecked(i);
String thisSubMenuName (sortMethod == sortByCategory ? pd->category
: pd->manufacturerName);
if (thisSubMenuName.trim().isEmpty())
thisSubMenuName = T("Other");
if (thisSubMenuName != lastSubMenuName)
{
if (sub.getNumItems() > 0)
{
menu.addSubMenu (lastSubMenuName, sub);
sub.clear();
}
lastSubMenuName = thisSubMenuName;
}
sub.addItem (types.indexOf (pd) + menuIdBase, pd->name, true, false);
}
if (sub.getNumItems() > 0)
menu.addSubMenu (lastSubMenuName, sub);
}
else if (sortMethod == sortByFileSystemLocation)
{
PluginFilesystemTree root;
root.buildTree (sorted);
root.addToMenu (menu, types);
}
else
{
for (int i = 0; i < sorted.size(); ++i)
{
const PluginDescription* const pd = sorted.getUnchecked(i);
menu.addItem (types.indexOf (pd) + menuIdBase, pd->name, true, false);
}
}
}
int KnownPluginList::getIndexChosenByMenu (const int menuResultCode) const
{
const int i = menuResultCode - menuIdBase;
return (((unsigned int) i) < (unsigned int) types.size()) ? i : -1;
}
END_JUCE_NAMESPACE

+ 176
- 0
src/juce_appframework/audio/plugins/juce_KnownPluginList.h View File

@@ -0,0 +1,176 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_KNOWNPLUGINLIST_JUCEHEADER__
#define __JUCE_KNOWNPLUGINLIST_JUCEHEADER__
#include "juce_PluginDescription.h"
#include "juce_AudioPluginFormat.h"
#include "../../events/juce_ChangeBroadcaster.h"
#include "../../gui/components/menus/juce_PopupMenu.h"
//==============================================================================
/**
Manages a list of plugin types.
This can be easily edited, saved and loaded, and used to create instances of
the plugin types in it.
@see PluginListComponent
*/
class JUCE_API KnownPluginList : public ChangeBroadcaster
{
public:
//==============================================================================
/** Creates an empty list.
*/
KnownPluginList();
/** Destructor. */
~KnownPluginList();
//==============================================================================
/** Clears the list. */
void clear();
/** Returns the number of types currently in the list.
@see getType
*/
int getNumTypes() const throw() { return types.size(); }
/** Returns one of the types.
@see getNumTypes
*/
PluginDescription* getType (const int index) const throw() { return types [index]; }
/** Looks for a type in the list which comes from this file.
*/
PluginDescription* getTypeForFile (const File& file) const throw();
/** Looks for a type in the list which matches a plugin type ID.
The identifierString parameter must have been created by
PluginDescription::createIdentifierString().
*/
PluginDescription* getTypeForIdentifierString (const String& identifierString) const throw();
/** Adds a type manually from its description. */
bool addType (const PluginDescription& type);
/** Removes a type. */
void removeType (const int index) throw();
/** Looks for all types that can be loaded from a given file, and adds them
to the list.
If dontRescanIfAlreadyInList is true, then the file will only be loaded and
re-tested if it's not already in the list, or if the file's modification
time has changed since the list was created. If dontRescanIfAlreadyInList is
false, the file will always be reloaded and tested.
Returns true if any new types were added, and all the types found in this
file (even if it was already known and hasn't been re-scanned) get returned
in the array.
*/
bool scanAndAddFile (const File& possiblePluginFile,
const bool dontRescanIfAlreadyInList,
OwnedArray <PluginDescription>& typesFound);
/** Returns true if the specified file is already known about and if it
hasn't been modified since our entry was created.
*/
bool isListingUpToDate (const File& possiblePluginFile) const throw();
/** Scans and adds a bunch of files that might have been dragged-and-dropped.
If any types are found in the files, their descriptions are returned in the array.
*/
void scanAndAddDragAndDroppedFiles (const StringArray& filenames,
OwnedArray <PluginDescription>& typesFound);
//==============================================================================
/** Sort methods used to change the order of the plugins in the list.
*/
enum SortMethod
{
defaultOrder = 0,
sortAlphabetically,
sortByCategory,
sortByManufacturer,
sortByFileSystemLocation
};
//==============================================================================
/** Adds all the plugin types to a popup menu so that the user can select one.
Depending on the sort method, it may add sub-menus for categories,
manufacturers, etc.
Use getIndexChosenByMenu() to find out the type that was chosen.
*/
void addToMenu (PopupMenu& menu,
const SortMethod sortMethod) const;
/** Converts a menu item index that has been chosen into its index in this list.
Returns -1 if it's not an ID that was used.
@see addToMenu
*/
int getIndexChosenByMenu (const int menuResultCode) const;
//==============================================================================
/** Sorts the list. */
void sort (const SortMethod method);
//==============================================================================
/** Creates some XML that can be used to store the state of this list.
*/
XmlElement* createXml() const;
/** Recreates the state of this list from its stored XML format.
*/
void recreateFromXml (const XmlElement& xml);
//==============================================================================
juce_UseDebuggingNewOperator
private:
OwnedArray <PluginDescription> types;
KnownPluginList (const KnownPluginList&);
const KnownPluginList& operator= (const KnownPluginList&);
};
#endif // __JUCE_KNOWNPLUGINLIST_JUCEHEADER__

+ 139
- 0
src/juce_appframework/audio/plugins/juce_PluginDescription.cpp View File

@@ -0,0 +1,139 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_PluginDescription.h"
#include "juce_AudioPluginFormat.h"
//==============================================================================
PluginDescription::PluginDescription() throw()
: uid (0),
isInstrument (false),
numInputChannels (0),
numOutputChannels (0)
{
}
PluginDescription::~PluginDescription() throw()
{
}
PluginDescription::PluginDescription (const PluginDescription& other) throw()
: name (other.name),
pluginFormatName (other.pluginFormatName),
category (other.category),
manufacturerName (other.manufacturerName),
version (other.version),
file (other.file),
uid (other.uid),
isInstrument (other.isInstrument),
lastFileModTime (other.lastFileModTime),
numInputChannels (other.numInputChannels),
numOutputChannels (other.numOutputChannels)
{
}
const PluginDescription& PluginDescription::operator= (const PluginDescription& other) throw()
{
name = other.name;
pluginFormatName = other.pluginFormatName;
category = other.category;
manufacturerName = other.manufacturerName;
version = other.version;
file = other.file;
uid = other.uid;
isInstrument = other.isInstrument;
lastFileModTime = other.lastFileModTime;
numInputChannels = other.numInputChannels;
numOutputChannels = other.numOutputChannels;
return *this;
}
bool PluginDescription::isDuplicateOf (const PluginDescription& other) const
{
return file == other.file
&& uid == other.uid;
}
const String PluginDescription::createIdentifierString() const throw()
{
return pluginFormatName
+ T("-") + name
+ T("-") + String::toHexString (file.getFileName().hashCode())
+ T("-") + String::toHexString (uid);
}
XmlElement* PluginDescription::createXml() const
{
XmlElement* const e = new XmlElement (T("PLUGIN"));
e->setAttribute (T("name"), name);
e->setAttribute (T("format"), pluginFormatName);
e->setAttribute (T("category"), category);
e->setAttribute (T("manufacturer"), manufacturerName);
e->setAttribute (T("version"), version);
e->setAttribute (T("file"), file.getFullPathName());
e->setAttribute (T("uid"), String::toHexString (uid));
e->setAttribute (T("isInstrument"), isInstrument);
e->setAttribute (T("fileTime"), String::toHexString (lastFileModTime.toMilliseconds()));
e->setAttribute (T("numInputs"), numInputChannels);
e->setAttribute (T("numOutputs"), numOutputChannels);
return e;
}
bool PluginDescription::loadFromXml (const XmlElement& xml)
{
if (xml.hasTagName (T("PLUGIN")))
{
name = xml.getStringAttribute (T("name"));
pluginFormatName = xml.getStringAttribute (T("format"));
category = xml.getStringAttribute (T("category"));
manufacturerName = xml.getStringAttribute (T("manufacturer"));
version = xml.getStringAttribute (T("version"));
file = File (xml.getStringAttribute (T("file")));
uid = xml.getStringAttribute (T("uid")).getHexValue32();
isInstrument = xml.getBoolAttribute (T("isInstrument"), false);
lastFileModTime = Time (xml.getStringAttribute (T("fileTime")).getHexValue64());
numInputChannels = xml.getIntAttribute (T("numInputs"));
numOutputChannels = xml.getIntAttribute (T("numOutputs"));
return true;
}
return false;
}
END_JUCE_NAMESPACE

+ 140
- 0
src/juce_appframework/audio/plugins/juce_PluginDescription.h View File

@@ -0,0 +1,140 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__
#define __JUCE_PLUGINDESCRIPTION_JUCEHEADER__
#include "../../../juce_core/io/files/juce_File.h"
#include "../../../juce_core/text/juce_XmlElement.h"
//==============================================================================
/**
A small class to represent some facts about a particular type of plugin.
This class is for storing and managing the details about a plugin without
actually having to load an instance of it.
A KnownPluginList contains a list of PluginDescription objects.
@see KnownPluginList
*/
class JUCE_API PluginDescription
{
public:
//==============================================================================
PluginDescription() throw();
PluginDescription (const PluginDescription& other) throw();
const PluginDescription& operator= (const PluginDescription& other) throw();
~PluginDescription() throw();
//==============================================================================
/** The name of the plugin. */
String name;
/** The plugin format, e.g. "VST", "AudioUnit", etc.
*/
String pluginFormatName;
/** A category, such as "Dynamics", "Reverbs", etc.
*/
String category;
/** The manufacturer. */
String manufacturerName;
/** The version. This string doesn't have any particular format. */
String version;
/** The binary module file containing the plugin. */
File file;
/** The last time the plugin file was changed.
This is handy when scanning for new or changed plugins.
*/
Time lastFileModTime;
/** A unique ID for the plugin.
Note that this might not be unique between formats, e.g. a VST and some
other format might actually have the same id.
@see createIdentifierString
*/
int uid;
/** True if the plugin identifies itself as a synthesiser. */
bool isInstrument;
/** The number of inputs. */
int numInputChannels;
/** The number of outputs. */
int numOutputChannels;
/** Returns true if the two descriptions refer the the same plugin.
This isn't quite as simple as them just having the same file (because of
shell plugins).
*/
bool isDuplicateOf (const PluginDescription& other) const;
//==============================================================================
/** Returns a string that can be saved and used to uniquely identify the
plugin again.
This contains less info than the XML encoding, and is independent of the
plugin's file location, so can be used to store a plugin ID for use
across different machines.
*/
const String createIdentifierString() const throw();
//==============================================================================
/** Creates an XML object containing these details.
@see loadFromXml
*/
XmlElement* createXml() const;
/** Reloads the info in this structure from an XML record that was previously
saved with createXML().
Returns true if the XML was a valid plugin description.
*/
bool loadFromXml (const XmlElement& xml);
//==============================================================================
juce_UseDebuggingNewOperator
};
#endif // __JUCE_PLUGINDESCRIPTION_JUCEHEADER__

+ 164
- 0
src/juce_appframework/audio/plugins/juce_PluginDirectoryScanner.cpp View File

@@ -0,0 +1,164 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_PluginDirectoryScanner.h"
#include "juce_AudioPluginFormat.h"
#include "../../../juce_core/io/files/juce_DirectoryIterator.h"
//==============================================================================
PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo,
AudioPluginFormat& formatToLookFor,
FileSearchPath directoriesToSearch,
const bool recursive,
const File& deadMansPedalFile_)
: list (listToAddTo),
format (formatToLookFor),
deadMansPedalFile (deadMansPedalFile_),
nextIndex (0),
progress (0)
{
directoriesToSearch.removeRedundantPaths();
for (int j = 0; j < directoriesToSearch.getNumPaths(); ++j)
recursiveFileSearch (directoriesToSearch [j], recursive);
// If any plugins have crashed recently when being loaded, move them to the
// end of the list to give the others a chance to load correctly..
const StringArray crashedPlugins (getDeadMansPedalFile());
for (int i = 0; i < crashedPlugins.size(); ++i)
{
const File f (crashedPlugins[i]);
for (int j = filesToScan.size(); --j >= 0;)
if (f == *filesToScan.getUnchecked (j))
filesToScan.move (j, -1);
}
}
void PluginDirectoryScanner::recursiveFileSearch (const File& dir, const bool recursive)
{
// avoid allowing the dir iterator to be recursive, because we want to avoid letting it delve inside
// .component or .vst directories.
DirectoryIterator iter (dir, false, "*", File::findFilesAndDirectories);
while (iter.next())
{
const File f (iter.getFile());
bool isPlugin = false;
if (format.fileMightContainThisPluginType (f))
{
isPlugin = true;
filesToScan.add (new File (f));
}
if (recursive && (! isPlugin) && f.isDirectory())
recursiveFileSearch (f, true);
}
}
PluginDirectoryScanner::~PluginDirectoryScanner()
{
}
//==============================================================================
const File PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const throw()
{
File* const file = filesToScan [nextIndex];
if (file != 0)
return *file;
return File::nonexistent;
}
bool PluginDirectoryScanner::scanNextFile (const bool dontRescanIfAlreadyInList)
{
File* const file = filesToScan [nextIndex];
if (file != 0)
{
if (! list.isListingUpToDate (*file))
{
OwnedArray <PluginDescription> typesFound;
// Add this plugin to the end of the dead-man's pedal list in case it crashes...
StringArray crashedPlugins (getDeadMansPedalFile());
crashedPlugins.removeString (file->getFullPathName());
crashedPlugins.add (file->getFullPathName());
setDeadMansPedalFile (crashedPlugins);
list.scanAndAddFile (*file,
dontRescanIfAlreadyInList,
typesFound);
// Managed to load without crashing, so remove it from the dead-man's-pedal..
crashedPlugins.removeString (file->getFullPathName());
setDeadMansPedalFile (crashedPlugins);
if (typesFound.size() == 0)
failedFiles.add (file->getFullPathName());
}
++nextIndex;
progress = nextIndex / (float) filesToScan.size();
}
return nextIndex < filesToScan.size();
}
const StringArray PluginDirectoryScanner::getDeadMansPedalFile() throw()
{
StringArray lines;
if (deadMansPedalFile != File::nonexistent)
{
lines.addLines (deadMansPedalFile.loadFileAsString());
lines.removeEmptyStrings();
}
return lines;
}
void PluginDirectoryScanner::setDeadMansPedalFile (const StringArray& newContents) throw()
{
if (deadMansPedalFile != File::nonexistent)
deadMansPedalFile.replaceWithText (newContents.joinIntoString ("\n"), true, true);
}
END_JUCE_NAMESPACE

+ 129
- 0
src/juce_appframework/audio/plugins/juce_PluginDirectoryScanner.h View File

@@ -0,0 +1,129 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__
#define __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__
#include "juce_KnownPluginList.h"
#include "juce_AudioPluginFormatManager.h"
//==============================================================================
/**
Scans a directory for plugins, and adds them to a KnownPluginList.
To use one of these, create it and call scanNextFile() repeatedly, until
it returns false.
*/
class JUCE_API PluginDirectoryScanner
{
public:
//==============================================================================
/**
Creates a scanner.
@param listToAddResultsTo this will get the new types added to it.
@param formatToLookFor this is the type of format that you want to look for
@param directoriesToSearch the path to search
@param searchRecursively true to search recursively
@param deadMansPedalFile if this isn't File::nonexistent, then it will
be used as a file to store the names of any plugins
that crash during initialisation. If there are
any plugins listed in it, then these will always
be scanned after all other possible files have
been tried - in this way, even if there's a few
dodgy plugins in your path, then a couple of rescans
will still manage to find all the proper plugins.
It's probably best to choose a file in the user's
application data directory (alongside your app's
settings file) for this. The file format it uses
is just a list of filenames of the modules that
failed.
*/
PluginDirectoryScanner (KnownPluginList& listToAddResultsTo,
AudioPluginFormat& formatToLookFor,
FileSearchPath directoriesToSearch,
const bool searchRecursively,
const File& deadMansPedalFile);
/** Destructor. */
~PluginDirectoryScanner();
//==============================================================================
/** Tries the next likely-looking file.
If dontRescanIfAlreadyInList is true, then the file will only be loaded and
re-tested if it's not already in the list, or if the file's modification
time has changed since the list was created. If dontRescanIfAlreadyInList is
false, the file will always be reloaded and tested.
Returns false when there are no more files to try.
*/
bool scanNextFile (const bool dontRescanIfAlreadyInList);
/** Returns the file that will be scanned during the next call to scanNextFile().
This is handy if you want to show the user which file is currently getting
scanned.
*/
const File getNextPluginFileThatWillBeScanned() const throw();
/** Returns the estimated progress, between 0 and 1.
*/
float getProgress() const { return progress; }
/** This returns a list of all the filenames of things that looked like being
a plugin file, but which failed to open for some reason.
*/
const StringArray& getFailedFiles() const throw() { return failedFiles; }
//==============================================================================
juce_UseDebuggingNewOperator
private:
KnownPluginList& list;
AudioPluginFormat& format;
OwnedArray <File> filesToScan;
File deadMansPedalFile;
StringArray failedFiles;
int nextIndex;
float progress;
void recursiveFileSearch (const File& dir, const bool recursive);
const StringArray getDeadMansPedalFile() throw();
void setDeadMansPedalFile (const StringArray& newContents) throw();
PluginDirectoryScanner (const PluginDirectoryScanner&);
const PluginDirectoryScanner& operator= (const PluginDirectoryScanner&);
};
#endif // __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__

+ 308
- 0
src/juce_appframework/audio/plugins/juce_PluginListComponent.cpp View File

@@ -0,0 +1,308 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_PluginListComponent.h"
#include "juce_PluginDirectoryScanner.h"
#include "../../gui/components/controls/juce_TextEditor.h"
#include "../../gui/components/windows/juce_AlertWindow.h"
#include "../../gui/graphics/fonts/juce_GlyphArrangement.h"
#include "../../gui/components/filebrowser/juce_FileSearchPathListComponent.h"
#include "../../../juce_core/text/juce_LocalisedStrings.h"
#include "../../events/juce_MessageManager.h"
//==============================================================================
PluginListComponent::PluginListComponent (KnownPluginList& listToEdit,
const File& deadMansPedalFile_,
PropertiesFile* const propertiesToUse_)
: list (listToEdit),
deadMansPedalFile (deadMansPedalFile_),
propertiesToUse (propertiesToUse_)
{
addAndMakeVisible (listBox = new ListBox (String::empty, this));
addAndMakeVisible (optionsButton = new TextButton ("Options..."));
optionsButton->addButtonListener (this);
optionsButton->setTriggeredOnMouseDown (true);
setSize (400, 600);
list.addChangeListener (this);
}
PluginListComponent::~PluginListComponent()
{
list.removeChangeListener (this);
deleteAllChildren();
}
void PluginListComponent::resized()
{
listBox->setBounds (0, 0, getWidth(), getHeight() - 30);
optionsButton->changeWidthToFitText (24);
optionsButton->setTopLeftPosition (8, getHeight() - 28);
}
void PluginListComponent::changeListenerCallback (void*)
{
listBox->updateContent();
listBox->repaint();
}
int PluginListComponent::getNumRows()
{
return list.getNumTypes();
}
void PluginListComponent::paintListBoxItem (int row,
Graphics& g,
int width, int height,
bool rowIsSelected)
{
if (rowIsSelected)
g.fillAll (findColour (TextEditor::highlightColourId));
const PluginDescription* const pd = list.getType (row);
if (pd != 0)
{
GlyphArrangement ga;
ga.addCurtailedLineOfText (Font (height * 0.7f, Font::bold), pd->name, 8.0f, height * 0.8f, width - 10.0f, true);
g.setColour (Colours::black);
ga.draw (g);
float x, y, r, b;
ga.getBoundingBox (0, -1, x, y, r, b, false);
String desc;
desc << pd->pluginFormatName
<< (pd->isInstrument ? " instrument" : " effect")
<< " - "
<< pd->numInputChannels << (pd->numInputChannels == 1 ? " in" : " ins")
<< " / "
<< pd->numOutputChannels << (pd->numOutputChannels == 1 ? " out" : " outs");
if (pd->manufacturerName.isNotEmpty())
desc << " - " << pd->manufacturerName;
if (pd->version.isNotEmpty())
desc << " - " << pd->version;
if (pd->category.isNotEmpty())
desc << " - category: '" << pd->category << '\'';
g.setColour (Colours::grey);
ga.clear();
ga.addCurtailedLineOfText (Font (height * 0.6f), desc, r + 10.0f, height * 0.8f, width - r - 12.0f, true);
ga.draw (g);
}
}
void PluginListComponent::deleteKeyPressed (int lastRowSelected)
{
list.removeType (lastRowSelected);
}
void PluginListComponent::buttonClicked (Button* b)
{
if (optionsButton == b)
{
PopupMenu menu;
menu.addItem (1, TRANS("Clear list"));
menu.addItem (5, TRANS("Remove selected plugin from list"), listBox->getNumSelectedRows() > 0);
menu.addItem (6, TRANS("Show folder containing selected plugin"), listBox->getNumSelectedRows() > 0);
menu.addItem (7, TRANS("Remove any plugins whose files no longer exist"));
menu.addSeparator();
menu.addItem (2, TRANS("Sort alphabetically"));
menu.addItem (3, TRANS("Sort by category"));
menu.addItem (4, TRANS("Sort by manufacturer"));
menu.addSeparator();
for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i)
{
AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i);
if (format->getDefaultLocationsToSearch().getNumPaths() > 0)
menu.addItem (10 + i, "Scan for new or updated " + format->getName() + " plugins...");
}
const int r = menu.showAt (optionsButton);
if (r == 1)
{
list.clear();
}
else if (r == 2)
{
list.sort (KnownPluginList::sortAlphabetically);
}
else if (r == 3)
{
list.sort (KnownPluginList::sortByCategory);
}
else if (r == 4)
{
list.sort (KnownPluginList::sortByManufacturer);
}
else if (r == 5)
{
const SparseSet <int> selected (listBox->getSelectedRows());
for (int i = list.getNumTypes(); --i >= 0;)
if (selected.contains (i))
list.removeType (i);
}
else if (r == 6)
{
const PluginDescription* const desc = list.getType (listBox->getSelectedRow());
if (desc != 0)
desc->file.getParentDirectory().startAsProcess();
}
else if (r == 7)
{
for (int i = list.getNumTypes(); --i >= 0;)
{
if (list.getType (i)->file != File::nonexistent
&& ! list.getType (i)->file.exists())
{
list.removeType (i);
}
}
}
else if (r != 0)
{
typeToScan = r - 10;
startTimer (1);
}
}
}
void PluginListComponent::timerCallback()
{
stopTimer();
scanFor (AudioPluginFormatManager::getInstance()->getFormat (typeToScan));
}
bool PluginListComponent::isInterestedInFileDrag (const StringArray& /*files*/)
{
return true;
}
void PluginListComponent::filesDropped (const StringArray& files, int, int)
{
OwnedArray <PluginDescription> typesFound;
list.scanAndAddDragAndDroppedFiles (files, typesFound);
}
void PluginListComponent::scanFor (AudioPluginFormat* format)
{
if (format == 0)
return;
FileSearchPath path (format->getDefaultLocationsToSearch());
if (propertiesToUse != 0)
path = propertiesToUse->getValue ("lastPluginScanPath_" + format->getName(), path.toString());
{
AlertWindow aw (TRANS("Select folders to scan..."), String::empty, AlertWindow::NoIcon);
FileSearchPathListComponent pathList;
pathList.setSize (500, 300);
pathList.setPath (path);
aw.addCustomComponent (&pathList);
aw.addButton (TRANS("Scan"), 1, KeyPress::returnKey);
aw.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey));
if (aw.runModalLoop() == 0)
return;
path = pathList.getPath();
}
if (propertiesToUse != 0)
{
propertiesToUse->setValue ("lastPluginScanPath_" + format->getName(), path.toString());
propertiesToUse->saveIfNeeded();
}
double progress = 0.0;
AlertWindow aw (TRANS("Scanning for plugins..."),
TRANS("Searching for all possible plugin files..."), AlertWindow::NoIcon);
aw.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey));
aw.addProgressBarComponent (progress);
aw.enterModalState();
MessageManager::getInstance()->dispatchPendingMessages();
PluginDirectoryScanner scanner (list, *format, path, true, deadMansPedalFile);
for (;;)
{
aw.setMessage (TRANS("Testing:\n\n")
+ scanner.getNextPluginFileThatWillBeScanned().getFileName());
MessageManager::getInstance()->dispatchPendingMessages (500);
if (! scanner.scanNextFile (true))
break;
if (! aw.isCurrentlyModal())
break;
progress = scanner.getProgress();
}
if (scanner.getFailedFiles().size() > 0)
{
StringArray shortNames;
for (int i = 0; i < scanner.getFailedFiles().size(); ++i)
shortNames.add (File (scanner.getFailedFiles()[i]).getFileName());
AlertWindow::showMessageBox (AlertWindow::InfoIcon,
TRANS("Scan complete"),
TRANS("Note that the following files appeared to be plugin files, but failed to load correctly:\n\n")
+ shortNames.joinIntoString (", "));
}
}
END_JUCE_NAMESPACE

+ 107
- 0
src/juce_appframework/audio/plugins/juce_PluginListComponent.h View File

@@ -0,0 +1,107 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
#define __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
#include "juce_KnownPluginList.h"
#include "juce_AudioPluginFormat.h"
#include "../../gui/components/controls/juce_ListBox.h"
#include "../../gui/components/buttons/juce_TextButton.h"
#include "../../application/juce_PropertiesFile.h"
//==============================================================================
/**
A component displaying a list of plugins, with options to scan for them,
add, remove and sort them.
*/
class JUCE_API PluginListComponent : public Component,
public ListBoxModel,
public ChangeListener,
public ButtonListener,
public Timer
{
public:
//==============================================================================
/**
Creates the list component.
For info about the deadMansPedalFile, see the PluginDirectoryScanner constructor.
The properties file, if supplied, is used to store the user's last search paths.
*/
PluginListComponent (KnownPluginList& listToRepresent,
const File& deadMansPedalFile,
PropertiesFile* const propertiesToUse);
/** Destructor. */
~PluginListComponent();
//==============================================================================
/** @internal */
void resized();
/** @internal */
bool isInterestedInFileDrag (const StringArray& files);
/** @internal */
void filesDropped (const StringArray& files, int, int);
/** @internal */
int getNumRows();
/** @internal */
void paintListBoxItem (int row, Graphics& g, int width, int height, bool rowIsSelected);
/** @internal */
void deleteKeyPressed (int lastRowSelected);
/** @internal */
void buttonClicked (Button* b);
/** @internal */
void changeListenerCallback (void*);
/** @internal */
void timerCallback();
//==============================================================================
juce_UseDebuggingNewOperator
private:
KnownPluginList& list;
File deadMansPedalFile;
ListBox* listBox;
TextButton* optionsButton;
PropertiesFile* propertiesToUse;
int typeToScan;
void scanFor (AudioPluginFormat* format);
PluginListComponent (const PluginListComponent&);
const PluginListComponent& operator= (const PluginListComponent&);
};
#endif // __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__

+ 14
- 0
src/juce_appframework/audio/processors/juce_AudioProcessor.h View File

@@ -69,6 +69,11 @@ public:
/** Destructor. */
virtual ~AudioProcessor();
//==============================================================================
/** Returns the name of this processor.
*/
virtual const String getName() const = 0;
//==============================================================================
/** Called before playback starts, to let the filter prepare itself.
@@ -229,6 +234,12 @@ public:
*/
void setLatencySamples (const int newLatency);
/** Returns true if the processor wants midi messages. */
virtual bool acceptsMidi() const = 0;
/** Returns true if the processor produces midi messages. */
virtual bool producesMidi() const = 0;
//==============================================================================
/** This returns a critical section that will automatically be locked while the host
is calling the processBlock() method.
@@ -535,6 +546,9 @@ private:
#ifdef JUCE_DEBUG
BitArray changingParams;
#endif
AudioProcessor (const AudioProcessor&);
const AudioProcessor& operator= (const AudioProcessor&);
};


+ 1340
- 0
src/juce_appframework/audio/processors/juce_AudioProcessorGraph.cpp
File diff suppressed because it is too large
View File


+ 440
- 0
src/juce_appframework/audio/processors/juce_AudioProcessorGraph.h View File

@@ -0,0 +1,440 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__
#define __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__
#include "juce_AudioProcessor.h"
#include "../plugins/juce_AudioPluginFormatManager.h"
#include "../plugins/juce_KnownPluginList.h"
#include "../../../juce_core/containers/juce_ReferenceCountedArray.h"
//==============================================================================
/**
A type of AudioProcessor which plays back a graph of other AudioProcessors.
Use one of these objects if you want to wire-up a set of AudioProcessors
and play back the result.
Processors can be added to the graph as "nodes" using addNode(), and once
added, you can connect any of their input or output channels to other
nodes using addConnection().
To play back a graph through an audio device, you might want to use an
AudioProcessorPlayer object.
*/
class JUCE_API AudioProcessorGraph : public AudioProcessor,
public AsyncUpdater
{
public:
//==============================================================================
/** Creates an empty graph.
*/
AudioProcessorGraph();
/** Destructor.
Any processor objects that have been added to the graph will also be deleted.
*/
~AudioProcessorGraph();
//==============================================================================
/** Represents one of the nodes, or processors, in an AudioProcessorGraph.
To create a node, call AudioProcessorGraph::addNode().
*/
class Node : public ReferenceCountedObject
{
public:
/** Destructor.
*/
~Node();
//==============================================================================
/** The ID number assigned to this node.
This is assigned by the graph that owns it, and can't be changed.
*/
const uint32 id;
/** The actual processor object that this node represents.
*/
AudioProcessor* const processor;
/** A set of user-definable properties that are associated with this node.
This can be used to attach values to the node for whatever purpose seems
useful. For example, you might store an x and y position if your application
is displaying the nodes on-screen.
*/
PropertySet properties;
//==============================================================================
/** A convenient typedef for referring to a pointer to a node object.
*/
typedef ReferenceCountedObjectPtr <Node> Ptr;
//==============================================================================
juce_UseDebuggingNewOperator
private:
friend class AudioProcessorGraph;
bool isPrepared;
Node (const uint32 id, AudioProcessor* const processor) throw();
void prepare (const double sampleRate, const int blockSize, AudioProcessorGraph* const graph);
void unprepare();
Node (const Node&);
const Node& operator= (const Node&);
};
//==============================================================================
/** Represents a connection between two channels of two nodes in an AudioProcessorGraph.
To create a connection, use AudioProcessorGraph::addConnection().
*/
struct Connection
{
public:
//==============================================================================
/** The ID number of the node which is the input source for this connection.
@see AudioProcessorGraph::getNodeForId
*/
uint32 sourceNodeId;
/** The index of the output channel of the source node from which this
connection takes its data.
If this value is the special number AudioProcessorGraph::midiChannelIndex, then
it is referring to the source node's midi output. Otherwise, it is the zero-based
index of an audio output channel in the source node.
*/
int sourceChannelIndex;
/** The ID number of the node which is the destination for this connection.
@see AudioProcessorGraph::getNodeForId
*/
uint32 destNodeId;
/** The index of the input channel of the destination node to which this
connection delivers its data.
If this value is the special number AudioProcessorGraph::midiChannelIndex, then
it is referring to the destination node's midi input. Otherwise, it is the zero-based
index of an audio input channel in the destination node.
*/
int destChannelIndex;
//==============================================================================
juce_UseDebuggingNewOperator
private:
};
//==============================================================================
/** Deletes all nodes and connections from this graph.
Any processor objects in the graph will be deleted.
*/
void clear();
/** Returns the number of nodes in the graph. */
int getNumNodes() const throw() { return nodes.size(); }
/** Returns a pointer to one of the nodes in the graph.
This will return 0 if the index is out of range.
@see getNodeForId
*/
Node* getNode (const int index) const throw() { return nodes [index]; }
/** Searches the graph for a node with the given ID number and returns it.
If no such node was found, this returns 0.
@see getNode
*/
Node* getNodeForId (const uint32 nodeId) const throw();
/** Adds a node to the graph.
This creates a new node in the graph, for the specified processor. Once you have
added a processor to the graph, the graph owns it and will delete it later when
it is no longer needed.
The optional nodeId parameter lets you specify an ID to use for the node, but
if the value is already in use, this new node will overwrite the old one.
If this succeeds, it returns a pointer to the newly-created node.
*/
Node* addNode (AudioProcessor* const newProcessor,
uint32 nodeId = 0);
/** Deletes a node within the graph which has the specified ID.
This will also delete any connections that are attached to this node.
*/
bool removeNode (const uint32 nodeId);
//==============================================================================
/** Returns the number of connections in the graph. */
int getNumConnections() const throw() { return connections.size(); }
/** Returns a pointer to one of the connections in the graph. */
const Connection* getConnection (const int index) const throw() { return connections [index]; }
/** Searches for a connection between some specified channels.
If no such connection is found, this returns 0.
*/
const Connection* getConnectionBetween (const uint32 sourceNodeId,
const int sourceChannelIndex,
const uint32 destNodeId,
const int destChannelIndex) const throw();
/** Returns true if there is a connection between any of the channels of
two specified nodes.
*/
bool isConnected (const uint32 possibleSourceNodeId,
const uint32 possibleDestNodeId) const throw();
/** Returns true if it would be legal to connect the specified points.
*/
bool canConnect (const uint32 sourceNodeId, const int sourceChannelIndex,
const uint32 destNodeId, const int destChannelIndex) const throw();
/** Attempts to connect two specified channels of two nodes.
If this isn't allowed (e.g. because you're trying to connect a midi channel
to an audio one or other such nonsense), then it'll return 0.
*/
bool addConnection (const uint32 sourceNodeId, const int sourceChannelIndex,
const uint32 destNodeId, const int destChannelIndex);
/** Deletes the connection with the specified index.
Returns true if a connection was actually deleted.
*/
void removeConnection (const int index);
/** Deletes any connection between two specified points.
Returns true if a connection was actually deleted.
*/
bool removeConnection (const uint32 sourceNodeId, const int sourceChannelIndex,
const uint32 destNodeId, const int destChannelIndex);
/** Removes all connections from the specified node.
*/
bool disconnectNode (const uint32 nodeId);
/** Performs a sanity checks of all the connections.
This might be useful if some of the processors are doing things like changing
their channel counts, which could render some connections obsolete.
*/
bool removeIllegalConnections();
//==============================================================================
/** A special number that represents the midi channel of a node.
This is used as a channel index value if you want to refer to the midi input
or output instead of an audio channel.
*/
static const int midiChannelIndex;
//==============================================================================
/** A special type of AudioProcessor that can live inside an AudioProcessorGraph
in order to use the audio that comes into and out of the graph itself.
If you create an AudioGraphIOProcessor in "input" mode, it will act as a
node in the graph which delivers the audio that is coming into the parent
graph. This allows you to stream the data to other nodes and process the
incoming audio.
Likewise, one of these in "output" mode can be sent data which it will add to
the sum of data being sent to the graph's output.
@see AudioProcessorGraph
*/
class AudioGraphIOProcessor : public AudioPluginInstance
{
public:
/** Specifies the mode in which this processor will operate.
*/
enum IODeviceType
{
audioInputNode, /**< In this mode, the processor has output channels
representing all the audio input channels that are
coming into its parent audio graph. */
audioOutputNode, /**< In this mode, the processor has input channels
representing all the audio output channels that are
going out of its parent audio graph. */
midiInputNode, /**< In this mode, the processor has a midi output which
delivers the same midi data that is arriving at its
parent graph. */
midiOutputNode /**< In this mode, the processor has a midi input and
any data sent to it will be passed out of the parent
graph. */
};
//==============================================================================
/** Returns the mode of this processor. */
IODeviceType getType() const throw() { return type; }
/** Returns the parent graph to which this processor belongs, or 0 if it
hasn't yet been added to one. */
AudioProcessorGraph* getParentGraph() const throw() { return graph; }
/** True if this is an audio or midi input. */
bool isInput() const throw();
/** True if this is an audio or midi output. */
bool isOutput() const throw();
//==============================================================================
AudioGraphIOProcessor (const IODeviceType type);
~AudioGraphIOProcessor();
const String getName() const;
void fillInPluginDescription (PluginDescription& d) const;
void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock);
void releaseResources();
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
const String getInputChannelName (const int channelIndex) const;
const String getOutputChannelName (const int channelIndex) const;
bool isInputChannelStereoPair (int index) const;
bool isOutputChannelStereoPair (int index) const;
bool acceptsMidi() const;
bool producesMidi() const;
AudioProcessorEditor* createEditor();
int getNumParameters();
const String getParameterName (int);
float getParameter (int);
const String getParameterText (int);
void setParameter (int, float);
int getNumPrograms();
int getCurrentProgram();
void setCurrentProgram (int);
const String getProgramName (int);
void changeProgramName (int, const String&);
void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);
void setStateInformation (const void* data, int sizeInBytes);
/** @internal */
void setParentGraph (AudioProcessorGraph* const graph) throw();
juce_UseDebuggingNewOperator
private:
const IODeviceType type;
AudioProcessorGraph* graph;
AudioGraphIOProcessor (const AudioGraphIOProcessor&);
const AudioGraphIOProcessor& operator= (const AudioGraphIOProcessor&);
};
//==============================================================================
// AudioProcessor methods:
const String getName() const;
void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock);
void releaseResources();
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
const String getInputChannelName (const int channelIndex) const;
const String getOutputChannelName (const int channelIndex) const;
bool isInputChannelStereoPair (int index) const;
bool isOutputChannelStereoPair (int index) const;
bool acceptsMidi() const;
bool producesMidi() const;
AudioProcessorEditor* createEditor() { return 0; }
int getNumParameters() { return 0; }
const String getParameterName (int) { return String::empty; }
float getParameter (int) { return 0; }
const String getParameterText (int) { return String::empty; }
void setParameter (int, float) { }
int getNumPrograms() { return 0; }
int getCurrentProgram() { return 0; }
void setCurrentProgram (int) { }
const String getProgramName (int) { return String::empty; }
void changeProgramName (int, const String&) { }
void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);
void setStateInformation (const void* data, int sizeInBytes);
/** @internal */
void handleAsyncUpdate();
//==============================================================================
juce_UseDebuggingNewOperator
private:
ReferenceCountedArray <Node> nodes;
OwnedArray <Connection> connections;
int lastNodeId;
AudioSampleBuffer renderingBuffers;
OwnedArray <MidiBuffer> midiBuffers;
CriticalSection renderLock;
VoidArray renderingOps;
friend class AudioGraphIOProcessor;
AudioSampleBuffer* currentAudioIOBuffer;
MidiBuffer* currentMidiIOBuffer;
void clearRenderingSequence();
void buildRenderingSequence();
bool isAnInputTo (const uint32 possibleInputId,
const uint32 possibleDestinationId,
const int recursionCheck) const throw();
AudioProcessorGraph (const AudioProcessorGraph&);
const AudioProcessorGraph& operator= (const AudioProcessorGraph&);
};
#endif // __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__

+ 207
- 0
src/juce_appframework/audio/processors/juce_AudioProcessorPlayer.cpp View File

@@ -0,0 +1,207 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_AudioProcessorPlayer.h"
#include "../../../juce_core/threads/juce_ScopedLock.h"
//==============================================================================
AudioProcessorPlayer::AudioProcessorPlayer()
: processor (0),
sampleRate (0),
blockSize (0),
isPrepared (false),
numInputChans (0),
numOutputChans (0),
tempBuffer (1, 1)
{
}
AudioProcessorPlayer::~AudioProcessorPlayer()
{
setProcessor (0);
}
//==============================================================================
void AudioProcessorPlayer::setProcessor (AudioProcessor* const processorToPlay)
{
if (processor != processorToPlay)
{
if (processorToPlay != 0 && sampleRate > 0 && blockSize > 0)
{
processorToPlay->setPlayConfigDetails (numInputChans, numOutputChans,
sampleRate, blockSize);
processorToPlay->prepareToPlay (sampleRate, blockSize);
}
lock.enter();
AudioProcessor* const oldOne = isPrepared ? processor : 0;
processor = processorToPlay;
isPrepared = true;
lock.exit();
if (oldOne != 0)
oldOne->releaseResources();
}
}
//==============================================================================
void AudioProcessorPlayer::audioDeviceIOCallback (const float** inputChannelData,
int totalNumInputChannels,
float** outputChannelData,
int totalNumOutputChannels,
int numSamples)
{
// these should have been prepared by audioDeviceAboutToStart()...
jassert (sampleRate > 0 && blockSize > 0);
incomingMidi.clear();
messageCollector.removeNextBlockOfMessages (incomingMidi, numSamples);
int i, numActiveChans = 0, numInputs = 0, numOutputs = 0;
// messy stuff needed to compact the channels down into an array
// of non-zero pointers..
for (i = 0; i < totalNumInputChannels; ++i)
{
if (inputChannelData[i] != 0)
{
inputChans [numInputs++] = inputChannelData[i];
if (numInputs >= numElementsInArray (inputChans))
break;
}
}
for (i = 0; i < totalNumOutputChannels; ++i)
{
if (outputChannelData[i] != 0)
{
outputChans [numOutputs++] = outputChannelData[i];
if (numOutputs >= numElementsInArray (outputChans))
break;
}
}
if (numInputs > numOutputs)
{
// if there aren't enough output channels for the number of
// inputs, we need to create some temporary extra ones (can't
// use the input data in case it gets written to)
tempBuffer.setSize (numInputs - numOutputs, numSamples,
false, false, true);
for (i = 0; i < numOutputs; ++i)
{
channels[numActiveChans] = outputChans[i];
memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * numSamples);
++numActiveChans;
}
for (i = numOutputs; i < numInputs; ++i)
{
channels[numActiveChans] = tempBuffer.getSampleData (i - numOutputs, 0);
memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * numSamples);
++numActiveChans;
}
}
else
{
for (i = 0; i < numInputs; ++i)
{
channels[numActiveChans] = outputChans[i];
memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * numSamples);
++numActiveChans;
}
for (i = numInputs; i < numOutputs; ++i)
{
channels[numActiveChans] = outputChans[i];
zeromem (channels[numActiveChans], sizeof (float) * numSamples);
++numActiveChans;
}
}
AudioSampleBuffer buffer (channels, numActiveChans, numSamples);
const ScopedLock sl (lock);
if (processor != 0)
processor->processBlock (buffer, incomingMidi);
}
void AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* device)
{
const ScopedLock sl (lock);
sampleRate = device->getCurrentSampleRate();
blockSize = device->getCurrentBufferSizeSamples();
numInputChans = device->getActiveInputChannels().countNumberOfSetBits();
numOutputChans = device->getActiveOutputChannels().countNumberOfSetBits();
messageCollector.reset (sampleRate);
zeromem (channels, sizeof (channels));
if (processor != 0)
{
if (isPrepared)
processor->releaseResources();
AudioProcessor* const oldProcessor = processor;
setProcessor (0);
setProcessor (oldProcessor);
}
}
void AudioProcessorPlayer::audioDeviceStopped()
{
const ScopedLock sl (lock);
if (processor != 0 && isPrepared)
processor->releaseResources();
sampleRate = 0.0;
blockSize = 0;
isPrepared = false;
tempBuffer.setSize (1, 1);
}
void AudioProcessorPlayer::handleIncomingMidiMessage (MidiInput*, const MidiMessage& message)
{
messageCollector.addMessageToQueue (message);
}
END_JUCE_NAMESPACE

+ 121
- 0
src/juce_appframework/audio/processors/juce_AudioProcessorPlayer.h View File

@@ -0,0 +1,121 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__
#define __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__
#include "juce_AudioProcessor.h"
#include "../devices/juce_AudioIODevice.h"
#include "../devices/juce_MidiInput.h"
#include "../midi/juce_MidiMessageCollector.h"
//==============================================================================
/**
An AudioIODeviceCallback object which streams audio through an AudioProcessor.
To use one of these, just make it the callback used by your AudioIODevice, and
give it a processor to use by calling setProcessor().
It's also a MidiInputCallback, so you can connect it to both an audio and midi
input to send both streams through the processor.
@see AudioProcessor, AudioProcessorGraph
*/
class JUCE_API AudioProcessorPlayer : public AudioIODeviceCallback,
public MidiInputCallback
{
public:
//==============================================================================
/**
*/
AudioProcessorPlayer();
/** Destructor. */
virtual ~AudioProcessorPlayer();
//==============================================================================
/** Sets the processor that should be played.
The processor that is passed in will not be deleted or owned by this object.
To stop anything playing, pass in 0 to this method.
*/
void setProcessor (AudioProcessor* const processorToPlay);
/** Returns the current audio processor that is being played.
*/
AudioProcessor* getCurrentProcessor() const throw() { return processor; }
/** Returns a midi message collector that you can pass midi messages to if you
want them to be injected into the midi stream that is being sent to the
processor.
*/
MidiMessageCollector& getMidiMessageCollector() throw() { return messageCollector; }
//==============================================================================
/** @internal */
void audioDeviceIOCallback (const float** inputChannelData,
int totalNumInputChannels,
float** outputChannelData,
int totalNumOutputChannels,
int numSamples);
/** @internal */
void audioDeviceAboutToStart (AudioIODevice* device);
/** @internal */
void audioDeviceStopped();
/** @internal */
void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message);
//==============================================================================
juce_UseDebuggingNewOperator
private:
AudioProcessor* processor;
CriticalSection lock;
double sampleRate;
int blockSize;
bool isPrepared;
int numInputChans, numOutputChans;
float* channels [128];
float* outputChans [128];
const float* inputChans [128];
AudioSampleBuffer tempBuffer;
MidiBuffer incomingMidi;
MidiMessageCollector messageCollector;
AudioProcessorPlayer (const AudioProcessorPlayer&);
const AudioProcessorPlayer& operator= (const AudioProcessorPlayer&);
};
#endif // __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__

Loading…
Cancel
Save