| @@ -109,6 +109,8 @@ OBJECTS := \ | |||||
| $(OBJDIR)/juce_MidiMessageSequence.o \ | $(OBJDIR)/juce_MidiMessageSequence.o \ | ||||
| $(OBJDIR)/juce_AudioProcessor.o \ | $(OBJDIR)/juce_AudioProcessor.o \ | ||||
| $(OBJDIR)/juce_AudioProcessorEditor.o \ | $(OBJDIR)/juce_AudioProcessorEditor.o \ | ||||
| $(OBJDIR)/juce_AudioProcessorGraph.o \ | |||||
| $(OBJDIR)/juce_AudioProcessorPlayer.o \ | |||||
| $(OBJDIR)/juce_GenericAudioProcessorEditor.o \ | $(OBJDIR)/juce_GenericAudioProcessorEditor.o \ | ||||
| $(OBJDIR)/juce_AiffAudioFormat.o \ | $(OBJDIR)/juce_AiffAudioFormat.o \ | ||||
| $(OBJDIR)/juce_AudioCDReader.o \ | $(OBJDIR)/juce_AudioCDReader.o \ | ||||
| @@ -120,6 +122,8 @@ OBJECTS := \ | |||||
| $(OBJDIR)/juce_WavAudioFormat.o \ | $(OBJDIR)/juce_WavAudioFormat.o \ | ||||
| $(OBJDIR)/bitbuffer.o \ | $(OBJDIR)/bitbuffer.o \ | ||||
| $(OBJDIR)/bitmath.o \ | $(OBJDIR)/bitmath.o \ | ||||
| $(OBJDIR)/bitreader.o \ | |||||
| $(OBJDIR)/bitwriter.o \ | |||||
| $(OBJDIR)/cpu.o \ | $(OBJDIR)/cpu.o \ | ||||
| $(OBJDIR)/crc.o \ | $(OBJDIR)/crc.o \ | ||||
| $(OBJDIR)/fixed.o \ | $(OBJDIR)/fixed.o \ | ||||
| @@ -801,6 +805,16 @@ $(OBJDIR)/juce_AudioProcessorEditor.o: ../../src/juce_appframework/audio/process | |||||
| @echo $(notdir $<) | @echo $(notdir $<) | ||||
| @$(CXX) $(CXXFLAGS) -o $@ -c $< | @$(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 | $(OBJDIR)/juce_GenericAudioProcessorEditor.o: ../../src/juce_appframework/audio/processors/juce_GenericAudioProcessorEditor.cpp | ||||
| -@$(CMD_MKOBJDIR) | -@$(CMD_MKOBJDIR) | ||||
| @echo $(notdir $<) | @echo $(notdir $<) | ||||
| @@ -856,6 +870,16 @@ $(OBJDIR)/bitmath.o: ../../src/juce_appframework/audio/audio_file_formats/flac/l | |||||
| @echo $(notdir $<) | @echo $(notdir $<) | ||||
| @$(CC) $(CFLAGS) -o $@ -c $< | @$(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 | $(OBJDIR)/cpu.o: ../../src/juce_appframework/audio/audio_file_formats/flac/libFLAC/cpu.c | ||||
| -@$(CMD_MKOBJDIR) | -@$(CMD_MKOBJDIR) | ||||
| @echo $(notdir $<) | @echo $(notdir $<) | ||||
| @@ -68,6 +68,10 @@ package.files = { matchfiles ( | |||||
| "../../src/juce_appframework/audio/midi/*.h", | "../../src/juce_appframework/audio/midi/*.h", | ||||
| "../../src/juce_appframework/audio/processors/*.cpp", | "../../src/juce_appframework/audio/processors/*.cpp", | ||||
| "../../src/juce_appframework/audio/processors/*.h", | "../../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/*.cpp", | ||||
| "../../src/juce_appframework/audio/audio_file_formats/*.h", | "../../src/juce_appframework/audio/audio_file_formats/*.h", | ||||
| "../../src/juce_appframework/audio/audio_file_formats/flac/libFLAC/*.c", | "../../src/juce_appframework/audio/audio_file_formats/flac/libFLAC/*.c", | ||||
| @@ -20,6 +20,22 @@ | |||||
| 84099CA10AE52BD000B2A05D /* juce_Synthesiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84099C9D0AE52BD000B2A05D /* juce_Synthesiser.cpp */; }; | 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 */; }; | 84099CA20AE52BD000B2A05D /* juce_Synthesiser.h in Headers */ = {isa = PBXBuildFile; fileRef = 84099C9E0AE52BD000B2A05D /* juce_Synthesiser.h */; }; | ||||
| 840F80BC092B399D005E7B4E /* juce.h in Headers */ = {isa = PBXBuildFile; fileRef = 840F80BB092B399D005E7B4E /* juce.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 */; }; | 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 */; }; | 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 */; }; | 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 */; }; | 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 */; }; | 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 */; }; | 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 */; }; | 84F690FF0B3444F800ABAE1C /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690FD0B3444F800ABAE1C /* bitwise.c */; }; | ||||
| 84F691000B3444F800ABAE1C /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690FE0B3444F800ABAE1C /* framing.c */; }; | 84F691000B3444F800ABAE1C /* framing.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F690FE0B3444F800ABAE1C /* framing.c */; }; | ||||
| 84F691170B34453600ABAE1C /* analysis.c in Sources */ = {isa = PBXBuildFile; fileRef = 84F691010B34453600ABAE1C /* analysis.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>"; }; | 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>"; }; | 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; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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 */ = { | 84F690DC0B3444A500ABAE1C /* flac */ = { | ||||
| isa = PBXGroup; | isa = PBXGroup; | ||||
| children = ( | 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; | name = flac; | ||||
| sourceTree = "<group>"; | sourceTree = "<group>"; | ||||
| @@ -3119,20 +3125,6 @@ | |||||
| 841E06370AF8CE75005E6FCC /* juce_AudioSampleBuffer.cpp in Sources */, | 841E06370AF8CE75005E6FCC /* juce_AudioSampleBuffer.cpp in Sources */, | ||||
| 841E06390AF8CE75005E6FCC /* juce_IIRFilter.cpp in Sources */, | 841E06390AF8CE75005E6FCC /* juce_IIRFilter.cpp in Sources */, | ||||
| 84F525000B32A8D500597B73 /* juce_ApplicationProperties.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 */, | 84F690FF0B3444F800ABAE1C /* bitwise.c in Sources */, | ||||
| 84F691000B3444F800ABAE1C /* framing.c in Sources */, | 84F691000B3444F800ABAE1C /* framing.c in Sources */, | ||||
| 84F691170B34453600ABAE1C /* analysis.c in Sources */, | 84F691170B34453600ABAE1C /* analysis.c in Sources */, | ||||
| @@ -3166,6 +3158,22 @@ | |||||
| 84BC4E2A0C8DD38C00FA249B /* juce_AudioProcessor.cpp in Sources */, | 84BC4E2A0C8DD38C00FA249B /* juce_AudioProcessor.cpp in Sources */, | ||||
| 84BC4E2C0C8DD38C00FA249B /* juce_AudioProcessorEditor.cpp in Sources */, | 84BC4E2C0C8DD38C00FA249B /* juce_AudioProcessorEditor.cpp in Sources */, | ||||
| 84BC4E2F0C8DD38C00FA249B /* juce_GenericAudioProcessorEditor.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; | runOnlyForDeploymentPostprocessing = 0; | ||||
| }; | }; | ||||
| @@ -1,13 +1,22 @@ | |||||
| ARCHS = ppc i386 | ARCHS = ppc i386 | ||||
| // For 10.2 compatibility, use these values: | |||||
| // For 10.2 (and later) compatibility, use these values: | |||||
| GCC_VERSION_ppc = 3.3 | GCC_VERSION_ppc = 3.3 | ||||
| MACOSX_DEPLOYMENT_TARGET = 10.4 | |||||
| MACOSX_DEPLOYMENT_TARGET_ppc = 10.2 | 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 | // 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 | |||||
| @@ -705,11 +705,15 @@ | |||||
| Name="flac" | Name="flac" | ||||
| > | > | ||||
| <File | <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> | ||||
| <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> | ||||
| <File | <File | ||||
| @@ -732,10 +736,6 @@ | |||||
| RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\format.c" | RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\format.c" | ||||
| > | > | ||||
| </File> | </File> | ||||
| <File | |||||
| RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\juce_FlacHeader.h" | |||||
| > | |||||
| </File> | |||||
| <File | <File | ||||
| RelativePath="..\..\..\src\juce_appframework\audio\audio_file_formats\flac\libFLAC\lpc_flac.c" | 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" | RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorEditor.h" | ||||
| > | > | ||||
| </File> | </File> | ||||
| <File | |||||
| RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorGraph.cpp" | |||||
| > | |||||
| </File> | |||||
| <File | |||||
| RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorGraph.h" | |||||
| > | |||||
| </File> | |||||
| <File | <File | ||||
| RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorListener.h" | RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorListener.h" | ||||
| > | > | ||||
| </File> | </File> | ||||
| <File | |||||
| RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorPlayer.cpp" | |||||
| > | |||||
| </File> | |||||
| <File | |||||
| RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_AudioProcessorPlayer.h" | |||||
| > | |||||
| </File> | |||||
| <File | <File | ||||
| RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_GenericAudioProcessorEditor.cpp" | RelativePath="..\..\..\src\juce_appframework\audio\processors\juce_GenericAudioProcessorEditor.cpp" | ||||
| > | > | ||||
| @@ -1202,6 +1218,94 @@ | |||||
| > | > | ||||
| </File> | </File> | ||||
| </Filter> | </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> | ||||
| <Filter | <Filter | ||||
| Name="events" | Name="events" | ||||
| @@ -6,12 +6,19 @@ | |||||
| ============================================================================== | ============================================================================== | ||||
| Changelist for version 1.46 | 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 | - Mac: the project now requires at least XCode V2.5 | ||||
| - new class: ScopedTryLock | - new class: ScopedTryLock | ||||
| - added AudioUnit support to the audio hosting code | - 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..) | - 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 | - 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 | - 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 | Changelist for version 1.45 | ||||
| @@ -214,78 +214,6 @@ | |||||
| > | > | ||||
| </File> | </File> | ||||
| </Filter> | </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> | ||||
| <Filter | <Filter | ||||
| Name="Resource Files" | Name="Resource Files" | ||||
| @@ -67,6 +67,7 @@ public: | |||||
| AudioPluginFormatManager::getInstance()->addFormat (new InternalPluginFormat()); | AudioPluginFormatManager::getInstance()->addFormat (new InternalPluginFormat()); | ||||
| mainWindow = new MainHostWindow(); | mainWindow = new MainHostWindow(); | ||||
| //mainWindow->setUsingNativeTitleBar (true); | |||||
| commandManager->registerAllCommandsForTarget (this); | commandManager->registerAllCommandsForTarget (this); | ||||
| commandManager->registerAllCommandsForTarget (mainWindow); | commandManager->registerAllCommandsForTarget (mainWindow); | ||||
| @@ -32,6 +32,7 @@ | |||||
| #include "../../../../juce.h" | #include "../../../../juce.h" | ||||
| #include "FilterGraph.h" | #include "FilterGraph.h" | ||||
| #include "InternalFilters.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 | XmlElement* FilterGraph::createXml() const | ||||
| @@ -601,19 +377,21 @@ XmlElement* FilterGraph::createXml() const | |||||
| XmlElement* xml = new XmlElement ("FILTERGRAPH"); | XmlElement* xml = new XmlElement ("FILTERGRAPH"); | ||||
| int i; | 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"); | 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); | xml->addChildElement (e); | ||||
| } | } | ||||
| @@ -627,10 +405,8 @@ void FilterGraph::restoreFromXml (const XmlElement& xml) | |||||
| forEachXmlChildElementWithTagName (xml, e, T("FILTER")) | forEachXmlChildElementWithTagName (xml, e, T("FILTER")) | ||||
| { | { | ||||
| FilterInGraph* f = FilterInGraph::createFromXml (*this, *e); | |||||
| if (f != 0) | |||||
| addFilter (f); | |||||
| createNodeFromXml (*e); | |||||
| changed(); | |||||
| } | } | ||||
| forEachXmlChildElementWithTagName (xml, e, T("CONNECTION")) | forEachXmlChildElementWithTagName (xml, e, T("CONNECTION")) | ||||
| @@ -641,171 +417,5 @@ void FilterGraph::restoreFromXml (const XmlElement& xml) | |||||
| e->getIntAttribute (T("dstChannel"))); | 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(); | |||||
| } | } | ||||
| @@ -32,12 +32,8 @@ | |||||
| #ifndef __JUCE_FILTERGRAPH_JUCEHEADER__ | #ifndef __JUCE_FILTERGRAPH_JUCEHEADER__ | ||||
| #define __JUCE_FILTERGRAPH_JUCEHEADER__ | #define __JUCE_FILTERGRAPH_JUCEHEADER__ | ||||
| #include "../plugins/juce_AudioPluginInstance.h" | |||||
| #include "../plugins/juce_PluginDescription.h" | |||||
| class FilterInGraph; | class FilterInGraph; | ||||
| class FilterGraph; | class FilterGraph; | ||||
| class FilterGraphPlayer; | |||||
| const char* const filenameSuffix = ".filtergraph"; | const char* const filenameSuffix = ".filtergraph"; | ||||
| const char* const filenameWildcard = "*.filtergraph"; | const char* const filenameWildcard = "*.filtergraph"; | ||||
| @@ -75,7 +71,7 @@ private: | |||||
| /** | /** | ||||
| Represents one of the filters in a FilterGraph. | Represents one of the filters in a FilterGraph. | ||||
| */ | */ | ||||
| class FilterInGraph : public ReferenceCountedObject | |||||
| /*class FilterInGraph : public ReferenceCountedObject | |||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -129,7 +125,7 @@ private: | |||||
| FilterInGraph (const FilterInGraph&); | FilterInGraph (const FilterInGraph&); | ||||
| const FilterInGraph& operator= (const FilterInGraph&); | const FilterInGraph& operator= (const FilterInGraph&); | ||||
| }; | }; | ||||
| */ | |||||
| //============================================================================== | //============================================================================== | ||||
| /** | /** | ||||
| @@ -143,11 +139,12 @@ public: | |||||
| ~FilterGraph(); | ~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 addFilter (const PluginDescription* desc, double x, double y); | ||||
| void removeFilter (const uint32 filterUID); | void removeFilter (const uint32 filterUID); | ||||
| @@ -155,14 +152,15 @@ public: | |||||
| void removeIllegalConnections(); | 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, | bool canConnect (uint32 sourceFilterUID, int sourceFilterChannel, | ||||
| uint32 destFilterUID, int destFilterChannel) const throw(); | uint32 destFilterUID, int destFilterChannel) const throw(); | ||||
| @@ -177,6 +175,9 @@ public: | |||||
| void clear(); | void clear(); | ||||
| //============================================================================== | |||||
| XmlElement* createXml() const; | XmlElement* createXml() const; | ||||
| void restoreFromXml (const XmlElement& xml); | void restoreFromXml (const XmlElement& xml); | ||||
| @@ -195,14 +196,17 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | 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 lastUID; | ||||
| uint32 getNextUID() throw(); | uint32 getNextUID() throw(); | ||||
| bool isAnInputTo (const uint32 possibleInput, const uint32 possibleDestination, int recursionCheck) const throw(); | |||||
| void createNodeFromXml (const XmlElement& xml); | |||||
| FilterGraph (const FilterGraph&); | FilterGraph (const FilterGraph&); | ||||
| const FilterGraph& operator= (const FilterGraph&); | const FilterGraph& operator= (const FilterGraph&); | ||||
| @@ -213,7 +217,7 @@ private: | |||||
| /** | /** | ||||
| */ | */ | ||||
| class FilterGraphPlayer : public AudioIODeviceCallback, | |||||
| /*class FilterGraphPlayer : public AudioIODeviceCallback, | |||||
| public MidiInputCallback, | public MidiInputCallback, | ||||
| public ChangeListener | public ChangeListener | ||||
| @@ -274,6 +278,6 @@ private: | |||||
| FilterGraphPlayer (const FilterGraphPlayer&); | FilterGraphPlayer (const FilterGraphPlayer&); | ||||
| const FilterGraphPlayer& operator= (const FilterGraphPlayer&); | const FilterGraphPlayer& operator= (const FilterGraphPlayer&); | ||||
| }; | }; | ||||
| */ | |||||
| #endif | #endif | ||||
| @@ -35,6 +35,95 @@ | |||||
| #include "MainHostWindow.h" | #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, | class PinComponent : public Component, | ||||
| public SettableTooltipClient | public SettableTooltipClient | ||||
| @@ -47,16 +136,16 @@ public: | |||||
| index (index_), | index (index_), | ||||
| isInput (isInput_) | 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; | String tip; | ||||
| if (isInput) | if (isInput) | ||||
| tip = f->filter->getInputChannelName (index_); | |||||
| tip = node->processor->getInputChannelName (index_); | |||||
| else | else | ||||
| tip = f->filter->getOutputChannelName (index_); | |||||
| tip = node->processor->getOutputChannelName (index_); | |||||
| if (tip.isEmpty()) | if (tip.isEmpty()) | ||||
| { | { | ||||
| @@ -185,10 +274,15 @@ public: | |||||
| } | } | ||||
| else if (r == 3 || r == 4) | else if (r == 3 || r == 4) | ||||
| { | { | ||||
| FilterInGraph* const f = graph.getFilterForUID (filterID); | |||||
| AudioProcessorGraph::Node::Ptr f (graph.getNodeForId (filterID)); | |||||
| if (f != 0) | 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) | if (getParentComponent() != 0) | ||||
| getParentComponent()->globalPositionToRelative (x, y); | 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) | if (e.mouseWasClicked() && e.getNumberOfClicks() == 2) | ||||
| { | { | ||||
| const FilterInGraph::Ptr f (graph.getFilterForUID (filterID)); | |||||
| const AudioProcessorGraph::Node::Ptr f (graph.getNodeForId (filterID)); | |||||
| if (f != 0) | if (f != 0) | ||||
| f->showUI (false); | |||||
| { | |||||
| PluginWindow* const w = PluginWindow::getWindowFor (f, false); | |||||
| if (w != 0) | |||||
| w->toFront (true); | |||||
| } | |||||
| } | } | ||||
| else if (! e.mouseWasClicked()) | else if (! e.mouseWasClicked()) | ||||
| { | { | ||||
| @@ -295,7 +390,7 @@ public: | |||||
| void update() | void update() | ||||
| { | { | ||||
| const FilterInGraph* const f = graph.getFilterForUID (filterID); | |||||
| const AudioProcessorGraph::Node::Ptr f (graph.getNodeForId (filterID)); | |||||
| if (f == 0) | if (f == 0) | ||||
| { | { | ||||
| @@ -303,12 +398,12 @@ public: | |||||
| return; | return; | ||||
| } | } | ||||
| numIns = f->filter->getNumInputChannels(); | |||||
| if (f->filter->acceptsMidi()) | |||||
| numIns = f->processor->getNumInputChannels(); | |||||
| if (f->processor->acceptsMidi()) | |||||
| ++numIns; | ++numIns; | ||||
| numOuts = f->filter->getNumOutputChannels(); | |||||
| if (f->filter->producesMidi()) | |||||
| numOuts = f->processor->getNumOutputChannels(); | |||||
| if (f->processor->producesMidi()) | |||||
| ++numOuts; | ++numOuts; | ||||
| int w = 100; | int w = 100; | ||||
| @@ -316,14 +411,20 @@ public: | |||||
| w = jmax (w, (jmax (numIns, numOuts) + 1) * 20); | 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)); | w = jmax (w, 16 + jmin (textWidth, 300)); | ||||
| if (textWidth > 300) | if (textWidth > 300) | ||||
| h = 100; | h = 100; | ||||
| setSize (w, h); | 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) | if (numIns != numInputs || numOuts != numOutputs) | ||||
| { | { | ||||
| @@ -333,20 +434,18 @@ public: | |||||
| deleteAllChildren(); | deleteAllChildren(); | ||||
| int i; | 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)); | addAndMakeVisible (new PinComponent (graph, filterID, i, true)); | ||||
| if (f->filter->acceptsMidi()) | |||||
| if (f->processor->acceptsMidi()) | |||||
| addAndMakeVisible (new PinComponent (graph, filterID, FilterGraph::midiChannelNumber, true)); | 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)); | addAndMakeVisible (new PinComponent (graph, filterID, i, false)); | ||||
| if (f->filter->producesMidi()) | |||||
| if (f->processor->producesMidi()) | |||||
| addAndMakeVisible (new PinComponent (graph, filterID, FilterGraph::midiChannelNumber, false)); | addAndMakeVisible (new PinComponent (graph, filterID, FilterGraph::midiChannelNumber, false)); | ||||
| setName (f->filter->getName()); | |||||
| resized(); | resized(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -679,17 +778,17 @@ FilterComponent* GraphEditorPanel::getComponentForFilter (const uint32 filterID) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| ConnectorComponent* GraphEditorPanel::getComponentForConnection (const FilterConnection& conn) const | |||||
| ConnectorComponent* GraphEditorPanel::getComponentForConnection (const AudioProcessorGraph::Connection& conn) const | |||||
| { | { | ||||
| for (int i = getNumChildComponents(); --i >= 0;) | for (int i = getNumChildComponents(); --i >= 0;) | ||||
| { | { | ||||
| ConnectorComponent* const c = dynamic_cast <ConnectorComponent*> (getChildComponent (i)); | ConnectorComponent* const c = dynamic_cast <ConnectorComponent*> (getChildComponent (i)); | ||||
| if (c != 0 | 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; | return c; | ||||
| } | } | ||||
| @@ -759,11 +858,11 @@ void GraphEditorPanel::updateComponents() | |||||
| for (i = graph.getNumFilters(); --i >= 0;) | 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); | addAndMakeVisible (comp); | ||||
| comp->update(); | comp->update(); | ||||
| } | } | ||||
| @@ -771,15 +870,15 @@ void GraphEditorPanel::updateComponents() | |||||
| for (i = graph.getNumConnections(); --i >= 0;) | 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) | if (getComponentForConnection (*c) == 0) | ||||
| { | { | ||||
| ConnectorComponent* const comp = new ConnectorComponent (graph); | ConnectorComponent* const comp = new ConnectorComponent (graph); | ||||
| addAndMakeVisible (comp); | 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)); | 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)); | MidiKeyboardComponent::horizontalKeyboard)); | ||||
| addAndMakeVisible (statusBar = new TooltipBar()); | addAndMakeVisible (statusBar = new TooltipBar()); | ||||
| graphPlayer->setAudioDeviceManager (deviceManager); | |||||
| deviceManager->setAudioCallback (&graphPlayer); | |||||
| graphPanel->updateComponents(); | graphPanel->updateComponents(); | ||||
| } | } | ||||
| GraphDocumentComponent::~GraphDocumentComponent() | GraphDocumentComponent::~GraphDocumentComponent() | ||||
| { | { | ||||
| deviceManager->setAudioCallback (0); | |||||
| deleteAllChildren(); | deleteAllChildren(); | ||||
| graphPlayer->setAudioDeviceManager (0); | |||||
| deleteAndZero (graphPlayer); | |||||
| graphPlayer.setProcessor (0); | |||||
| keyState.removeListener (&graphPlayer.getMidiMessageCollector()); | |||||
| graph.clear(); | graph.clear(); | ||||
| } | } | ||||
| @@ -32,7 +32,6 @@ | |||||
| #ifndef __JUCE_FILTERGRAPHEDITOR_JUCEHEADER__ | #ifndef __JUCE_FILTERGRAPHEDITOR_JUCEHEADER__ | ||||
| #define __JUCE_FILTERGRAPHEDITOR_JUCEHEADER__ | #define __JUCE_FILTERGRAPHEDITOR_JUCEHEADER__ | ||||
| #include "../plugins/juce_KnownPluginList.h" | |||||
| #include "FilterGraph.h" | #include "FilterGraph.h" | ||||
| class FilterComponent; | class FilterComponent; | ||||
| @@ -57,7 +56,7 @@ public: | |||||
| void createNewPlugin (const PluginDescription* desc, int x, int y); | void createNewPlugin (const PluginDescription* desc, int x, int y); | ||||
| FilterComponent* getComponentForFilter (const uint32 filterID) const; | 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; | PinComponent* findPinAt (const int x, const int y) const; | ||||
| void resized(); | void resized(); | ||||
| @@ -110,12 +109,39 @@ public: | |||||
| private: | private: | ||||
| AudioDeviceManager* deviceManager; | AudioDeviceManager* deviceManager; | ||||
| FilterGraphPlayer* graphPlayer; | |||||
| AudioProcessorPlayer graphPlayer; | |||||
| MidiKeyboardState keyState; | |||||
| GraphEditorPanel* graphPanel; | GraphEditorPanel* graphPanel; | ||||
| Component* keyboardComp; | Component* keyboardComp; | ||||
| Component* statusBar; | 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 | #endif | ||||
| @@ -33,319 +33,22 @@ | |||||
| #include "InternalFilters.h" | #include "InternalFilters.h" | ||||
| #include "FilterGraph.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() | 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) | if (desc.name == audioOutDesc.name) | ||||
| { | { | ||||
| return new AudioOutputDeviceFilter (desc.numInputChannels); | |||||
| return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); | |||||
| } | } | ||||
| else if (desc.name == audioInDesc.name) | else if (desc.name == audioInDesc.name) | ||||
| { | { | ||||
| return new AudioInputDeviceFilter (desc.numOutputChannels); | |||||
| return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); | |||||
| } | } | ||||
| else if (desc.name == midiInDesc.name) | else if (desc.name == midiInDesc.name) | ||||
| { | { | ||||
| return new MidiInputDeviceFilter(); | |||||
| return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -33,7 +33,7 @@ | |||||
| #define __JUCE_MAINHOSTWINDOW_JUCEHEADER__xxxxx | #define __JUCE_MAINHOSTWINDOW_JUCEHEADER__xxxxx | ||||
| #include "FilterGraph.h" | #include "FilterGraph.h" | ||||
| #include "../plugins/juce_AudioPluginFormat.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| /** | /** | ||||
| @@ -32,7 +32,7 @@ | |||||
| #include "../../../../juce.h" | #include "../../../../juce.h" | ||||
| #include "MainHostWindow.h" | #include "MainHostWindow.h" | ||||
| #include "InternalFilters.h" | #include "InternalFilters.h" | ||||
| #include "../plugins/juce_PluginListComponent.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| class PluginListWindow : public DocumentWindow | class PluginListWindow : public DocumentWindow | ||||
| @@ -85,6 +85,13 @@ MainHostWindow::MainHostWindow() | |||||
| : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(), Colours::lightgrey, | : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(), Colours::lightgrey, | ||||
| DocumentWindow::allButtons) | DocumentWindow::allButtons) | ||||
| { | { | ||||
| XmlElement* const savedAudioState = ApplicationProperties::getInstance()->getUserSettings() | |||||
| ->getXmlValue (T("audioDeviceState")); | |||||
| deviceManager.initialise (256, 256, savedAudioState, true); | |||||
| delete savedAudioState; | |||||
| setResizable (true, false); | setResizable (true, false); | ||||
| setResizeLimits (500, 400, 10000, 10000); | setResizeLimits (500, 400, 10000, 10000); | ||||
| centreWithSize (800, 600); | centreWithSize (800, 600); | ||||
| @@ -104,13 +111,6 @@ MainHostWindow::MainHostWindow() | |||||
| InternalPluginFormat internalFormat; | InternalPluginFormat internalFormat; | ||||
| internalFormat.getAllTypes (internalTypes); | 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() | XmlElement* const savedPluginList = ApplicationProperties::getInstance() | ||||
| ->getUserSettings() | ->getUserSettings() | ||||
| ->getXmlValue (T("pluginList")); | ->getXmlValue (T("pluginList")); | ||||
| @@ -34,7 +34,6 @@ | |||||
| #include "FilterGraph.h" | #include "FilterGraph.h" | ||||
| #include "GraphEditorPanel.h" | #include "GraphEditorPanel.h" | ||||
| #include "../plugins/juce_KnownPluginList.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -105,3 +105,27 @@ void AudioPluginFormatManager::addFormat (AudioPluginFormat* const format) throw | |||||
| { | { | ||||
| formats.add (format); | 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; | |||||
| } | |||||
| @@ -146,6 +146,19 @@ public: | |||||
| */ | */ | ||||
| void addFormat (AudioPluginFormat* const format) throw(); | 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 | juce_UseDebuggingNewOperator | ||||
| @@ -60,6 +60,15 @@ PluginDescription* KnownPluginList::getTypeForFile (const File& file) const thro | |||||
| return 0; | 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) | bool KnownPluginList::addType (const PluginDescription& type) | ||||
| { | { | ||||
| for (int i = types.size(); --i >= 0;) | for (int i = types.size(); --i >= 0;) | ||||
| @@ -341,7 +350,7 @@ public: | |||||
| { | { | ||||
| PluginDescription* const plugin = plugins.getUnchecked(i); | PluginDescription* const plugin = plugins.getUnchecked(i); | ||||
| m.addItem (allPlugins.indexOf (plugin) + menuIdBase, | |||||
| m.addItem (allPlugins.indexOf (plugin) + menuIdBase, | |||||
| plugin->name, true, false); | plugin->name, true, false); | ||||
| } | } | ||||
| } | } | ||||
| @@ -74,6 +74,13 @@ public: | |||||
| */ | */ | ||||
| PluginDescription* getTypeForFile (const File& file) const throw(); | 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. */ | /** Adds a type manually from its description. */ | ||||
| bool addType (const PluginDescription& type); | bool addType (const PluginDescription& type); | ||||
| @@ -85,44 +85,11 @@ bool PluginDescription::isDuplicateOf (const PluginDescription& other) const | |||||
| && uid == other.uid; | && 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 | XmlElement* PluginDescription::createXml() const | ||||
| @@ -85,6 +85,8 @@ public: | |||||
| Note that this might not be unique between formats, e.g. a VST and some | Note that this might not be unique between formats, e.g. a VST and some | ||||
| other format might actually have the same id. | other format might actually have the same id. | ||||
| @see createIdentifierString | |||||
| */ | */ | ||||
| int uid; | int uid; | ||||
| @@ -111,17 +113,6 @@ public: | |||||
| */ | */ | ||||
| void fillInFromInstance (AudioPluginInstance& instance) throw(); | 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. | /** Creates an XML object containing these details. | ||||
| @@ -136,6 +127,16 @@ public: | |||||
| */ | */ | ||||
| bool loadFromXml (const XmlElement& xml); | 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 | juce_UseDebuggingNewOperator | ||||
| @@ -124,6 +124,16 @@ bool DemoJuceFilter::isOutputChannelStereoPair (int index) const | |||||
| return false; | return false; | ||||
| } | } | ||||
| bool DemoJuceFilter::acceptsMidi() const | |||||
| { | |||||
| return true; | |||||
| } | |||||
| bool DemoJuceFilter::producesMidi() const | |||||
| { | |||||
| return true; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void DemoJuceFilter::prepareToPlay (double sampleRate, int samplesPerBlock) | void DemoJuceFilter::prepareToPlay (double sampleRate, int samplesPerBlock) | ||||
| { | { | ||||
| @@ -71,6 +71,9 @@ public: | |||||
| bool isInputChannelStereoPair (int index) const; | bool isInputChannelStereoPair (int index) const; | ||||
| bool isOutputChannelStereoPair (int index) const; | bool isOutputChannelStereoPair (int index) const; | ||||
| bool acceptsMidi() const; | |||||
| bool producesMidi() const; | |||||
| //============================================================================== | //============================================================================== | ||||
| int getNumPrograms() { return 0; } | int getNumPrograms() { return 0; } | ||||
| int getCurrentProgram() { return 0; } | int getCurrentProgram() { return 0; } | ||||
| @@ -101,15 +101,14 @@ void AudioFilterStreamer::audioDeviceIOCallback (const float** inputChannelData, | |||||
| zeromem (outChans[numOutsWanted++], sizeof (float) * numSamples); | 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; | isPlaying = true; | ||||
| emptyBuffer.setSize (1 + filter.getNumOutputChannels(), | emptyBuffer.setSize (1 + filter.getNumOutputChannels(), | ||||
| jmax (2048, numSamplesPerBlock * 2)); | |||||
| jmax (2048, device->getCurrentBlockSizeSamples() * 2)); | |||||
| emptyBuffer.clear(); | emptyBuffer.clear(); | ||||
| midiCollector.reset (sampleRate); | midiCollector.reset (sampleRate); | ||||
| @@ -66,7 +66,7 @@ public: | |||||
| int totalNumOutputChannels, | int totalNumOutputChannels, | ||||
| int numSamples); | int numSamples); | ||||
| void audioDeviceAboutToStart (double sampleRate, int numSamplesPerBlock); | |||||
| void audioDeviceAboutToStart (AudioIODevice* device); | |||||
| void audioDeviceStopped(); | void audioDeviceStopped(); | ||||
| void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message); | void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message); | ||||
| @@ -32,7 +32,7 @@ | |||||
| 84EAE2F309DAAF0B00288D0A /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84EAE2F109DAAF0B00288D0A /* AGL.framework */; }; | 84EAE2F309DAAF0B00288D0A /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84EAE2F109DAAF0B00288D0A /* AGL.framework */; }; | ||||
| 84EAE2F409DAAF0B00288D0A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84EAE2F209DAAF0B00288D0A /* OpenGL.framework */; }; | 84EAE2F409DAAF0B00288D0A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84EAE2F209DAAF0B00288D0A /* OpenGL.framework */; }; | ||||
| 84F8DB0B099CA8DD00E911ED /* QuickTimeDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F8DB0A099CA8DD00E911ED /* QuickTimeDemo.cpp */; }; | 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 */; }; | 8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; }; | ||||
| 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; }; | 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; }; | ||||
| /* End PBXBuildFile section */ | /* 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; }; | 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>"; }; | 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>"; }; | 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 */ | /* End PBXFileReference section */ | ||||
| /* Begin PBXFrameworksBuildPhase section */ | /* Begin PBXFrameworksBuildPhase section */ | ||||
| @@ -85,7 +85,7 @@ | |||||
| isa = PBXFrameworksBuildPhase; | isa = PBXFrameworksBuildPhase; | ||||
| buildActionMask = 2147483647; | buildActionMask = 2147483647; | ||||
| files = ( | files = ( | ||||
| 84FDB0950C15BDDD00CD0087 /* libjucedebug.a in Frameworks */, | |||||
| 84FDB0950C15BDDD00CD0087 /* libjuce.a in Frameworks */, | |||||
| 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */, | 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */, | ||||
| 84C49F2606C0F3200066071B /* CoreAudio.framework in Frameworks */, | 84C49F2606C0F3200066071B /* CoreAudio.framework in Frameworks */, | ||||
| 84C4A41106C0F9A00066071B /* IOKit.framework in Frameworks */, | 84C4A41106C0F9A00066071B /* IOKit.framework in Frameworks */, | ||||
| @@ -181,7 +181,7 @@ | |||||
| 84FDB0900C15BDCE00CD0087 /* Products */ = { | 84FDB0900C15BDCE00CD0087 /* Products */ = { | ||||
| isa = PBXGroup; | isa = PBXGroup; | ||||
| children = ( | children = ( | ||||
| 84FDB0940C15BDCE00CD0087 /* libjucedebug.a */, | |||||
| 84FDB0940C15BDCE00CD0087 /* libjuce.a */, | |||||
| ); | ); | ||||
| name = Products; | name = Products; | ||||
| sourceTree = "<group>"; | sourceTree = "<group>"; | ||||
| @@ -244,10 +244,10 @@ | |||||
| /* End PBXProject section */ | /* End PBXProject section */ | ||||
| /* Begin PBXReferenceProxy section */ | /* Begin PBXReferenceProxy section */ | ||||
| 84FDB0940C15BDCE00CD0087 /* libjucedebug.a */ = { | |||||
| 84FDB0940C15BDCE00CD0087 /* libjuce.a */ = { | |||||
| isa = PBXReferenceProxy; | isa = PBXReferenceProxy; | ||||
| fileType = archive.ar; | fileType = archive.ar; | ||||
| path = libjucedebug.a; | |||||
| path = libjuce.a; | |||||
| remoteRef = 84FDB0930C15BDCE00CD0087 /* PBXContainerItemProxy */; | remoteRef = 84FDB0930C15BDCE00CD0087 /* PBXContainerItemProxy */; | ||||
| sourceTree = BUILT_PRODUCTS_DIR; | sourceTree = BUILT_PRODUCTS_DIR; | ||||
| }; | }; | ||||
| @@ -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,61,61,61,61,61,61,61, | ||||
| 61,61,61,61,61,61,61,61,61,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, | 61,61,61,61,61,61,61,61,61,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, | 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, | 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, | 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,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,61,61,61,61,61,61,61,61,61,61,61,61,61, | ||||
| 61,61,61,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,61,61,61,61, | ||||
| 61,61,61,61,61,61,61,61,61,61,61,61,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,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,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,61,61,61,61,61,61, | ||||
| 61,61,61,61,61,61,61,61,61,61,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; | 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, | 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, | ||||
| @@ -15,7 +15,7 @@ namespace BinaryData | |||||
| const int demo_table_data_xmlSize = 5239; | const int demo_table_data_xmlSize = 5239; | ||||
| extern const char* draganddropdemo_cpp; | extern const char* draganddropdemo_cpp; | ||||
| const int draganddropdemo_cppSize = 7873; | |||||
| const int draganddropdemo_cppSize = 7937; | |||||
| extern const char* fontsandtextdemo_cpp; | extern const char* fontsandtextdemo_cpp; | ||||
| const int fontsandtextdemo_cppSize = 9064; | const int fontsandtextdemo_cppSize = 9064; | ||||
| @@ -342,7 +342,7 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| void audioDeviceAboutToStart (double sampleRate, int numSamplesPerBlock) | |||||
| void audioDeviceAboutToStart (AudioIODevice*) | |||||
| { | { | ||||
| zeromem (circularBuffer, sizeof (float) * bufferSize); | zeromem (circularBuffer, sizeof (float) * bufferSize); | ||||
| } | } | ||||
| @@ -504,10 +504,10 @@ public: | |||||
| waveformComponent->audioDeviceIOCallback (inputChannelData, totalNumInputChannels, outputChannelData, totalNumOutputChannels, numSamples); | 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() | void audioDeviceStopped() | ||||
| @@ -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 | // 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 | // sort of object that you're interested in before returning true, but for | ||||
| @@ -342,7 +342,7 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| void audioDeviceAboutToStart (double sampleRate, int numSamplesPerBlock) | |||||
| void audioDeviceAboutToStart (AudioIODevice*) | |||||
| { | { | ||||
| zeromem (circularBuffer, sizeof (float) * bufferSize); | zeromem (circularBuffer, sizeof (float) * bufferSize); | ||||
| } | } | ||||
| @@ -504,10 +504,10 @@ public: | |||||
| waveformComponent->audioDeviceIOCallback (inputChannelData, totalNumInputChannels, outputChannelData, totalNumOutputChannels, numSamples); | 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() | void audioDeviceStopped() | ||||
| @@ -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 | // 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 | // sort of object that you're interested in before returning true, but for | ||||
| @@ -169,6 +169,7 @@ END_JUCE_NAMESPACE | |||||
| #pragma comment(lib, "ole32.lib") | #pragma comment(lib, "ole32.lib") | ||||
| #pragma comment(lib, "advapi32.lib") | #pragma comment(lib, "advapi32.lib") | ||||
| #pragma comment(lib, "ws2_32.lib") | #pragma comment(lib, "ws2_32.lib") | ||||
| #pragma comment(lib, "SetupAPI.Lib") | |||||
| //#pragma comment(lib, "gdiplus.lib") | //#pragma comment(lib, "gdiplus.lib") | ||||
| #if JUCE_OPENGL | #if JUCE_OPENGL | ||||
| @@ -137,6 +137,16 @@ | |||||
| #define JUCE_USE_XSHM 1 | #define JUCE_USE_XSHM 1 | ||||
| #endif | #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 | /** Disabling this will avoid linking to any UI code. This is handy for | ||||
| @@ -95,9 +95,15 @@ | |||||
| #ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ | #ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ | ||||
| #include "juce_appframework/audio/processors/juce_AudioProcessorEditor.h" | #include "juce_appframework/audio/processors/juce_AudioProcessorEditor.h" | ||||
| #endif | #endif | ||||
| #ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ | |||||
| #include "juce_appframework/audio/processors/juce_AudioProcessorGraph.h" | |||||
| #endif | |||||
| #ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ | #ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ | ||||
| #include "juce_appframework/audio/processors/juce_AudioProcessorListener.h" | #include "juce_appframework/audio/processors/juce_AudioProcessorListener.h" | ||||
| #endif | #endif | ||||
| #ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ | |||||
| #include "juce_appframework/audio/processors/juce_AudioProcessorPlayer.h" | |||||
| #endif | |||||
| #ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ | #ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ | ||||
| #include "juce_appframework/audio/processors/juce_GenericAudioProcessorEditor.h" | #include "juce_appframework/audio/processors/juce_GenericAudioProcessorEditor.h" | ||||
| #endif | #endif | ||||
| @@ -155,6 +161,39 @@ | |||||
| #ifndef __JUCE_SYNTHESISER_JUCEHEADER__ | #ifndef __JUCE_SYNTHESISER_JUCEHEADER__ | ||||
| #include "juce_appframework/audio/synthesisers/juce_Synthesiser.h" | #include "juce_appframework/audio/synthesisers/juce_Synthesiser.h" | ||||
| #endif | #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__ | #ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ | ||||
| #include "juce_appframework/audio/audio_file_formats/juce_AiffAudioFormat.h" | #include "juce_appframework/audio/audio_file_formats/juce_AiffAudioFormat.h" | ||||
| #endif | #endif | ||||
| @@ -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__ | |||||
| @@ -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__ | |||||
| @@ -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__ | |||||
| @@ -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__ | |||||
| @@ -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 | |||||
| @@ -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__ | |||||
| @@ -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 | |||||
| @@ -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__ | |||||
| @@ -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 | |||||
| @@ -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__ | |||||
| @@ -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 | |||||
| @@ -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__ | |||||
| @@ -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 | |||||
| @@ -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__ | |||||
| @@ -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 | |||||
| @@ -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__ | |||||
| @@ -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 | |||||
| @@ -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__ | |||||
| @@ -69,6 +69,11 @@ public: | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| virtual ~AudioProcessor(); | virtual ~AudioProcessor(); | ||||
| //============================================================================== | |||||
| /** Returns the name of this processor. | |||||
| */ | |||||
| virtual const String getName() const = 0; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Called before playback starts, to let the filter prepare itself. | /** Called before playback starts, to let the filter prepare itself. | ||||
| @@ -229,6 +234,12 @@ public: | |||||
| */ | */ | ||||
| void setLatencySamples (const int newLatency); | 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 | /** This returns a critical section that will automatically be locked while the host | ||||
| is calling the processBlock() method. | is calling the processBlock() method. | ||||
| @@ -535,6 +546,9 @@ private: | |||||
| #ifdef JUCE_DEBUG | #ifdef JUCE_DEBUG | ||||
| BitArray changingParams; | BitArray changingParams; | ||||
| #endif | #endif | ||||
| AudioProcessor (const AudioProcessor&); | |||||
| const AudioProcessor& operator= (const AudioProcessor&); | |||||
| }; | }; | ||||
| @@ -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__ | |||||
| @@ -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 | |||||
| @@ -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__ | |||||