diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile index 656eae35e93b946cafe53646a6345519d3cc5d37..b5ecbffed88b8f7aeeca4aff25715102b9398489 100644 --- a/Builds/Linux/Makefile +++ b/Builds/Linux/Makefile @@ -18,12 +18,12 @@ ifeq ($(CONFIG),Debug) TARGET_ARCH := -march=native endif - CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=0.3.3" -D "JUCE_APP_VERSION_HEX=0x303" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../JuceLibraryCode/modules + CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=0.3.4" -D "JUCE_APP_VERSION_HEX=0x304" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../JuceLibraryCode/modules CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O3 -export-dynamic -g -pg -std=c++0x CXXFLAGS += $(CFLAGS) LDFLAGS += $(TARGET_ARCH) -L$(BINDIR) -L$(LIBDIR) -L/usr/X11R6/lib/ -L/usr/local/include -lGL -lX11 -lXext -lXinerama -lasound -ldl -lfreetype -lpthread -lrt -pg -ldl -lXext -lGLU -lhdf5 -lhdf5_cpp LDDEPS := - RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=0.3.3" -D "JUCE_APP_VERSION_HEX=0x303" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../JuceLibraryCode/modules + RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=0.3.4" -D "JUCE_APP_VERSION_HEX=0x304" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../JuceLibraryCode/modules TARGET := open-ephys BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) CLEANCMD = rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) @@ -39,12 +39,12 @@ ifeq ($(CONFIG),Release) TARGET_ARCH := -march=native endif - CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=0.3.3" -D "JUCE_APP_VERSION_HEX=0x303" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../JuceLibraryCode/modules + CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=0.3.4" -D "JUCE_APP_VERSION_HEX=0x304" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../JuceLibraryCode/modules CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3 -export-dynamic -g -pg -std=c++0x CXXFLAGS += $(CFLAGS) LDFLAGS += $(TARGET_ARCH) -L$(BINDIR) -L$(LIBDIR) -fvisibility=hidden -L/usr/X11R6/lib/ -lGL -lX11 -lXext -lXinerama -lasound -ldl -lfreetype -lpthread -lrt -pg -ldl -lXext -lGLU -lhdf5 -lhdf5_cpp LDDEPS := - RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=0.3.3" -D "JUCE_APP_VERSION_HEX=0x303" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../JuceLibraryCode/modules + RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=0.3.4" -D "JUCE_APP_VERSION_HEX=0x304" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../JuceLibraryCode/modules TARGET := open-ephys-release BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) CLEANCMD = rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) @@ -58,7 +58,6 @@ OBJECTS := \ $(OBJDIR)/ArduinoOutputEditor_e1b7e52b.o \ $(OBJDIR)/AudioEditor_3931be27.o \ $(OBJDIR)/AudioNode_3db3557c.o \ - $(OBJDIR)/AudioResamplingNode_bdba71b0.o \ $(OBJDIR)/Channel_5cb2d4d2.o \ $(OBJDIR)/ChannelMappingEditor_9b145f15.o \ $(OBJDIR)/ChannelMappingNode_ec0559ea.o \ @@ -70,8 +69,6 @@ OBJECTS := \ $(OBJDIR)/rhd2000evalboard_e0b412d5.o \ $(OBJDIR)/rhd2000registers_cf6cd63b.o \ $(OBJDIR)/RHD2000Thread_23e0b041.o \ - $(OBJDIR)/FileReaderThread_933ea08.o \ - $(OBJDIR)/FPGAThread_a8dc34ed.o \ $(OBJDIR)/DataBuffer_6ae4f549.o \ $(OBJDIR)/DataThread_b2a47a13.o \ $(OBJDIR)/Bessel_7e54cb27.o \ @@ -107,15 +104,10 @@ OBJECTS := \ $(OBJDIR)/FileReaderEditor_e1193ff7.o \ $(OBJDIR)/FilterEditor_93e366f5.o \ $(OBJDIR)/FilterNode_d2b4d9ca.o \ - $(OBJDIR)/FPGAOutput_9ccd34ea.o \ - $(OBJDIR)/FPGAOutputEditor_749d7837.o \ $(OBJDIR)/GenericProcessor_3e79932a.o \ $(OBJDIR)/LfpDisplayCanvas_9bbf9660.o \ $(OBJDIR)/LfpDisplayEditor_e7c32ff5.o \ $(OBJDIR)/LfpDisplayNode_fdf2e2ca.o \ - $(OBJDIR)/LfpTriggeredAverageCanvas_5ba95b5e.o \ - $(OBJDIR)/LfpTriggeredAverageEditor_a7acf4f3.o \ - $(OBJDIR)/LfpTriggeredAverageNode_2ee5cf48.o \ $(OBJDIR)/Merger_53fb4e4a.o \ $(OBJDIR)/MergerEditor_e36b0997.o \ $(OBJDIR)/MessageCenter_bd1ba084.o \ @@ -139,8 +131,6 @@ OBJECTS := \ $(OBJDIR)/PeriStimulusTimeHistogramNode_9631ca2a.o \ $(OBJDIR)/tictoc_cdca1ed.o \ $(OBJDIR)/TrialCircularBuffer_4a4cef0c.o \ - $(OBJDIR)/ReferenceNode_97454f26.o \ - $(OBJDIR)/ReferenceNodeEditor_7d0ff573.o \ $(OBJDIR)/ResamplingNode_9825590a.o \ $(OBJDIR)/ResamplingNodeEditor_8b120457.o \ $(OBJDIR)/PulsePal_14932a18.o \ @@ -166,8 +156,6 @@ OBJECTS := \ $(OBJDIR)/DataWindow_83ce6754.o \ $(OBJDIR)/SpikeObject_24e8c655.o \ $(OBJDIR)/MatlabLikePlot_fb09c37f.o \ - $(OBJDIR)/WiFiOutput_416d244a.o \ - $(OBJDIR)/WiFiOutputEditor_ada45f97.o \ $(OBJDIR)/EcubeDialogComponent_2ec3bd57.o \ $(OBJDIR)/CustomArrowButton_206e4278.o \ $(OBJDIR)/GraphViewer_e43fd2ce.o \ @@ -250,11 +238,6 @@ $(OBJDIR)/AudioNode_3db3557c.o: ../../Source/Processors/AudioNode/AudioNode.cpp @echo "Compiling AudioNode.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/AudioResamplingNode_bdba71b0.o: ../../Source/Processors/AudioResamplingNode/AudioResamplingNode.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling AudioResamplingNode.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/Channel_5cb2d4d2.o: ../../Source/Processors/Channel/Channel.cpp -@mkdir -p $(OBJDIR) @echo "Compiling Channel.cpp" @@ -310,16 +293,6 @@ $(OBJDIR)/RHD2000Thread_23e0b041.o: ../../Source/Processors/DataThreads/RHD2000T @echo "Compiling RHD2000Thread.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/FileReaderThread_933ea08.o: ../../Source/Processors/DataThreads/FileReaderThread.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling FileReaderThread.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/FPGAThread_a8dc34ed.o: ../../Source/Processors/DataThreads/FPGAThread.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling FPGAThread.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/DataBuffer_6ae4f549.o: ../../Source/Processors/DataThreads/DataBuffer.cpp -@mkdir -p $(OBJDIR) @echo "Compiling DataBuffer.cpp" @@ -495,16 +468,6 @@ $(OBJDIR)/FilterNode_d2b4d9ca.o: ../../Source/Processors/FilterNode/FilterNode.c @echo "Compiling FilterNode.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/FPGAOutput_9ccd34ea.o: ../../Source/Processors/FPGAOutput/FPGAOutput.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling FPGAOutput.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/FPGAOutputEditor_749d7837.o: ../../Source/Processors/FPGAOutput/FPGAOutputEditor.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling FPGAOutputEditor.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/GenericProcessor_3e79932a.o: ../../Source/Processors/GenericProcessor/GenericProcessor.cpp -@mkdir -p $(OBJDIR) @echo "Compiling GenericProcessor.cpp" @@ -525,21 +488,6 @@ $(OBJDIR)/LfpDisplayNode_fdf2e2ca.o: ../../Source/Processors/LfpDisplayNode/LfpD @echo "Compiling LfpDisplayNode.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/LfpTriggeredAverageCanvas_5ba95b5e.o: ../../Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageCanvas.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling LfpTriggeredAverageCanvas.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/LfpTriggeredAverageEditor_a7acf4f3.o: ../../Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageEditor.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling LfpTriggeredAverageEditor.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/LfpTriggeredAverageNode_2ee5cf48.o: ../../Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling LfpTriggeredAverageNode.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/Merger_53fb4e4a.o: ../../Source/Processors/Merger/Merger.cpp -@mkdir -p $(OBJDIR) @echo "Compiling Merger.cpp" @@ -655,16 +603,6 @@ $(OBJDIR)/TrialCircularBuffer_4a4cef0c.o: ../../Source/Processors/PSTH/TrialCirc @echo "Compiling TrialCircularBuffer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/ReferenceNode_97454f26.o: ../../Source/Processors/ReferenceNode/ReferenceNode.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling ReferenceNode.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/ReferenceNodeEditor_7d0ff573.o: ../../Source/Processors/ReferenceNode/ReferenceNodeEditor.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling ReferenceNodeEditor.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/ResamplingNode_9825590a.o: ../../Source/Processors/ResamplingNode/ResamplingNode.cpp -@mkdir -p $(OBJDIR) @echo "Compiling ResamplingNode.cpp" @@ -790,16 +728,6 @@ $(OBJDIR)/MatlabLikePlot_fb09c37f.o: ../../Source/Processors/Visualization/Matla @echo "Compiling MatlabLikePlot.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/WiFiOutput_416d244a.o: ../../Source/Processors/WiFiOutput/WiFiOutput.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling WiFiOutput.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/WiFiOutputEditor_ada45f97.o: ../../Source/Processors/WiFiOutput/WiFiOutputEditor.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling WiFiOutputEditor.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/EcubeDialogComponent_2ec3bd57.o: ../../Source/UI/EcubeDialogComponent.cpp -@mkdir -p $(OBJDIR) @echo "Compiling EcubeDialogComponent.cpp" diff --git a/Builds/MacOSX/Info.plist b/Builds/MacOSX/Info.plist index 5db847465d67cce80fe1330283aca27cb95a772a..c9fa38de1f2a137aee04e5040b8fd9e1ee9b2980 100644 --- a/Builds/MacOSX/Info.plist +++ b/Builds/MacOSX/Info.plist @@ -16,9 +16,9 @@ <key>CFBundleSignature</key> <string>????</string> <key>CFBundleShortVersionString</key> - <string>0.3.3</string> + <string>0.3.4</string> <key>CFBundleVersion</key> - <string>0.3.3</string> + <string>0.3.4</string> <key>NSHumanReadableCopyright</key> <string>Open Ephys</string> <key>NSHighResolutionCapable</key> diff --git a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj index 14c951fc1ab6172abf13715164f2efb1117c75d5..67ceb869433dc3be1e29c8c791c48fcd5c619ed2 100644 --- a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj @@ -28,7 +28,6 @@ 527EB48A4A9C2F4FF1BC4FB2 = {isa = PBXBuildFile; fileRef = E850C14F13F9855CE1E14C1A; }; 8352817FEDC7542D3E65B49A = {isa = PBXBuildFile; fileRef = DA4EAC64A750D0C3DEE83C5D; }; 44DB81313BDDF1ECB6AD33FE = {isa = PBXBuildFile; fileRef = 1F22CC8D992B8B49D57DDB3F; }; - 64FC0EA0C132341C1C3E98E1 = {isa = PBXBuildFile; fileRef = 41E88094E8D929866A6DCA9A; }; C45009DBCD71E9E234BFCE97 = {isa = PBXBuildFile; fileRef = FA8CC6FD54A9F20DA755F2EA; }; E6038800731F7C747D181A51 = {isa = PBXBuildFile; fileRef = D0105584D551FED59203CC84; }; FFCA1C44C024BCA1878F49FE = {isa = PBXBuildFile; fileRef = 25CEC111DFEC71FA6828257F; }; @@ -40,8 +39,6 @@ DA836EC803E4FF4EDEBE6386 = {isa = PBXBuildFile; fileRef = 2D2BAC4320470CF68743F58E; }; 702C9BFCE865CB6C6B8BFB0D = {isa = PBXBuildFile; fileRef = 5DB3B3197F8C1E5EE159D6FC; }; 739573501D1D440A72C5C2E5 = {isa = PBXBuildFile; fileRef = A3FB0EA0264580F6B00D993B; }; - 955561F4FF4484648FDB9F73 = {isa = PBXBuildFile; fileRef = 1718EC50691D8421EC00F8B3; }; - 6B67D7B6301182C7621294B6 = {isa = PBXBuildFile; fileRef = FA23A1334E4CFA77BC18A153; }; FAE745870674A07A65690433 = {isa = PBXBuildFile; fileRef = 788F8B7719B70465762B634B; }; 24CC7E9A7E87F762D4AB0467 = {isa = PBXBuildFile; fileRef = 92602D7166325C7232B85EDD; }; 9252537C12447F047243DEE9 = {isa = PBXBuildFile; fileRef = 041038F6E67FE0409D8ECC74; }; @@ -77,15 +74,10 @@ 24800AF87AD21CE652552EDE = {isa = PBXBuildFile; fileRef = 56F810EF10E01535A417B671; }; 0203D029CE7420984F737E51 = {isa = PBXBuildFile; fileRef = 414969AEF838522C9FE1B807; }; 3BAE3A1FD0834E798B8602BF = {isa = PBXBuildFile; fileRef = 9AA19ECEFE2B49832ECEED2F; }; - 1A415CE073017DDDA7F2E234 = {isa = PBXBuildFile; fileRef = 4448875C40EAB061B2F8A289; }; - 63B3CC385B0988C7ABA3B07B = {isa = PBXBuildFile; fileRef = AB4D72F040FF59BED08826EC; }; B49852F77C0C392C159A1914 = {isa = PBXBuildFile; fileRef = C5654EAA7B65445CF1340983; }; 9F431DA23C92CA0F8E3A2A28 = {isa = PBXBuildFile; fileRef = D9BF6DA66C22FFF5C4D41991; }; BFFD23BD72ECEC9E54936061 = {isa = PBXBuildFile; fileRef = 88C69F0563A99BD2F7BF5FBB; }; FA882EEE408CBBDC7BD90F14 = {isa = PBXBuildFile; fileRef = 1C64C490BD7FE9E57D6C682D; }; - 0E62780F9978861D5D2BCF71 = {isa = PBXBuildFile; fileRef = CC9134D38EBEC67112CA7502; }; - E13848868678C0655147C59D = {isa = PBXBuildFile; fileRef = 20DBF92457AF75C0698D1B26; }; - 01646F263C203BB412580CB8 = {isa = PBXBuildFile; fileRef = FA12F07F4F9C872C18A2817B; }; 6D00BABD3FE1AA0EAA267C1C = {isa = PBXBuildFile; fileRef = 07B84F46CF90D04BB6B673C5; }; AD371C6F383F03EF392B6581 = {isa = PBXBuildFile; fileRef = BAA5B3AD1A27F8C4D37A6869; }; 4EF2825142BBAA76FD55FE26 = {isa = PBXBuildFile; fileRef = BC1543B1F822FEEDCB9AC26D; }; @@ -109,8 +101,6 @@ 093F0BA37D6C91C7E92AB658 = {isa = PBXBuildFile; fileRef = 25B9B8D5E54B9C547197E414; }; 620CF6292EFB911F15916EA6 = {isa = PBXBuildFile; fileRef = 547C76794FAC1BC349163509; }; 7B50AD44D4F9610CE4A43414 = {isa = PBXBuildFile; fileRef = FB827FEEA15A274E5F7577DB; }; - A5A90525A975EC3B1E40086E = {isa = PBXBuildFile; fileRef = D9B10885C9D93CEF580EF167; }; - 79FC643530710BF2885932C1 = {isa = PBXBuildFile; fileRef = 6D4D435D25CFC019E0FCF4A1; }; 69B5045877D4C674E8A4967F = {isa = PBXBuildFile; fileRef = E102C308B0722DFFFEFF2415; }; 97105BCBC5B1BE4E86D48899 = {isa = PBXBuildFile; fileRef = 55DFE30C901793E56A7E3A22; }; 790911EDF00A4BF77327D99A = {isa = PBXBuildFile; fileRef = 48E12736F471C43C959AD15C; }; @@ -136,8 +126,6 @@ 1B620FC17AAECA4C5DE741E2 = {isa = PBXBuildFile; fileRef = 66463AB11EA4D6341C32F27E; }; 19BB86C918F89D1377F8A0E1 = {isa = PBXBuildFile; fileRef = 5894D40A0E8FA6E9B3EBF9D9; }; 89223664B6CB2A912E36B091 = {isa = PBXBuildFile; fileRef = F115ED75E977A54AAF036B2C; }; - AEE1F2B70ED51F7AFEF4E93B = {isa = PBXBuildFile; fileRef = B25949076F9BB831C5862415; }; - 74D0CA6935D890153FB58C56 = {isa = PBXBuildFile; fileRef = 3734FF118787377E4C8741D1; }; 8F39AD3F7938EFE82D06E89F = {isa = PBXBuildFile; fileRef = AF28CAB9C7531EF7422602E1; }; BA608CEFC85F7AB9E30E0EB3 = {isa = PBXBuildFile; fileRef = F960CC94B136201BDA148EEA; }; D499273B65D901D0A101CAAA = {isa = PBXBuildFile; fileRef = E5C1D021C0FD6FAD082C5D75; }; @@ -194,7 +182,6 @@ 06072EC6BCD3B7D8C17C2402 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessor.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"; sourceTree = "SOURCE_ROOT"; }; 078625CF5C083AD538D23401 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioCDReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; 0790CCE2FCFDFA6944DFC402 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; - 07A8ED74417654C40F9EFEFC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FPGAOutput.h; path = ../../Source/Processors/FPGAOutput/FPGAOutput.h; sourceTree = "SOURCE_ROOT"; }; 07B84F46CF90D04BB6B673C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Merger.cpp; path = ../../Source/Processors/Merger/Merger.cpp; sourceTree = "SOURCE_ROOT"; }; 07FD5E530E9E6BFB2ACA4B8C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_formats.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.h"; sourceTree = "SOURCE_ROOT"; }; 081E86FE0B991469CFA8D7EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CPlusPlusCodeTokeniser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -265,7 +252,6 @@ 167524110873F9888CF1B9E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandID.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"; sourceTree = "SOURCE_ROOT"; }; 168823A9EBD85BFBFD2CE2EE = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons-03.png"; path = "../../Resources/Images/Icons/RadioButtons-03.png"; sourceTree = "SOURCE_ROOT"; }; 1712916024EC787B6C231732 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected_over-03.png"; path = "../../Resources/Images/Icons/RadioButtons_selected_over-03.png"; sourceTree = "SOURCE_ROOT"; }; - 1718EC50691D8421EC00F8B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FileReaderThread.cpp; path = ../../Source/Processors/DataThreads/FileReaderThread.cpp; sourceTree = "SOURCE_ROOT"; }; 1719507D8A73EA71F1C3F306 = {isa = PBXFileReference; lastKnownFileType = file; name = "cpmono-plain-serialized"; path = "../../Resources/Fonts/cpmono-plain-serialized"; sourceTree = "SOURCE_ROOT"; }; 172FA5C9EC4B16BC0C45F269 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Variant.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_Variant.h"; sourceTree = "SOURCE_ROOT"; }; 174842EA681FA29BE38A6272 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -313,7 +299,6 @@ 205E9A5C31827555F1CAC30D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_osx.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_osx.h"; sourceTree = "SOURCE_ROOT"; }; 208DCD7025D0DF2740C01E4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; 20BB146B925C4D4AD43BA479 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = State.cpp; path = ../../Source/Processors/Dsp/State.cpp; sourceTree = "SOURCE_ROOT"; }; - 20DBF92457AF75C0698D1B26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LfpTriggeredAverageEditor.cpp; path = ../../Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageEditor.cpp; sourceTree = "SOURCE_ROOT"; }; 20EB4F22A76954F2986F364A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Windowing.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; 215B159836CE40810964B773 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Uuid.h"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Uuid.h"; sourceTree = "SOURCE_ROOT"; }; 215E1BD79B5870D5356810F0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Visualizer.h; path = ../../Source/Processors/Visualization/Visualizer.h; sourceTree = "SOURCE_ROOT"; }; @@ -322,7 +307,6 @@ 21C11A58CAA0F9E86AA204EC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Slider.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.h"; sourceTree = "SOURCE_ROOT"; }; 21D3C1095D2B5A834D998B74 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_OpenSL.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_android_OpenSL.cpp"; sourceTree = "SOURCE_ROOT"; }; 222AC2E9BEFE12BE7FF88879 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Thread.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Thread.cpp"; sourceTree = "SOURCE_ROOT"; }; - 22FAA3DA9944AA853D66114F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LfpTriggeredAverageCanvas.h; path = ../../Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageCanvas.h; sourceTree = "SOURCE_ROOT"; }; 235A8987D99A191D07208D2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = okFrontPanelDLL.cpp; path = "../../Source/Processors/DataThreads/rhythm-api/okFrontPanelDLL.cpp"; sourceTree = "SOURCE_ROOT"; }; 23609D430A25F54723269E91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_basics.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; }; 23A6BA852B71DAAF3F709428 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RHD2000Thread.h; path = ../../Source/Processors/DataThreads/RHD2000Thread.h; sourceTree = "SOURCE_ROOT"; }; @@ -401,7 +385,6 @@ 36332333DBF8363163F454E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = HDF5Recording.cpp; path = ../../Source/Processors/RecordNode/HDF5Recording.cpp; sourceTree = "SOURCE_ROOT"; }; 3663C981D28BF165C1B601A7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OptionalScopedPointer.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_OptionalScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; 36A9736F04AAA2F8E9D711BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SpinLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_SpinLock.h"; sourceTree = "SOURCE_ROOT"; }; - 3734FF118787377E4C8741D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = WiFiOutputEditor.cpp; path = ../../Source/Processors/WiFiOutput/WiFiOutputEditor.cpp; sourceTree = "SOURCE_ROOT"; }; 3753B3B311AE0A9F4CC5AD40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ofArduino.cpp; path = ../../Source/Processors/Serial/ofArduino.cpp; sourceTree = "SOURCE_ROOT"; }; 3774BBCA6CB133D9A854CF71 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CustomLookAndFeel.cpp; path = ../../Source/UI/CustomLookAndFeel.cpp; sourceTree = "SOURCE_ROOT"; }; 381F5DC605AE69088004DF80 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "PipelineB-01.png"; path = "../../Resources/Images/Buttons/PipelineB-01.png"; sourceTree = "SOURCE_ROOT"; }; @@ -458,7 +441,6 @@ 414D8E6E4EE98E66C2583A50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; 416B99B14B44CB16B725C4B2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableObjectResizer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h"; sourceTree = "SOURCE_ROOT"; }; 41AF61914A96159E9EA194B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Clipboard.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp"; sourceTree = "SOURCE_ROOT"; }; - 41E88094E8D929866A6DCA9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioResamplingNode.cpp; path = ../../Source/Processors/AudioResamplingNode/AudioResamplingNode.cpp; sourceTree = "SOURCE_ROOT"; }; 420843E39C285B620B220C1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LeakedObjectDetector.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_LeakedObjectDetector.h"; sourceTree = "SOURCE_ROOT"; }; 420B0E95F1300ABFDC125DBF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AccessClass.cpp; path = ../../Source/AccessClass.cpp; sourceTree = "SOURCE_ROOT"; }; 42BF0530EADF336E58D39CD3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FloatVectorOperations.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h"; sourceTree = "SOURCE_ROOT"; }; @@ -466,7 +448,6 @@ 434E153E6C8337C1E4A2709A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; 442F01DC974E1EAC57450906 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PoleFilter.h; path = ../../Source/Processors/Dsp/PoleFilter.h; sourceTree = "SOURCE_ROOT"; }; 4434939E139A45962C8CFB4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableShape.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4448875C40EAB061B2F8A289 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FPGAOutput.cpp; path = ../../Source/Processors/FPGAOutput/FPGAOutput.cpp; sourceTree = "SOURCE_ROOT"; }; 449B26D1265BB91B331EFF84 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = HDF5FileFormat.h; path = ../../Source/Processors/RecordNode/HDF5FileFormat.h; sourceTree = "SOURCE_ROOT"; }; 44E04E5F584A8BFAD062A09D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ShapeButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.h"; sourceTree = "SOURCE_ROOT"; }; 45258533F9F65AC96D3080B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTouchMapper.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_MultiTouchMapper.h"; sourceTree = "SOURCE_ROOT"; }; @@ -531,7 +512,6 @@ 50DD8D693741DD18106C0BA7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentListener.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.h"; sourceTree = "SOURCE_ROOT"; }; 510ACDAD798813D7FC110197 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedComponent.h"; sourceTree = "SOURCE_ROOT"; }; 511C443A0A806706A772E981 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Primes.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.cpp"; sourceTree = "SOURCE_ROOT"; }; - 513D20023796491A24EC58A7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WiFiOutputEditor.h; path = ../../Source/Processors/WiFiOutput/WiFiOutputEditor.h; sourceTree = "SOURCE_ROOT"; }; 515213CC3271E8DEA8125D33 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicLibrary.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_DynamicLibrary.h"; sourceTree = "SOURCE_ROOT"; }; 515C4C8AC20EA25F3DEF2336 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LuaCodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; 51926BEEA63BF141D93A5B36 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePoint.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -545,7 +525,6 @@ 5343D594AA7D444A7C6AD924 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPDecompressorInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h"; sourceTree = "SOURCE_ROOT"; }; 5379FC603780F30A2F05FE78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AsyncUpdater.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.h"; sourceTree = "SOURCE_ROOT"; }; 53C8A2696FE4389E4AB4441C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Slider.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.cpp"; sourceTree = "SOURCE_ROOT"; }; - 540CD9ED0C719DB1DAECA37E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WiFiOutput.h; path = ../../Source/Processors/WiFiOutput/WiFiOutput.h; sourceTree = "SOURCE_ROOT"; }; 54339ADDCB6F8E9E7721A986 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; 547C76794FAC1BC349163509 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = tictoc.cpp; path = ../../Source/Processors/PSTH/tictoc.cpp; sourceTree = "SOURCE_ROOT"; }; 54B7796F6DCF5531789CCF43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Types.h; path = ../../Source/Processors/Dsp/Types.h; sourceTree = "SOURCE_ROOT"; }; @@ -600,7 +579,6 @@ 5E0F8A60411A03461FD687CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GroupComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_GroupComponent.h"; sourceTree = "SOURCE_ROOT"; }; 5E1EFF4EEA5684FA00CAA353 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableBorderComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h"; sourceTree = "SOURCE_ROOT"; }; 5E5098D437FC0612291567AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Documentation.cpp; path = ../../Source/Processors/Dsp/Documentation.cpp; sourceTree = "SOURCE_ROOT"; }; - 5E5736CB6D96D5271F1A7597 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioResamplingNode.h; path = ../../Source/Processors/AudioResamplingNode/AudioResamplingNode.h; sourceTree = "SOURCE_ROOT"; }; 5E663D5A55F191AB92A1383F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.h"; sourceTree = "SOURCE_ROOT"; }; 5E94E897783BEEFE61E61A2C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; 5EA566ED87CC02EA6DF1993B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilterEditor.h; path = ../../Source/Processors/FilterNode/FilterEditor.h; sourceTree = "SOURCE_ROOT"; }; @@ -646,7 +624,6 @@ 670987D88775D6B240C34820 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NotificationType.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_NotificationType.h"; sourceTree = "SOURCE_ROOT"; }; 674FDCCEF6A1379A0F689004 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBoundsConstrainer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h"; sourceTree = "SOURCE_ROOT"; }; 677CC8DA903C77D8ECBAE26D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Params.h; path = ../../Source/Processors/Dsp/Params.h; sourceTree = "SOURCE_ROOT"; }; - 679BBE9F6C930A1941BA7944 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ReferenceNode.h; path = ../../Source/Processors/ReferenceNode/ReferenceNode.h; sourceTree = "SOURCE_ROOT"; }; 67BB47E709B643D4C01AB34C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDeviceSelectorComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; 6832130272774CD542793762 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CoreGraphicsContext.mm"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm"; sourceTree = "SOURCE_ROOT"; }; 686FA8DDF2848517CBFB9E4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseCursor.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -672,7 +649,6 @@ 6D34DD9AB987A67BADE71C65 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons-05.png"; path = "../../Resources/Images/Icons/RadioButtons-05.png"; sourceTree = "SOURCE_ROOT"; }; 6D38B76951D31D96F1B71E0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SerialInputEditor.cpp; path = ../../Source/Processors/SerialInput/SerialInputEditor.cpp; sourceTree = "SOURCE_ROOT"; }; 6D4BA4399FDEB6D2195B257D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SplashScreen.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SplashScreen.h"; sourceTree = "SOURCE_ROOT"; }; - 6D4D435D25CFC019E0FCF4A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ReferenceNodeEditor.cpp; path = ../../Source/Processors/ReferenceNode/ReferenceNodeEditor.cpp; sourceTree = "SOURCE_ROOT"; }; 6D4DFC260B2966E3EBFC0C79 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SliderPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; 6D619C7A3A14981DC4EFF223 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilterAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; 6D77949E9C7C9B5A7795C0E0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathStrokeType.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.h"; sourceTree = "SOURCE_ROOT"; }; @@ -799,14 +775,12 @@ 8689288B66B16EFB106CB2F4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextInputTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h"; sourceTree = "SOURCE_ROOT"; }; 86E8E44A13F17083ED300BD5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeListener.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeListener.h"; sourceTree = "SOURCE_ROOT"; }; 86F4AAFCE3FEB34E325F3020 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_ComSmartPtr.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h"; sourceTree = "SOURCE_ROOT"; }; - 8751DF970A9E3598683BACAF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FPGAThread.h; path = ../../Source/Processors/DataThreads/FPGAThread.h; sourceTree = "SOURCE_ROOT"; }; 879B0383EF2A8B116903A500 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageCache.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.h"; sourceTree = "SOURCE_ROOT"; }; 87B4BA68E49DD11197B7AFDB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; }; 87C0534EAC82E887E1D354C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Butterworth.h; path = ../../Source/Processors/Dsp/Butterworth.h; sourceTree = "SOURCE_ROOT"; }; 880CC7C325EFF665AC3006D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyListener.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"; sourceTree = "SOURCE_ROOT"; }; 881237D5E366342B117C0ED7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WildcardFileFilter.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_WildcardFileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; 8822ADC9DB83FAF39B841E31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Font.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp"; sourceTree = "SOURCE_ROOT"; }; - 883E23B392AFB86C3EE1A2AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ReferenceNodeEditor.h; path = ../../Source/Processors/ReferenceNode/ReferenceNodeEditor.h; sourceTree = "SOURCE_ROOT"; }; 8882F8EBE55F52FA8E519249 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Files.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; 88C69F0563A99BD2F7BF5FBB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LfpDisplayEditor.cpp; path = ../../Source/Processors/LfpDisplayNode/LfpDisplayEditor.cpp; sourceTree = "SOURCE_ROOT"; }; 88E5D0906646465409715828 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PreferencesPanel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -875,7 +849,6 @@ 949422DF0532222450E95926 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = RecordNode.cpp; path = ../../Source/Processors/RecordNode/RecordNode.cpp; sourceTree = "SOURCE_ROOT"; }; 94BD861806F8EA598EC09370 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableCornerComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; 95A64508FF3D0140D3001A19 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ArduinoOutput.cpp; path = ../../Source/Processors/ArduinoOutput/ArduinoOutput.cpp; sourceTree = "SOURCE_ROOT"; }; - 95B57108E929DD11F898B7B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FileReaderThread.h; path = ../../Source/Processors/DataThreads/FileReaderThread.h; sourceTree = "SOURCE_ROOT"; }; 95EC6B1536DC65070D0ADCEE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ListBox.h"; sourceTree = "SOURCE_ROOT"; }; 967138FE8A086734ADC8CABB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Value.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp"; sourceTree = "SOURCE_ROOT"; }; 96E99CD031BD069997E387FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiBuffer.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -964,7 +937,6 @@ AADBA8C0AD524CE677428AFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; AAF5C27D2EEDD254A3652717 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Bessel.h; path = ../../Source/Processors/Dsp/Bessel.h; sourceTree = "SOURCE_ROOT"; }; AB4C7059669AC385B02179C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileLogger.h"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h"; sourceTree = "SOURCE_ROOT"; }; - AB4D72F040FF59BED08826EC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FPGAOutputEditor.cpp; path = ../../Source/Processors/FPGAOutput/FPGAOutputEditor.cpp; sourceTree = "SOURCE_ROOT"; }; ABA3FCD5D762336535D56D94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedLock.h"; sourceTree = "SOURCE_ROOT"; }; AC116E6590D49AB2EF19CB9E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLImage.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLImage.cpp"; sourceTree = "SOURCE_ROOT"; }; AC9E30922A14330704FB2573 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDisplayNode.cpp; path = ../../Source/Processors/SpikeDisplayNode/SpikeDisplayNode.cpp; sourceTree = "SOURCE_ROOT"; }; @@ -976,7 +948,6 @@ AD7D35FCD8CF66B6C393A7F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; AD960F561259904BA68DDA73 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedFile.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_MemoryMappedFile.h"; sourceTree = "SOURCE_ROOT"; }; ADCB42E4C5641007A4B78025 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeObject.h; path = ../../Source/Processors/Visualization/SpikeObject.h; sourceTree = "SOURCE_ROOT"; }; - ADCEA06868A5085B60487AC3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LfpTriggeredAverageEditor.h; path = ../../Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageEditor.h; sourceTree = "SOURCE_ROOT"; }; AE1EA04666EAD34D0CA0373D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_opengl.h"; path = "../../JuceLibraryCode/modules/juce_opengl/juce_opengl.h"; sourceTree = "SOURCE_ROOT"; }; AE1FC768C646A0EFEC3E3A11 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeDisplayNode.h; path = ../../Source/Processors/SpikeDisplayNode/SpikeDisplayNode.h; sourceTree = "SOURCE_ROOT"; }; AE3D7946F13CE32AE41DD1B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MatlabLikePlot.h; path = ../../Source/Processors/Visualization/MatlabLikePlot.h; sourceTree = "SOURCE_ROOT"; }; @@ -1016,7 +987,6 @@ B2241E3C5C9F93389586F357 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryIterator.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.h"; sourceTree = "SOURCE_ROOT"; }; B23E6EBB5F99CF7FC72FAC4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VisualizerEditor.h; path = ../../Source/Processors/Editors/VisualizerEditor.h; sourceTree = "SOURCE_ROOT"; }; B24098EC4FD79D5EDC9383EC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Initialisation.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/application/juce_Initialisation.h"; sourceTree = "SOURCE_ROOT"; }; - B25949076F9BB831C5862415 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = WiFiOutput.cpp; path = ../../Source/Processors/WiFiOutput/WiFiOutput.cpp; sourceTree = "SOURCE_ROOT"; }; B2EF409A1F459E964756BA7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; B2F72769CF14BD7F882E9542 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LfpDisplayNode.h; path = ../../Source/Processors/LfpDisplayNode/LfpDisplayNode.h; sourceTree = "SOURCE_ROOT"; }; B2FA9CC4754E136F22281176 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageEffectFilter.h"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_ImageEffectFilter.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1138,7 +1108,6 @@ CC35C78D5B446ABF57DDDAE0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageFileFormat.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.h"; sourceTree = "SOURCE_ROOT"; }; CC42C4D4230BE4F1071CB2D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableEdgeComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h"; sourceTree = "SOURCE_ROOT"; }; CC62E20B1189C697DD238810 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_linux.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_linux.h"; sourceTree = "SOURCE_ROOT"; }; - CC9134D38EBEC67112CA7502 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LfpTriggeredAverageCanvas.cpp; path = ../../Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageCanvas.cpp; sourceTree = "SOURCE_ROOT"; }; CCE779E203974113A80D6D85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = tictoc.h; path = ../../Source/Processors/PSTH/tictoc.h; sourceTree = "SOURCE_ROOT"; }; CD2E26CFD0DC7F6090E15A20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Line.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Line.h"; sourceTree = "SOURCE_ROOT"; }; CD41C1D09F6D73FA33993F45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Desktop.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1197,7 +1166,6 @@ D8AFDCC674A7514B7019EEA6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.h"; sourceTree = "SOURCE_ROOT"; }; D952A208CC8164F0B459EC9E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; D960588B732D973B82500E2D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorListener.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h"; sourceTree = "SOURCE_ROOT"; }; - D9B10885C9D93CEF580EF167 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ReferenceNode.cpp; path = ../../Source/Processors/ReferenceNode/ReferenceNode.cpp; sourceTree = "SOURCE_ROOT"; }; D9BF6DA66C22FFF5C4D41991 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LfpDisplayCanvas.cpp; path = ../../Source/Processors/LfpDisplayNode/LfpDisplayCanvas.cpp; sourceTree = "SOURCE_ROOT"; }; D9C9FCA6D705B72B80DB1142 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Socket.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp"; sourceTree = "SOURCE_ROOT"; }; D9CB4CEC2C07346BE69262A0 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected-01.png"; path = "../../Resources/Images/Icons/RadioButtons_selected-01.png"; sourceTree = "SOURCE_ROOT"; }; @@ -1213,7 +1181,6 @@ DB4FF7675E5C98CF62DA8A2E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AccessClass.h; path = ../../Source/AccessClass.h; sourceTree = "SOURCE_ROOT"; }; DB550BAB034060FF4578BB64 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_basics.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h"; sourceTree = "SOURCE_ROOT"; }; DB7866AFC8A4894810DBD05E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterProcessLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_InterProcessLock.h"; sourceTree = "SOURCE_ROOT"; }; - DBAB7848C770895CED4E2F95 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LfpTriggeredAverageNode.h; path = ../../Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.h; sourceTree = "SOURCE_ROOT"; }; DBB769DEBCD6468C13A3CD25 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; DBCA7E2FFCFD1354DD19DDD6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_data_structures.mm"; path = "../../JuceLibraryCode/modules/juce_data_structures/juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; }; DBED17FBB262C4DACEEDA9B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiKeyboardState.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1275,31 +1242,29 @@ E7ACE8C1456403A574236451 = {isa = PBXFileReference; lastKnownFileType = file; name = "cpmono-bold-serialized"; path = "../../Resources/Fonts/cpmono-bold-serialized"; sourceTree = "SOURCE_ROOT"; }; E7EE416EF527C7506B499070 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BigInteger.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.h"; sourceTree = "SOURCE_ROOT"; }; E835BEB3C42E4B241804BE13 = {isa = PBXFileReference; lastKnownFileType = file; name = "cpmono-light-serialized"; path = "../../Resources/Fonts/cpmono-light-serialized"; sourceTree = "SOURCE_ROOT"; }; + E849E3966302E7D4D06712F5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = RecordControl.cpp; path = ../../Source/Processors/RecordControl/RecordControl.cpp; sourceTree = "SOURCE_ROOT"; }; E850C14F13F9855CE1E14C1A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ArduinoOutputEditor.cpp; path = ../../Source/Processors/ArduinoOutput/ArduinoOutputEditor.cpp; sourceTree = "SOURCE_ROOT"; }; - E91A272EF06892937CB4B9CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentDragger.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"; sourceTree = "SOURCE_ROOT"; }; + E8964C0BE264A55753BC6B7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; + E91923510CB2280C3A3B9E9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; }; E946426F95E0240683CB3337 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; }; - EA2FC92CECD1EDA1F07DC59C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; }; - ED86166920362E9D2BE2CB26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SVGParser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp"; sourceTree = "SOURCE_ROOT"; }; - EDAC82BD742A54182E8DF2FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinatePositioner.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h"; sourceTree = "SOURCE_ROOT"; }; - EE0336B43A39FD585DF638EE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableEdgeComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - EE4DD055D31F7D9DC718DBD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentMovementWatcher.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"; sourceTree = "SOURCE_ROOT"; }; + EA354D7D8E48D461415D52D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; + EA9518CDEA7049C21D5CE2D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Process.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Process.h"; sourceTree = "SOURCE_ROOT"; }; + EAB6A66678B122C578B16445 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; + EAC262A83CD2BEA14542AE89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPool.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.h"; sourceTree = "SOURCE_ROOT"; }; + EAEA49B9394D802B79CA8164 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; + EDA209B0E7D124EA581023AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatManager.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; + EF3F9AA8D70E1D4D55F13182 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioThumbnail.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp"; sourceTree = "SOURCE_ROOT"; }; F5A00ACFA3D76168F22F1205 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 99E1BC08B886CFDD2CCFD462 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "open-ephys.app"; sourceTree = "BUILT_PRODUCTS_DIR"; }; - E849E3966302E7D4D06712F5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = RecordControl.cpp; path = ../../Source/Processors/RecordControl/RecordControl.cpp; sourceTree = "SOURCE_ROOT"; }; - E8964C0BE264A55753BC6B7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; E8D51D470C9955D7D03D5469 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ChebyshevII.h; path = ../../Source/Processors/Dsp/ChebyshevII.h; sourceTree = "SOURCE_ROOT"; }; - E91923510CB2280C3A3B9E9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; }; + E91A272EF06892937CB4B9CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentDragger.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"; sourceTree = "SOURCE_ROOT"; }; E93BE115650B1CB80EACB841 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = EditorViewportButtons.h; path = ../../Source/UI/EditorViewportButtons.h; sourceTree = "SOURCE_ROOT"; }; E97684DCE824DEDA6683C6CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Synthesiser.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"; sourceTree = "SOURCE_ROOT"; }; - EA354D7D8E48D461415D52D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; + EA2FC92CECD1EDA1F07DC59C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; }; EA73332E3D5AEC04ADDFBB2A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; }; - EA9518CDEA7049C21D5CE2D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Process.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Process.h"; sourceTree = "SOURCE_ROOT"; }; EAB2319C7AA57E06A2247CDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; }; EAB637B566FEBBDADA654262 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; }; - EAB6A66678B122C578B16445 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; - EAC262A83CD2BEA14542AE89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPool.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.h"; sourceTree = "SOURCE_ROOT"; }; EAC7A64301F0BF2C5E33A1F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnectionServer.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp"; sourceTree = "SOURCE_ROOT"; }; - EAEA49B9394D802B79CA8164 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; EB5F9A50EB53A57D6AE303C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_QuickTimeMovieComponent.mm"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_mac_QuickTimeMovieComponent.mm"; sourceTree = "SOURCE_ROOT"; }; EBD8622EAEF10558809888B7 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected_over-01.png"; path = "../../Resources/Images/Icons/RadioButtons_selected_over-01.png"; sourceTree = "SOURCE_ROOT"; }; EC95A2CF4B33EA37DA5FC1AC = {isa = PBXFileReference; lastKnownFileType = file.ttf; name = nordic.ttf; path = ../../Resources/Fonts/nordic.ttf; sourceTree = "SOURCE_ROOT"; }; @@ -1307,14 +1272,15 @@ ECBEF88BBC974D96ED781C75 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_posix_SharedCode.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h"; sourceTree = "SOURCE_ROOT"; }; ECCE033FF2ACE42188FA4A7F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TemporaryFile.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.h"; sourceTree = "SOURCE_ROOT"; }; ECE3BE71EB6B9CF1CE869BBE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/misc/juce_BubbleComponent.h"; sourceTree = "SOURCE_ROOT"; }; - ED0955C4DE64766A7F5F96F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FPGAOutputEditor.h; path = ../../Source/Processors/FPGAOutput/FPGAOutputEditor.h; sourceTree = "SOURCE_ROOT"; }; + ED86166920362E9D2BE2CB26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SVGParser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp"; sourceTree = "SOURCE_ROOT"; }; ED887A521EEB8F3EBA7DDB31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODeviceType.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h"; sourceTree = "SOURCE_ROOT"; }; - EDA209B0E7D124EA581023AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatManager.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; + EDAC82BD742A54182E8DF2FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinatePositioner.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h"; sourceTree = "SOURCE_ROOT"; }; + EE0336B43A39FD585DF638EE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableEdgeComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; EE2C669B127D00C86B1B8CA8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Registry.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Registry.cpp"; sourceTree = "SOURCE_ROOT"; }; + EE4DD055D31F7D9DC718DBD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentMovementWatcher.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"; sourceTree = "SOURCE_ROOT"; }; EEA51B7EF1CF19028C6672E0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DocumentWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; EEFC66D2DF5FD66B4D83B22F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Component.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.h"; sourceTree = "SOURCE_ROOT"; }; EF059B26886B32000BCF8CFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInputSource.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInputSource.h"; sourceTree = "SOURCE_ROOT"; }; - EF3F9AA8D70E1D4D55F13182 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioThumbnail.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp"; sourceTree = "SOURCE_ROOT"; }; EF4A6E0E1232071252ACCD7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; EF610B2A17D9B1C0D24DCE67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_android_JNIHelpers.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_JNIHelpers.h"; sourceTree = "SOURCE_ROOT"; }; EF7B66764093D950724EFE70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLShaderProgram.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1360,9 +1326,7 @@ F960CC94B136201BDA148EEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CustomArrowButton.cpp; path = ../../Source/UI/CustomArrowButton.cpp; sourceTree = "SOURCE_ROOT"; }; F9E2371F1A99B292F2947FF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; F9F37AD1C3E7CA932FF44E69 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LagrangeInterpolator.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp"; sourceTree = "SOURCE_ROOT"; }; - FA12F07F4F9C872C18A2817B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LfpTriggeredAverageNode.cpp; path = ../../Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.cpp; sourceTree = "SOURCE_ROOT"; }; FA1F1E9C7DEA48CAE6C247F4 = {isa = PBXFileReference; lastKnownFileType = image.png; name = OpenEphysBoardLogoGray.png; path = ../../Resources/Images/Icons/OpenEphysBoardLogoGray.png; sourceTree = "SOURCE_ROOT"; }; - FA23A1334E4CFA77BC18A153 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FPGAThread.cpp; path = ../../Source/Processors/DataThreads/FPGAThread.cpp; sourceTree = "SOURCE_ROOT"; }; FA2F04BA4E146ABF649BBE89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = rhd2000evalboard.h; path = "../../Source/Processors/DataThreads/rhythm-api/rhd2000evalboard.h"; sourceTree = "SOURCE_ROOT"; }; FA8CC6FD54A9F20DA755F2EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Channel.cpp; path = ../../Source/Processors/Channel/Channel.cpp; sourceTree = "SOURCE_ROOT"; }; FAC7E62CC15CA977A6FC72D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChangeBroadcaster.cpp"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1479,9 +1443,6 @@ C15024C101ECE85FDDCD770D, 1F22CC8D992B8B49D57DDB3F, 19B08AF9187EC45ECDE87602, ); name = AudioNode; sourceTree = "<group>"; }; - 7BE07AA81C59DD7252F709E6 = {isa = PBXGroup; children = ( - 41E88094E8D929866A6DCA9A, - 5E5736CB6D96D5271F1A7597, ); name = AudioResamplingNode; sourceTree = "<group>"; }; B3EC4C17E1555DCD89B1B62C = {isa = PBXGroup; children = ( FA8CC6FD54A9F20DA755F2EA, 74BAC33D6BC1D961F04DCC72, ); name = Channel; sourceTree = "<group>"; }; @@ -1509,10 +1470,6 @@ EBA825AF6FDB51EBA368CB8D, A3FB0EA0264580F6B00D993B, 23A6BA852B71DAAF3F709428, - 1718EC50691D8421EC00F8B3, - 95B57108E929DD11F898B7B1, - FA23A1334E4CFA77BC18A153, - 8751DF970A9E3598683BACAF, 788F8B7719B70465762B634B, F09FD6D9CA4997216ADBF54F, 92602D7166325C7232B85EDD, @@ -1595,11 +1552,6 @@ 5EA566ED87CC02EA6DF1993B, 9AA19ECEFE2B49832ECEED2F, 70651FEF347D8DE167B68EB8, ); name = FilterNode; sourceTree = "<group>"; }; - 85403FACC153147273CEB933 = {isa = PBXGroup; children = ( - 4448875C40EAB061B2F8A289, - 07A8ED74417654C40F9EFEFC, - AB4D72F040FF59BED08826EC, - ED0955C4DE64766A7F5F96F2, ); name = FPGAOutput; sourceTree = "<group>"; }; 5FAE90CAD8DAA5CE48855F38 = {isa = PBXGroup; children = ( C5654EAA7B65445CF1340983, 012F05BBF926C8F39AC7871B, ); name = GenericProcessor; sourceTree = "<group>"; }; @@ -1610,13 +1562,6 @@ E04512D01D2F6FE00C336CAD, 1C64C490BD7FE9E57D6C682D, B2F72769CF14BD7F882E9542, ); name = LfpDisplayNode; sourceTree = "<group>"; }; - 518310F63C8005A8D097A1D8 = {isa = PBXGroup; children = ( - CC9134D38EBEC67112CA7502, - 22FAA3DA9944AA853D66114F, - 20DBF92457AF75C0698D1B26, - ADCEA06868A5085B60487AC3, - FA12F07F4F9C872C18A2817B, - DBAB7848C770895CED4E2F95, ); name = LfpTriggeredAverageNode; sourceTree = "<group>"; }; A1678CA8F8E882F5D7EFDB3E = {isa = PBXGroup; children = ( 07B84F46CF90D04BB6B673C5, CA50A6F43BD78D01A8BE974B, @@ -1673,11 +1618,6 @@ CCE779E203974113A80D6D85, FB827FEEA15A274E5F7577DB, 76D8904379362E11CA4EA11D, ); name = PSTH; sourceTree = "<group>"; }; - 21389ED521B378402213EFC3 = {isa = PBXGroup; children = ( - D9B10885C9D93CEF580EF167, - 679BBE9F6C930A1941BA7944, - 6D4D435D25CFC019E0FCF4A1, - 883E23B392AFB86C3EE1A2AC, ); name = ReferenceNode; sourceTree = "<group>"; }; 456FCC98D03DFAE9AFEC271B = {isa = PBXGroup; children = ( E102C308B0722DFFFEFF2415, B574136FEE7957F7439CB346, @@ -1740,15 +1680,9 @@ 215E1BD79B5870D5356810F0, F115ED75E977A54AAF036B2C, AE3D7946F13CE32AE41DD1B7, ); name = Visualization; sourceTree = "<group>"; }; - 552D8D8CC92277F54C95F760 = {isa = PBXGroup; children = ( - B25949076F9BB831C5862415, - 540CD9ED0C719DB1DAECA37E, - 3734FF118787377E4C8741D1, - 513D20023796491A24EC58A7, ); name = WiFiOutput; sourceTree = "<group>"; }; 83A3E005DDFCC55F277EEDA5 = {isa = PBXGroup; children = ( 9C8E3549A602E74DCFC44244, 9C7703C01E449614C1CD884D, - 7BE07AA81C59DD7252F709E6, B3EC4C17E1555DCD89B1B62C, 3EE4DBB6ED04E5B9DA85CDF9, DEA24DC5AC8325310FB40395, @@ -1758,10 +1692,8 @@ AE49B2C17B100D5B4F81F694, 10488A99117FC063889F25C7, 1C714E881A404D148C6170CD, - 85403FACC153147273CEB933, 5FAE90CAD8DAA5CE48855F38, 29B817DBDA971F3DA7039F93, - 518310F63C8005A8D097A1D8, A1678CA8F8E882F5D7EFDB3E, F12EEDE785E2D38F654AE1B1, 2AC55A2E70C6CF50A8C46F6B, @@ -1772,7 +1704,6 @@ 0E7092A11A3C96E5ECA71CDA, 2206667D18B61DE29C856408, 70AFD6EB1539BF938821F7A8, - 21389ED521B378402213EFC3, 456FCC98D03DFAE9AFEC271B, 3DE49DED45C5CDD8D184E248, C451C93CE8C359C1A4BD23C7, @@ -1782,8 +1713,7 @@ 7B2364D82845C97E7A1B1924, D3F8D770C9E60B5BA2CCBC68, E2624A71F15AE5C96B34505B, - C4B85C0286AC2510730355E3, - 552D8D8CC92277F54C95F760, ); name = Processors; sourceTree = "<group>"; }; + C4B85C0286AC2510730355E3, ); name = Processors; sourceTree = "<group>"; }; 1D78FCCF430CD91FD1DBD95B = {isa = PBXGroup; children = ( AF28CAB9C7531EF7422602E1, A186E03EC7A6A7E657F38300, @@ -2931,8 +2861,8 @@ "_DEBUG=1", "DEBUG=1", "JUCER_XCODE_MAC_F6D2F4CF=1", - "JUCE_APP_VERSION=0.3.3", - "JUCE_APP_VERSION_HEX=0x303", ); + "JUCE_APP_VERSION=0.3.4", + "JUCE_APP_VERSION_HEX=0x304", ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../JuceLibraryCode/modules", "/opt/local/include", "/usr/local/include", "$(inherited)"); INFOPLIST_FILE = Info.plist; @@ -2953,8 +2883,8 @@ "_NDEBUG=1", "NDEBUG=1", "JUCER_XCODE_MAC_F6D2F4CF=1", - "JUCE_APP_VERSION=0.3.3", - "JUCE_APP_VERSION_HEX=0x303", ); + "JUCE_APP_VERSION=0.3.4", + "JUCE_APP_VERSION_HEX=0x304", ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../JuceLibraryCode/modules", "/opt/local/include", "/usr/local/include", "$(inherited)"); @@ -3012,7 +2942,6 @@ 527EB48A4A9C2F4FF1BC4FB2, 8352817FEDC7542D3E65B49A, 44DB81313BDDF1ECB6AD33FE, - 64FC0EA0C132341C1C3E98E1, C45009DBCD71E9E234BFCE97, E6038800731F7C747D181A51, FFCA1C44C024BCA1878F49FE, @@ -3024,8 +2953,6 @@ DA836EC803E4FF4EDEBE6386, 702C9BFCE865CB6C6B8BFB0D, 739573501D1D440A72C5C2E5, - 955561F4FF4484648FDB9F73, - 6B67D7B6301182C7621294B6, FAE745870674A07A65690433, 24CC7E9A7E87F762D4AB0467, 9252537C12447F047243DEE9, @@ -3061,15 +2988,10 @@ 24800AF87AD21CE652552EDE, 0203D029CE7420984F737E51, 3BAE3A1FD0834E798B8602BF, - 1A415CE073017DDDA7F2E234, - 63B3CC385B0988C7ABA3B07B, B49852F77C0C392C159A1914, 9F431DA23C92CA0F8E3A2A28, BFFD23BD72ECEC9E54936061, FA882EEE408CBBDC7BD90F14, - 0E62780F9978861D5D2BCF71, - E13848868678C0655147C59D, - 01646F263C203BB412580CB8, 6D00BABD3FE1AA0EAA267C1C, AD371C6F383F03EF392B6581, 4EF2825142BBAA76FD55FE26, @@ -3093,8 +3015,6 @@ 093F0BA37D6C91C7E92AB658, 620CF6292EFB911F15916EA6, 7B50AD44D4F9610CE4A43414, - A5A90525A975EC3B1E40086E, - 79FC643530710BF2885932C1, 69B5045877D4C674E8A4967F, 97105BCBC5B1BE4E86D48899, 790911EDF00A4BF77327D99A, @@ -3120,8 +3040,6 @@ 1B620FC17AAECA4C5DE741E2, 19BB86C918F89D1377F8A0E1, 89223664B6CB2A912E36B091, - AEE1F2B70ED51F7AFEF4E93B, - 74D0CA6935D890153FB58C56, 8F39AD3F7938EFE82D06E89F, BA608CEFC85F7AB9E30E0EB3, D499273B65D901D0A101CAAA, diff --git a/Builds/VisualStudio2012/open-ephys.vcxproj b/Builds/VisualStudio2012/open-ephys.vcxproj index a5d50392bfc83a22fa091a8af9c18449b81b8876..1096a85715e768cea0a9d2678b818c6ca66a8bf9 100644 --- a/Builds/VisualStudio2012/open-ephys.vcxproj +++ b/Builds/VisualStudio2012/open-ephys.vcxproj @@ -89,7 +89,7 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.3;JUCE_APP_VERSION_HEX=0x303;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.4;JUCE_APP_VERSION_HEX=0x304;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> <PrecompiledHeader/> @@ -135,7 +135,7 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.3;JUCE_APP_VERSION_HEX=0x303;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.4;JUCE_APP_VERSION_HEX=0x304;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> <PrecompiledHeader/> @@ -183,7 +183,7 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.3;JUCE_APP_VERSION_HEX=0x303;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.4;JUCE_APP_VERSION_HEX=0x304;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> <PrecompiledHeader/> @@ -227,7 +227,7 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.3;JUCE_APP_VERSION_HEX=0x303;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=0.3.4;JUCE_APP_VERSION_HEX=0x304;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> <PrecompiledHeader/> @@ -270,7 +270,6 @@ <ClCompile Include="..\..\Source\Processors\ArduinoOutput\ArduinoOutputEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\AudioNode\AudioEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\AudioNode\AudioNode.cpp"/> - <ClCompile Include="..\..\Source\Processors\AudioResamplingNode\AudioResamplingNode.cpp"/> <ClCompile Include="..\..\Source\Processors\Channel\Channel.cpp"/> <ClCompile Include="..\..\Source\Processors\ChannelMappingNode\ChannelMappingEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\ChannelMappingNode\ChannelMappingNode.cpp"/> @@ -282,8 +281,6 @@ <ClCompile Include="..\..\Source\Processors\DataThreads\rhythm-api\rhd2000evalboard.cpp"/> <ClCompile Include="..\..\Source\Processors\DataThreads\rhythm-api\rhd2000registers.cpp"/> <ClCompile Include="..\..\Source\Processors\DataThreads\RHD2000Thread.cpp"/> - <ClCompile Include="..\..\Source\Processors\DataThreads\FileReaderThread.cpp"/> - <ClCompile Include="..\..\Source\Processors\DataThreads\FPGAThread.cpp"/> <ClCompile Include="..\..\Source\Processors\DataThreads\DataBuffer.cpp"/> <ClCompile Include="..\..\Source\Processors\DataThreads\DataThread.cpp"/> <ClCompile Include="..\..\Source\Processors\Dsp\Bessel.cpp"/> @@ -319,15 +316,10 @@ <ClCompile Include="..\..\Source\Processors\FileReader\FileReaderEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\FilterNode\FilterEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\FilterNode\FilterNode.cpp"/> - <ClCompile Include="..\..\Source\Processors\FPGAOutput\FPGAOutput.cpp"/> - <ClCompile Include="..\..\Source\Processors\FPGAOutput\FPGAOutputEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\GenericProcessor\GenericProcessor.cpp"/> <ClCompile Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayCanvas.cpp"/> <ClCompile Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.cpp"/> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageCanvas.cpp"/> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageEditor.cpp"/> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageNode.cpp"/> <ClCompile Include="..\..\Source\Processors\Merger\Merger.cpp"/> <ClCompile Include="..\..\Source\Processors\Merger\MergerEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\MessageCenter\MessageCenter.cpp"/> @@ -351,8 +343,6 @@ <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.cpp"/> <ClCompile Include="..\..\Source\Processors\PSTH\tictoc.cpp"/> <ClCompile Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.cpp"/> - <ClCompile Include="..\..\Source\Processors\ReferenceNode\ReferenceNode.cpp"/> - <ClCompile Include="..\..\Source\Processors\ReferenceNode\ReferenceNodeEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\ResamplingNode\ResamplingNode.cpp"/> <ClCompile Include="..\..\Source\Processors\ResamplingNode\ResamplingNodeEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\Serial\PulsePal.cpp"/> @@ -378,8 +368,6 @@ <ClCompile Include="..\..\Source\Processors\Visualization\DataWindow.cpp"/> <ClCompile Include="..\..\Source\Processors\Visualization\SpikeObject.cpp"/> <ClCompile Include="..\..\Source\Processors\Visualization\MatlabLikePlot.cpp"/> - <ClCompile Include="..\..\Source\Processors\WiFiOutput\WiFiOutput.cpp"/> - <ClCompile Include="..\..\Source\Processors\WiFiOutput\WiFiOutputEditor.cpp"/> <ClCompile Include="..\..\Source\UI\EcubeDialogComponent.cpp"/> <ClCompile Include="..\..\Source\UI\CustomArrowButton.cpp"/> <ClCompile Include="..\..\Source\UI\GraphViewer.cpp"/> @@ -1525,7 +1513,6 @@ <ClInclude Include="..\..\Source\Processors\ArduinoOutput\ArduinoOutputEditor.h"/> <ClInclude Include="..\..\Source\Processors\AudioNode\AudioEditor.h"/> <ClInclude Include="..\..\Source\Processors\AudioNode\AudioNode.h"/> - <ClInclude Include="..\..\Source\Processors\AudioResamplingNode\AudioResamplingNode.h"/> <ClInclude Include="..\..\Source\Processors\Channel\Channel.h"/> <ClInclude Include="..\..\Source\Processors\ChannelMappingNode\ChannelMappingEditor.h"/> <ClInclude Include="..\..\Source\Processors\ChannelMappingNode\ChannelMappingNode.h"/> @@ -1537,8 +1524,6 @@ <ClInclude Include="..\..\Source\Processors\DataThreads\rhythm-api\rhd2000evalboard.h"/> <ClInclude Include="..\..\Source\Processors\DataThreads\rhythm-api\rhd2000registers.h"/> <ClInclude Include="..\..\Source\Processors\DataThreads\RHD2000Thread.h"/> - <ClInclude Include="..\..\Source\Processors\DataThreads\FileReaderThread.h"/> - <ClInclude Include="..\..\Source\Processors\DataThreads\FPGAThread.h"/> <ClInclude Include="..\..\Source\Processors\DataThreads\DataBuffer.h"/> <ClInclude Include="..\..\Source\Processors\DataThreads\DataThread.h"/> <ClInclude Include="..\..\Source\Processors\Dsp\Bessel.h"/> @@ -1580,15 +1565,10 @@ <ClInclude Include="..\..\Source\Processors\FileReader\FileReaderEditor.h"/> <ClInclude Include="..\..\Source\Processors\FilterNode\FilterEditor.h"/> <ClInclude Include="..\..\Source\Processors\FilterNode\FilterNode.h"/> - <ClInclude Include="..\..\Source\Processors\FPGAOutput\FPGAOutput.h"/> - <ClInclude Include="..\..\Source\Processors\FPGAOutput\FPGAOutputEditor.h"/> <ClInclude Include="..\..\Source\Processors\GenericProcessor\GenericProcessor.h"/> <ClInclude Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayCanvas.h"/> <ClInclude Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayEditor.h"/> <ClInclude Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.h"/> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageCanvas.h"/> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageEditor.h"/> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageNode.h"/> <ClInclude Include="..\..\Source\Processors\Merger\Merger.h"/> <ClInclude Include="..\..\Source\Processors\Merger\MergerEditor.h"/> <ClInclude Include="..\..\Source\Processors\MessageCenter\MessageCenter.h"/> @@ -1612,8 +1592,6 @@ <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.h"/> <ClInclude Include="..\..\Source\Processors\PSTH\tictoc.h"/> <ClInclude Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.h"/> - <ClInclude Include="..\..\Source\Processors\ReferenceNode\ReferenceNode.h"/> - <ClInclude Include="..\..\Source\Processors\ReferenceNode\ReferenceNodeEditor.h"/> <ClInclude Include="..\..\Source\Processors\ResamplingNode\ResamplingNode.h"/> <ClInclude Include="..\..\Source\Processors\ResamplingNode\ResamplingNodeEditor.h"/> <ClInclude Include="..\..\Source\Processors\Serial\PulsePal.h"/> @@ -1641,8 +1619,6 @@ <ClInclude Include="..\..\Source\Processors\Visualization\SpikeObject.h"/> <ClInclude Include="..\..\Source\Processors\Visualization\Visualizer.h"/> <ClInclude Include="..\..\Source\Processors\Visualization\MatlabLikePlot.h"/> - <ClInclude Include="..\..\Source\Processors\WiFiOutput\WiFiOutput.h"/> - <ClInclude Include="..\..\Source\Processors\WiFiOutput\WiFiOutputEditor.h"/> <ClInclude Include="..\..\Source\UI\EcubeDialogComponent.h"/> <ClInclude Include="..\..\Source\UI\CustomArrowButton.h"/> <ClInclude Include="..\..\Source\UI\GraphViewer.h"/> diff --git a/Builds/VisualStudio2012/open-ephys.vcxproj.filters b/Builds/VisualStudio2012/open-ephys.vcxproj.filters index 937da5cfa2fd273731fb7cac2f41720d21e74a55..b0ccd22aab60f10b7b3e6cf3a0075eda82c9906e 100644 --- a/Builds/VisualStudio2012/open-ephys.vcxproj.filters +++ b/Builds/VisualStudio2012/open-ephys.vcxproj.filters @@ -38,9 +38,6 @@ <Filter Include="open-ephys\Source\Processors\AudioNode"> <UniqueIdentifier>{117683A8-B332-1FBB-1FA0-8C6C7D231B69}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\AudioResamplingNode"> - <UniqueIdentifier>{BB0D2303-17CA-2E39-9765-7A701B2AE2F6}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\Processors\Channel"> <UniqueIdentifier>{7374BFF8-0BFC-382A-1DC3-F4B934CF25BC}</UniqueIdentifier> </Filter> @@ -71,18 +68,12 @@ <Filter Include="open-ephys\Source\Processors\FilterNode"> <UniqueIdentifier>{189BB62E-5852-A4F3-AC79-704FAAE02870}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\FPGAOutput"> - <UniqueIdentifier>{995BE2D8-55CB-BBA8-8155-2EFE5F03F143}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\Processors\GenericProcessor"> <UniqueIdentifier>{223ADE1C-7B16-1075-5D22-4771767BF960}</UniqueIdentifier> </Filter> <Filter Include="open-ephys\Source\Processors\LfpDisplayNode"> <UniqueIdentifier>{6F781BCA-7DB6-E933-BDDB-D2EAA51713B0}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\LfpTriggeredAverageNode"> - <UniqueIdentifier>{1150A21B-5E97-AC73-C141-CEF966829E71}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\Processors\Merger"> <UniqueIdentifier>{144C1CD2-E387-1D24-EFF3-C5238BD84182}</UniqueIdentifier> </Filter> @@ -113,9 +104,6 @@ <Filter Include="open-ephys\Source\Processors\PSTH"> <UniqueIdentifier>{2714D3F1-1A51-5CEC-5EE2-26686D9EEAF8}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\ReferenceNode"> - <UniqueIdentifier>{763A6B4C-B0C6-BA22-7FAB-0DEEF8D66097}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\Processors\ResamplingNode"> <UniqueIdentifier>{3135385A-1E61-FB08-3E00-D5C52DFB1BC9}</UniqueIdentifier> </Filter> @@ -146,9 +134,6 @@ <Filter Include="open-ephys\Source\Processors\Visualization"> <UniqueIdentifier>{851942D5-FED6-A7B2-6FAB-C278A247FE7A}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\WiFiOutput"> - <UniqueIdentifier>{F733C561-3FBD-E17D-CC23-601836ADF7E6}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\UI"> <UniqueIdentifier>{717A0FE3-E079-E4BD-8F50-15A1953825C5}</UniqueIdentifier> </Filter> @@ -472,9 +457,6 @@ <ClCompile Include="..\..\Source\Processors\AudioNode\AudioNode.cpp"> <Filter>open-ephys\Source\Processors\AudioNode</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\AudioResamplingNode\AudioResamplingNode.cpp"> - <Filter>open-ephys\Source\Processors\AudioResamplingNode</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\Channel\Channel.cpp"> <Filter>open-ephys\Source\Processors\Channel</Filter> </ClCompile> @@ -508,12 +490,6 @@ <ClCompile Include="..\..\Source\Processors\DataThreads\RHD2000Thread.cpp"> <Filter>open-ephys\Source\Processors\DataThreads</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\DataThreads\FileReaderThread.cpp"> - <Filter>open-ephys\Source\Processors\DataThreads</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\DataThreads\FPGAThread.cpp"> - <Filter>open-ephys\Source\Processors\DataThreads</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\DataThreads\DataBuffer.cpp"> <Filter>open-ephys\Source\Processors\DataThreads</Filter> </ClCompile> @@ -619,12 +595,6 @@ <ClCompile Include="..\..\Source\Processors\FilterNode\FilterNode.cpp"> <Filter>open-ephys\Source\Processors\FilterNode</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\FPGAOutput\FPGAOutput.cpp"> - <Filter>open-ephys\Source\Processors\FPGAOutput</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\FPGAOutput\FPGAOutputEditor.cpp"> - <Filter>open-ephys\Source\Processors\FPGAOutput</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\GenericProcessor\GenericProcessor.cpp"> <Filter>open-ephys\Source\Processors\GenericProcessor</Filter> </ClCompile> @@ -637,15 +607,6 @@ <ClCompile Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.cpp"> <Filter>open-ephys\Source\Processors\LfpDisplayNode</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageCanvas.cpp"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageEditor.cpp"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageNode.cpp"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\Merger\Merger.cpp"> <Filter>open-ephys\Source\Processors\Merger</Filter> </ClCompile> @@ -715,12 +676,6 @@ <ClCompile Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.cpp"> <Filter>open-ephys\Source\Processors\PSTH</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\ReferenceNode\ReferenceNode.cpp"> - <Filter>open-ephys\Source\Processors\ReferenceNode</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\ReferenceNode\ReferenceNodeEditor.cpp"> - <Filter>open-ephys\Source\Processors\ReferenceNode</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\ResamplingNode\ResamplingNode.cpp"> <Filter>open-ephys\Source\Processors\ResamplingNode</Filter> </ClCompile> @@ -796,12 +751,6 @@ <ClCompile Include="..\..\Source\Processors\Visualization\MatlabLikePlot.cpp"> <Filter>open-ephys\Source\Processors\Visualization</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\WiFiOutput\WiFiOutput.cpp"> - <Filter>open-ephys\Source\Processors\WiFiOutput</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\WiFiOutput\WiFiOutputEditor.cpp"> - <Filter>open-ephys\Source\Processors\WiFiOutput</Filter> - </ClCompile> <ClCompile Include="..\..\Source\UI\EcubeDialogComponent.cpp"> <Filter>open-ephys\Source\UI</Filter> </ClCompile> @@ -2094,9 +2043,6 @@ <ClInclude Include="..\..\Source\Processors\AudioNode\AudioNode.h"> <Filter>open-ephys\Source\Processors\AudioNode</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\AudioResamplingNode\AudioResamplingNode.h"> - <Filter>open-ephys\Source\Processors\AudioResamplingNode</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\Channel\Channel.h"> <Filter>open-ephys\Source\Processors\Channel</Filter> </ClInclude> @@ -2130,12 +2076,6 @@ <ClInclude Include="..\..\Source\Processors\DataThreads\RHD2000Thread.h"> <Filter>open-ephys\Source\Processors\DataThreads</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\DataThreads\FileReaderThread.h"> - <Filter>open-ephys\Source\Processors\DataThreads</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\DataThreads\FPGAThread.h"> - <Filter>open-ephys\Source\Processors\DataThreads</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\DataThreads\DataBuffer.h"> <Filter>open-ephys\Source\Processors\DataThreads</Filter> </ClInclude> @@ -2259,12 +2199,6 @@ <ClInclude Include="..\..\Source\Processors\FilterNode\FilterNode.h"> <Filter>open-ephys\Source\Processors\FilterNode</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\FPGAOutput\FPGAOutput.h"> - <Filter>open-ephys\Source\Processors\FPGAOutput</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\FPGAOutput\FPGAOutputEditor.h"> - <Filter>open-ephys\Source\Processors\FPGAOutput</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\GenericProcessor\GenericProcessor.h"> <Filter>open-ephys\Source\Processors\GenericProcessor</Filter> </ClInclude> @@ -2277,15 +2211,6 @@ <ClInclude Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.h"> <Filter>open-ephys\Source\Processors\LfpDisplayNode</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageCanvas.h"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageEditor.h"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageNode.h"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\Merger\Merger.h"> <Filter>open-ephys\Source\Processors\Merger</Filter> </ClInclude> @@ -2355,12 +2280,6 @@ <ClInclude Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.h"> <Filter>open-ephys\Source\Processors\PSTH</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\ReferenceNode\ReferenceNode.h"> - <Filter>open-ephys\Source\Processors\ReferenceNode</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\ReferenceNode\ReferenceNodeEditor.h"> - <Filter>open-ephys\Source\Processors\ReferenceNode</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\ResamplingNode\ResamplingNode.h"> <Filter>open-ephys\Source\Processors\ResamplingNode</Filter> </ClInclude> @@ -2442,12 +2361,6 @@ <ClInclude Include="..\..\Source\Processors\Visualization\MatlabLikePlot.h"> <Filter>open-ephys\Source\Processors\Visualization</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\WiFiOutput\WiFiOutput.h"> - <Filter>open-ephys\Source\Processors\WiFiOutput</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\WiFiOutput\WiFiOutputEditor.h"> - <Filter>open-ephys\Source\Processors\WiFiOutput</Filter> - </ClInclude> <ClInclude Include="..\..\Source\UI\EcubeDialogComponent.h"> <Filter>open-ephys\Source\UI</Filter> </ClInclude> diff --git a/Builds/VisualStudio2012/resources.rc b/Builds/VisualStudio2012/resources.rc index cc5759faef0b71cf1372bd7ab2c0762df6a84c49..9dca811221456380143e32719a2a4b2667ee81af 100644 --- a/Builds/VisualStudio2012/resources.rc +++ b/Builds/VisualStudio2012/resources.rc @@ -7,7 +7,7 @@ #include <windows.h> VS_VERSION_INFO VERSIONINFO -FILEVERSION 0,3,3,0 +FILEVERSION 0,3,4,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -15,9 +15,9 @@ BEGIN BEGIN VALUE "CompanyName", "Open Ephys\0" VALUE "FileDescription", "open-ephys\0" - VALUE "FileVersion", "0.3.3\0" + VALUE "FileVersion", "0.3.4\0" VALUE "ProductName", "open-ephys\0" - VALUE "ProductVersion", "0.3.3\0" + VALUE "ProductVersion", "0.3.4\0" END END diff --git a/Builds/VisualStudio2013/open-ephys.sln b/Builds/VisualStudio2013/open-ephys.sln index 662031ed0931146b2134f1fc184c05eedda69cc9..59a9d10ba28a4b47817570df74b1433044daefbb 100644 --- a/Builds/VisualStudio2013/open-ephys.sln +++ b/Builds/VisualStudio2013/open-ephys.sln @@ -1,31 +1,21 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30501.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "open-ephys", "open-ephys.vcxproj", "{9C924D66-7DEC-1AEF-B375-DB8666BFB909}" +Project("{5A05F353-1D63-394C-DFB0-981BB2309002}") = "open-ephys", "open-ephys.vcxproj", "{9C924D66-7DEC-1AEF-B375-DB8666BFB909}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Debug64|Win32 = Debug64|Win32 - Debug64|x64 = Debug64|x64 Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Release64|Win32 = Release64|Win32 + Debug64|x64 = Debug64|x64 Release64|x64 = Release64|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Debug|Win32.ActiveCfg = Debug|Win32 {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Debug|Win32.Build.0 = Debug|Win32 - {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Debug|x64.ActiveCfg = Debug|Win32 - {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Debug64|Win32.ActiveCfg = Debug64|x64 - {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Debug64|x64.ActiveCfg = Debug64|x64 - {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Debug64|x64.Build.0 = Debug64|x64 {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Release|Win32.ActiveCfg = Release|Win32 {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Release|Win32.Build.0 = Release|Win32 - {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Release|x64.ActiveCfg = Release|Win32 - {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Release64|Win32.ActiveCfg = Release64|x64 + {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Debug64|x64.ActiveCfg = Debug64|x64 + {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Debug64|x64.Build.0 = Debug64|x64 {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Release64|x64.ActiveCfg = Release64|x64 {9C924D66-7DEC-1AEF-B375-DB8666BFB909}.Release64|x64.Build.0 = Release64|x64 EndGlobalSection diff --git a/Builds/VisualStudio2013/open-ephys.vcxproj b/Builds/VisualStudio2013/open-ephys.vcxproj index ae72d3d461febee00924cea722b54e0998733d28..32fea9560b293910ff4a354f2949343c33df6497 100644 --- a/Builds/VisualStudio2013/open-ephys.vcxproj +++ b/Builds/VisualStudio2013/open-ephys.vcxproj @@ -89,7 +89,7 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.3;JUCE_APP_VERSION_HEX=0x303;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.4;JUCE_APP_VERSION_HEX=0x304;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> <PrecompiledHeader/> @@ -136,7 +136,7 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.3;JUCE_APP_VERSION_HEX=0x303;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.4;JUCE_APP_VERSION_HEX=0x304;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> <PrecompiledHeader/> @@ -185,7 +185,7 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.3;JUCE_APP_VERSION_HEX=0x303;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;_DEBUG;NOMINMAX;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.4;JUCE_APP_VERSION_HEX=0x304;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> <PrecompiledHeader/> @@ -230,7 +230,7 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../Resources/windows-libs/HDF5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.3;JUCE_APP_VERSION_HEX=0x303;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;NOMINMAX;JUCER_VS2013_78A5020=1;JUCE_APP_VERSION=0.3.4;JUCE_APP_VERSION_HEX=0x304;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> <PrecompiledHeader/> @@ -274,7 +274,6 @@ <ClCompile Include="..\..\Source\Processors\ArduinoOutput\ArduinoOutputEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\AudioNode\AudioEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\AudioNode\AudioNode.cpp"/> - <ClCompile Include="..\..\Source\Processors\AudioResamplingNode\AudioResamplingNode.cpp"/> <ClCompile Include="..\..\Source\Processors\Channel\Channel.cpp"/> <ClCompile Include="..\..\Source\Processors\ChannelMappingNode\ChannelMappingEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\ChannelMappingNode\ChannelMappingNode.cpp"/> @@ -286,8 +285,6 @@ <ClCompile Include="..\..\Source\Processors\DataThreads\rhythm-api\rhd2000evalboard.cpp"/> <ClCompile Include="..\..\Source\Processors\DataThreads\rhythm-api\rhd2000registers.cpp"/> <ClCompile Include="..\..\Source\Processors\DataThreads\RHD2000Thread.cpp"/> - <ClCompile Include="..\..\Source\Processors\DataThreads\FileReaderThread.cpp"/> - <ClCompile Include="..\..\Source\Processors\DataThreads\FPGAThread.cpp"/> <ClCompile Include="..\..\Source\Processors\DataThreads\DataBuffer.cpp"/> <ClCompile Include="..\..\Source\Processors\DataThreads\DataThread.cpp"/> <ClCompile Include="..\..\Source\Processors\Dsp\Bessel.cpp"/> @@ -323,15 +320,10 @@ <ClCompile Include="..\..\Source\Processors\FileReader\FileReaderEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\FilterNode\FilterEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\FilterNode\FilterNode.cpp"/> - <ClCompile Include="..\..\Source\Processors\FPGAOutput\FPGAOutput.cpp"/> - <ClCompile Include="..\..\Source\Processors\FPGAOutput\FPGAOutputEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\GenericProcessor\GenericProcessor.cpp"/> <ClCompile Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayCanvas.cpp"/> <ClCompile Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.cpp"/> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageCanvas.cpp"/> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageEditor.cpp"/> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageNode.cpp"/> <ClCompile Include="..\..\Source\Processors\Merger\Merger.cpp"/> <ClCompile Include="..\..\Source\Processors\Merger\MergerEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\MessageCenter\MessageCenter.cpp"/> @@ -355,8 +347,6 @@ <ClCompile Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.cpp"/> <ClCompile Include="..\..\Source\Processors\PSTH\tictoc.cpp"/> <ClCompile Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.cpp"/> - <ClCompile Include="..\..\Source\Processors\ReferenceNode\ReferenceNode.cpp"/> - <ClCompile Include="..\..\Source\Processors\ReferenceNode\ReferenceNodeEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\ResamplingNode\ResamplingNode.cpp"/> <ClCompile Include="..\..\Source\Processors\ResamplingNode\ResamplingNodeEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\Serial\PulsePal.cpp"/> @@ -382,8 +372,6 @@ <ClCompile Include="..\..\Source\Processors\Visualization\DataWindow.cpp"/> <ClCompile Include="..\..\Source\Processors\Visualization\SpikeObject.cpp"/> <ClCompile Include="..\..\Source\Processors\Visualization\MatlabLikePlot.cpp"/> - <ClCompile Include="..\..\Source\Processors\WiFiOutput\WiFiOutput.cpp"/> - <ClCompile Include="..\..\Source\Processors\WiFiOutput\WiFiOutputEditor.cpp"/> <ClCompile Include="..\..\Source\UI\EcubeDialogComponent.cpp"/> <ClCompile Include="..\..\Source\UI\CustomArrowButton.cpp"/> <ClCompile Include="..\..\Source\UI\GraphViewer.cpp"/> @@ -1529,7 +1517,6 @@ <ClInclude Include="..\..\Source\Processors\ArduinoOutput\ArduinoOutputEditor.h"/> <ClInclude Include="..\..\Source\Processors\AudioNode\AudioEditor.h"/> <ClInclude Include="..\..\Source\Processors\AudioNode\AudioNode.h"/> - <ClInclude Include="..\..\Source\Processors\AudioResamplingNode\AudioResamplingNode.h"/> <ClInclude Include="..\..\Source\Processors\Channel\Channel.h"/> <ClInclude Include="..\..\Source\Processors\ChannelMappingNode\ChannelMappingEditor.h"/> <ClInclude Include="..\..\Source\Processors\ChannelMappingNode\ChannelMappingNode.h"/> @@ -1541,8 +1528,6 @@ <ClInclude Include="..\..\Source\Processors\DataThreads\rhythm-api\rhd2000evalboard.h"/> <ClInclude Include="..\..\Source\Processors\DataThreads\rhythm-api\rhd2000registers.h"/> <ClInclude Include="..\..\Source\Processors\DataThreads\RHD2000Thread.h"/> - <ClInclude Include="..\..\Source\Processors\DataThreads\FileReaderThread.h"/> - <ClInclude Include="..\..\Source\Processors\DataThreads\FPGAThread.h"/> <ClInclude Include="..\..\Source\Processors\DataThreads\DataBuffer.h"/> <ClInclude Include="..\..\Source\Processors\DataThreads\DataThread.h"/> <ClInclude Include="..\..\Source\Processors\Dsp\Bessel.h"/> @@ -1584,15 +1569,10 @@ <ClInclude Include="..\..\Source\Processors\FileReader\FileReaderEditor.h"/> <ClInclude Include="..\..\Source\Processors\FilterNode\FilterEditor.h"/> <ClInclude Include="..\..\Source\Processors\FilterNode\FilterNode.h"/> - <ClInclude Include="..\..\Source\Processors\FPGAOutput\FPGAOutput.h"/> - <ClInclude Include="..\..\Source\Processors\FPGAOutput\FPGAOutputEditor.h"/> <ClInclude Include="..\..\Source\Processors\GenericProcessor\GenericProcessor.h"/> <ClInclude Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayCanvas.h"/> <ClInclude Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayEditor.h"/> <ClInclude Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.h"/> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageCanvas.h"/> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageEditor.h"/> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageNode.h"/> <ClInclude Include="..\..\Source\Processors\Merger\Merger.h"/> <ClInclude Include="..\..\Source\Processors\Merger\MergerEditor.h"/> <ClInclude Include="..\..\Source\Processors\MessageCenter\MessageCenter.h"/> @@ -1616,8 +1596,6 @@ <ClInclude Include="..\..\Source\Processors\PSTH\PeriStimulusTimeHistogramNode.h"/> <ClInclude Include="..\..\Source\Processors\PSTH\tictoc.h"/> <ClInclude Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.h"/> - <ClInclude Include="..\..\Source\Processors\ReferenceNode\ReferenceNode.h"/> - <ClInclude Include="..\..\Source\Processors\ReferenceNode\ReferenceNodeEditor.h"/> <ClInclude Include="..\..\Source\Processors\ResamplingNode\ResamplingNode.h"/> <ClInclude Include="..\..\Source\Processors\ResamplingNode\ResamplingNodeEditor.h"/> <ClInclude Include="..\..\Source\Processors\Serial\PulsePal.h"/> @@ -1645,8 +1623,6 @@ <ClInclude Include="..\..\Source\Processors\Visualization\SpikeObject.h"/> <ClInclude Include="..\..\Source\Processors\Visualization\Visualizer.h"/> <ClInclude Include="..\..\Source\Processors\Visualization\MatlabLikePlot.h"/> - <ClInclude Include="..\..\Source\Processors\WiFiOutput\WiFiOutput.h"/> - <ClInclude Include="..\..\Source\Processors\WiFiOutput\WiFiOutputEditor.h"/> <ClInclude Include="..\..\Source\UI\EcubeDialogComponent.h"/> <ClInclude Include="..\..\Source\UI\CustomArrowButton.h"/> <ClInclude Include="..\..\Source\UI\GraphViewer.h"/> diff --git a/Builds/VisualStudio2013/open-ephys.vcxproj.filters b/Builds/VisualStudio2013/open-ephys.vcxproj.filters index dc72e411330d13256b1875f07360900789a7679f..1251522bb6537167fe39418f84eefb817ea90604 100644 --- a/Builds/VisualStudio2013/open-ephys.vcxproj.filters +++ b/Builds/VisualStudio2013/open-ephys.vcxproj.filters @@ -38,9 +38,6 @@ <Filter Include="open-ephys\Source\Processors\AudioNode"> <UniqueIdentifier>{117683A8-B332-1FBB-1FA0-8C6C7D231B69}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\AudioResamplingNode"> - <UniqueIdentifier>{BB0D2303-17CA-2E39-9765-7A701B2AE2F6}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\Processors\Channel"> <UniqueIdentifier>{7374BFF8-0BFC-382A-1DC3-F4B934CF25BC}</UniqueIdentifier> </Filter> @@ -71,18 +68,12 @@ <Filter Include="open-ephys\Source\Processors\FilterNode"> <UniqueIdentifier>{189BB62E-5852-A4F3-AC79-704FAAE02870}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\FPGAOutput"> - <UniqueIdentifier>{995BE2D8-55CB-BBA8-8155-2EFE5F03F143}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\Processors\GenericProcessor"> <UniqueIdentifier>{223ADE1C-7B16-1075-5D22-4771767BF960}</UniqueIdentifier> </Filter> <Filter Include="open-ephys\Source\Processors\LfpDisplayNode"> <UniqueIdentifier>{6F781BCA-7DB6-E933-BDDB-D2EAA51713B0}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\LfpTriggeredAverageNode"> - <UniqueIdentifier>{1150A21B-5E97-AC73-C141-CEF966829E71}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\Processors\Merger"> <UniqueIdentifier>{144C1CD2-E387-1D24-EFF3-C5238BD84182}</UniqueIdentifier> </Filter> @@ -113,9 +104,6 @@ <Filter Include="open-ephys\Source\Processors\PSTH"> <UniqueIdentifier>{2714D3F1-1A51-5CEC-5EE2-26686D9EEAF8}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\ReferenceNode"> - <UniqueIdentifier>{763A6B4C-B0C6-BA22-7FAB-0DEEF8D66097}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\Processors\ResamplingNode"> <UniqueIdentifier>{3135385A-1E61-FB08-3E00-D5C52DFB1BC9}</UniqueIdentifier> </Filter> @@ -146,9 +134,6 @@ <Filter Include="open-ephys\Source\Processors\Visualization"> <UniqueIdentifier>{851942D5-FED6-A7B2-6FAB-C278A247FE7A}</UniqueIdentifier> </Filter> - <Filter Include="open-ephys\Source\Processors\WiFiOutput"> - <UniqueIdentifier>{F733C561-3FBD-E17D-CC23-601836ADF7E6}</UniqueIdentifier> - </Filter> <Filter Include="open-ephys\Source\UI"> <UniqueIdentifier>{717A0FE3-E079-E4BD-8F50-15A1953825C5}</UniqueIdentifier> </Filter> @@ -472,9 +457,6 @@ <ClCompile Include="..\..\Source\Processors\AudioNode\AudioNode.cpp"> <Filter>open-ephys\Source\Processors\AudioNode</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\AudioResamplingNode\AudioResamplingNode.cpp"> - <Filter>open-ephys\Source\Processors\AudioResamplingNode</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\Channel\Channel.cpp"> <Filter>open-ephys\Source\Processors\Channel</Filter> </ClCompile> @@ -508,12 +490,6 @@ <ClCompile Include="..\..\Source\Processors\DataThreads\RHD2000Thread.cpp"> <Filter>open-ephys\Source\Processors\DataThreads</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\DataThreads\FileReaderThread.cpp"> - <Filter>open-ephys\Source\Processors\DataThreads</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\DataThreads\FPGAThread.cpp"> - <Filter>open-ephys\Source\Processors\DataThreads</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\DataThreads\DataBuffer.cpp"> <Filter>open-ephys\Source\Processors\DataThreads</Filter> </ClCompile> @@ -619,12 +595,6 @@ <ClCompile Include="..\..\Source\Processors\FilterNode\FilterNode.cpp"> <Filter>open-ephys\Source\Processors\FilterNode</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\FPGAOutput\FPGAOutput.cpp"> - <Filter>open-ephys\Source\Processors\FPGAOutput</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\FPGAOutput\FPGAOutputEditor.cpp"> - <Filter>open-ephys\Source\Processors\FPGAOutput</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\GenericProcessor\GenericProcessor.cpp"> <Filter>open-ephys\Source\Processors\GenericProcessor</Filter> </ClCompile> @@ -637,15 +607,6 @@ <ClCompile Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.cpp"> <Filter>open-ephys\Source\Processors\LfpDisplayNode</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageCanvas.cpp"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageEditor.cpp"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageNode.cpp"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\Merger\Merger.cpp"> <Filter>open-ephys\Source\Processors\Merger</Filter> </ClCompile> @@ -715,12 +676,6 @@ <ClCompile Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.cpp"> <Filter>open-ephys\Source\Processors\PSTH</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\ReferenceNode\ReferenceNode.cpp"> - <Filter>open-ephys\Source\Processors\ReferenceNode</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\ReferenceNode\ReferenceNodeEditor.cpp"> - <Filter>open-ephys\Source\Processors\ReferenceNode</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Processors\ResamplingNode\ResamplingNode.cpp"> <Filter>open-ephys\Source\Processors\ResamplingNode</Filter> </ClCompile> @@ -796,12 +751,6 @@ <ClCompile Include="..\..\Source\Processors\Visualization\MatlabLikePlot.cpp"> <Filter>open-ephys\Source\Processors\Visualization</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Processors\WiFiOutput\WiFiOutput.cpp"> - <Filter>open-ephys\Source\Processors\WiFiOutput</Filter> - </ClCompile> - <ClCompile Include="..\..\Source\Processors\WiFiOutput\WiFiOutputEditor.cpp"> - <Filter>open-ephys\Source\Processors\WiFiOutput</Filter> - </ClCompile> <ClCompile Include="..\..\Source\UI\EcubeDialogComponent.cpp"> <Filter>open-ephys\Source\UI</Filter> </ClCompile> @@ -2094,9 +2043,6 @@ <ClInclude Include="..\..\Source\Processors\AudioNode\AudioNode.h"> <Filter>open-ephys\Source\Processors\AudioNode</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\AudioResamplingNode\AudioResamplingNode.h"> - <Filter>open-ephys\Source\Processors\AudioResamplingNode</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\Channel\Channel.h"> <Filter>open-ephys\Source\Processors\Channel</Filter> </ClInclude> @@ -2130,12 +2076,6 @@ <ClInclude Include="..\..\Source\Processors\DataThreads\RHD2000Thread.h"> <Filter>open-ephys\Source\Processors\DataThreads</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\DataThreads\FileReaderThread.h"> - <Filter>open-ephys\Source\Processors\DataThreads</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\DataThreads\FPGAThread.h"> - <Filter>open-ephys\Source\Processors\DataThreads</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\DataThreads\DataBuffer.h"> <Filter>open-ephys\Source\Processors\DataThreads</Filter> </ClInclude> @@ -2259,12 +2199,6 @@ <ClInclude Include="..\..\Source\Processors\FilterNode\FilterNode.h"> <Filter>open-ephys\Source\Processors\FilterNode</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\FPGAOutput\FPGAOutput.h"> - <Filter>open-ephys\Source\Processors\FPGAOutput</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\FPGAOutput\FPGAOutputEditor.h"> - <Filter>open-ephys\Source\Processors\FPGAOutput</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\GenericProcessor\GenericProcessor.h"> <Filter>open-ephys\Source\Processors\GenericProcessor</Filter> </ClInclude> @@ -2277,15 +2211,6 @@ <ClInclude Include="..\..\Source\Processors\LfpDisplayNode\LfpDisplayNode.h"> <Filter>open-ephys\Source\Processors\LfpDisplayNode</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageCanvas.h"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageEditor.h"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\LfpTriggeredAverageNode\LfpTriggeredAverageNode.h"> - <Filter>open-ephys\Source\Processors\LfpTriggeredAverageNode</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\Merger\Merger.h"> <Filter>open-ephys\Source\Processors\Merger</Filter> </ClInclude> @@ -2355,12 +2280,6 @@ <ClInclude Include="..\..\Source\Processors\PSTH\TrialCircularBuffer.h"> <Filter>open-ephys\Source\Processors\PSTH</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\ReferenceNode\ReferenceNode.h"> - <Filter>open-ephys\Source\Processors\ReferenceNode</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\ReferenceNode\ReferenceNodeEditor.h"> - <Filter>open-ephys\Source\Processors\ReferenceNode</Filter> - </ClInclude> <ClInclude Include="..\..\Source\Processors\ResamplingNode\ResamplingNode.h"> <Filter>open-ephys\Source\Processors\ResamplingNode</Filter> </ClInclude> @@ -2442,12 +2361,6 @@ <ClInclude Include="..\..\Source\Processors\Visualization\MatlabLikePlot.h"> <Filter>open-ephys\Source\Processors\Visualization</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Processors\WiFiOutput\WiFiOutput.h"> - <Filter>open-ephys\Source\Processors\WiFiOutput</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Processors\WiFiOutput\WiFiOutputEditor.h"> - <Filter>open-ephys\Source\Processors\WiFiOutput</Filter> - </ClInclude> <ClInclude Include="..\..\Source\UI\EcubeDialogComponent.h"> <Filter>open-ephys\Source\UI</Filter> </ClInclude> diff --git a/Builds/VisualStudio2013/resources.rc b/Builds/VisualStudio2013/resources.rc index cc5759faef0b71cf1372bd7ab2c0762df6a84c49..9dca811221456380143e32719a2a4b2667ee81af 100644 --- a/Builds/VisualStudio2013/resources.rc +++ b/Builds/VisualStudio2013/resources.rc @@ -7,7 +7,7 @@ #include <windows.h> VS_VERSION_INFO VERSIONINFO -FILEVERSION 0,3,3,0 +FILEVERSION 0,3,4,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -15,9 +15,9 @@ BEGIN BEGIN VALUE "CompanyName", "Open Ephys\0" VALUE "FileDescription", "open-ephys\0" - VALUE "FileVersion", "0.3.3\0" + VALUE "FileVersion", "0.3.4\0" VALUE "ProductName", "open-ephys\0" - VALUE "ProductVersion", "0.3.3\0" + VALUE "ProductVersion", "0.3.4\0" END END diff --git a/JuceLibraryCode/JuceHeader.h b/JuceLibraryCode/JuceHeader.h index 94eac05313a9f059ed97531c4e75e7bb3353edf6..fb111b6443002a8d2a511e978f5e51fe63217d21 100644 --- a/JuceLibraryCode/JuceHeader.h +++ b/JuceLibraryCode/JuceHeader.h @@ -39,8 +39,8 @@ namespace ProjectInfo { const char* const projectName = "open-ephys"; - const char* const versionString = "0.3.3"; - const int versionNumber = 0x303; + const char* const versionString = "0.3.4"; + const int versionNumber = 0x304; } #endif // __APPHEADERFILE_YNSYIRR__ diff --git a/Source/Processors/ArduinoOutput/ArduinoOutput.cpp b/Source/Processors/ArduinoOutput/ArduinoOutput.cpp index 053020e76980a015ff39f4b531e81b38f337fb8c..a26c70c3a3965cfd6ff9a39ea2518a30d7504657 100755 --- a/Source/Processors/ArduinoOutput/ArduinoOutput.cpp +++ b/Source/Processors/ArduinoOutput/ArduinoOutput.cpp @@ -138,8 +138,7 @@ bool ArduinoOutput::disable() } void ArduinoOutput::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { diff --git a/Source/Processors/ArduinoOutput/ArduinoOutput.h b/Source/Processors/ArduinoOutput/ArduinoOutput.h index 86f6480dbedf6b8bdff342f5505bfd7f12847921..da49269f6c014c2da8d1d8094867225e9edaf43f 100755 --- a/Source/Processors/ArduinoOutput/ArduinoOutput.h +++ b/Source/Processors/ArduinoOutput/ArduinoOutput.h @@ -51,7 +51,7 @@ public: ~ArduinoOutput(); /** Searches for events and triggers the Arduino output when appropriate. */ - void process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& events); /** Currently unused. Future uses may include changing the TTL trigger channel or the output channel of the Arduino. */ diff --git a/Source/Processors/AudioNode/AudioNode.cpp b/Source/Processors/AudioNode/AudioNode.cpp index 53d3339624768a4e73a505a4eb46cbb93b912d45..aaf2460194076bc1409580092b9de8523b1f515f 100755 --- a/Source/Processors/AudioNode/AudioNode.cpp +++ b/Source/Processors/AudioNode/AudioNode.cpp @@ -26,12 +26,10 @@ #include "AudioNode.h" AudioNode::AudioNode() - : GenericProcessor("Audio Node"), audioEditor(0), volume(0.00001f), noiseGateLevel(0.0f), - bufferA(2,10000), - bufferB(2,10000) + : GenericProcessor("Audio Node"), audioEditor(0), volume(0.00001f), noiseGateLevel(0.0f) { - settings.numInputs = 2048; + settings.numInputs = 4096; settings.numOutputs = 2; // 128 inputs, 2 outputs (left and right channel) @@ -39,19 +37,13 @@ AudioNode::AudioNode() nextAvailableChannel = 2; // keep first two channels empty - numSamplesExpected = 1024; - - samplesInOverflowBuffer = 0; - samplesInBackupBuffer = 0; + tempBuffer = new AudioSampleBuffer(16, 1024); } AudioNode::~AudioNode() { - - - } AudioProcessorEditor* AudioNode::createEditor() @@ -71,9 +63,6 @@ void AudioNode::resetConnections() channelPointers.clear(); - samplesInOverflowBuffer = 0; - samplesInBackupBuffer = 0; - } void AudioNode::updateBufferSize() @@ -165,24 +154,79 @@ void AudioNode::prepareToPlay(double sampleRate_, int estimatedSamplesPerBlock) // std::cout << "Processor sample rate: " << getSampleRate() << std::endl; // std::cout << "Audio card sample rate: " << sampleRate_ << std::endl; // std::cout << "Samples per block: " << estimatedSamplesPerBlock << std::endl; + if (sampleRate_ != destBufferSampleRate || estimatedSamplesPerBlock != estimatedSamples) + { + destBufferSampleRate = sampleRate_; + estimatedSamples = estimatedSamplesPerBlock; + recreateBuffers(); + } - numSamplesExpected = (int)(getSampleRate()/sampleRate_*float(estimatedSamplesPerBlock)) + 1; - // processor sample rate divided by sound card sample rate - - samplesInBackupBuffer = 0; - samplesInOverflowBuffer = 0; +} +void AudioNode::recreateBuffers() +{ + numSamplesExpected.clear(); + samplesInBackupBuffer.clear(); + samplesInOverflowBuffer.clear(); + ratio.clear(); + filters.clear(); bufferA.clear(); bufferB.clear(); + bufferSwap.clear(); + + for (int i = 0; i < channelPointers.size(); i++) + { + // processor sample rate divided by sound card sample rate + numSamplesExpected.add((int)(channelPointers[i]->sampleRate/destBufferSampleRate*float(estimatedSamples)) + 1); + samplesInBackupBuffer.add(0); + samplesInOverflowBuffer.add(0); + sourceBufferSampleRate.add(channelPointers[i]->sampleRate); + + filters.add(new Dsp::SmoothedFilterDesign<Dsp::RBJ::Design::LowPass, 1> (1024)); + + ratio.add(float(numSamplesExpected[i])/float(estimatedSamples)); + updateFilter(i); + + bufferA.add(new AudioSampleBuffer(1,10000)); + bufferB.add(new AudioSampleBuffer(1,10000)); + bufferSwap.add(false); + + } + + tempBuffer->setSize(getNumInputs(), 4096); +} + +bool AudioNode::enable() +{ + recreateBuffers(); + return true; +} + +void AudioNode::updateFilter(int i) +{ + + double cutoffFreq = (ratio[i] > 1.0) ? 2 * destBufferSampleRate // downsample + : destBufferSampleRate / 2; // upsample + + double sampleFreq = (ratio[i] > 1.0) ? sourceBufferSampleRate[i] // downsample + : destBufferSampleRate; // upsample + + Dsp::Params params; + params[0] = sampleFreq; // sample rate + params[1] = cutoffFreq; // cutoff frequency + params[2] = 1.25; //Q // + + filters[i]->setParams(params); - bufferSwap = false; } void AudioNode::process(AudioSampleBuffer& buffer, - MidiBuffer& midiMessages, - int& nSamples) + MidiBuffer& events) { float gain; + int valuesNeeded = buffer.getNumSamples(); // samples needed to fill out the buffer + + //std::cout << "Buffer size: " << buffer.getNumChannels() << std::endl; // clear the left and right channels buffer.clear(0,0,buffer.getNumSamples()); @@ -194,186 +238,229 @@ void AudioNode::process(AudioSampleBuffer& buffer, AudioSampleBuffer* overflowBuffer; AudioSampleBuffer* backupBuffer; - if (!bufferSwap) + if (channelPointers.size() > 0) // we have some channels { - overflowBuffer = &bufferA; - backupBuffer = &bufferB; - bufferSwap = true; - } - else - { - overflowBuffer = &bufferB; - backupBuffer = &bufferA; - bufferSwap = false; - } - - backupBuffer->clear(); - samplesInOverflowBuffer = samplesInBackupBuffer; // size of buffer after last round - samplesInBackupBuffer = 0; + tempBuffer->clear(); - int samplesToCopy = 0; - int orphanedSamples = 0; - - if (channelPointers.size() > 0) - { - bool copiedBuffer = false; - - for (int i = 2; i < buffer.getNumChannels(); i++) + for (int i = 0; i < buffer.getNumChannels()-2; i++) // cycle through them all { - if (channelPointers[i-2]->isMonitored) + if (channelPointers[i]->isMonitored) { - if (!copiedBuffer) - { - // 1. copy overflow buffer + //std::cout << "Processing channel " << i << std::endl; - samplesToCopy = ((samplesInOverflowBuffer <= numSamplesExpected) ? - samplesInOverflowBuffer : - numSamplesExpected); + if (!bufferSwap[i]) + { + overflowBuffer = bufferA[i]; + backupBuffer = bufferB[i]; - // std::cout << " " << std::endl; - // std::cout << "Copying " << samplesToCopy << " samples from overflow buffer of " << samplesInOverflowBuffer << " samples." << std::endl; + bufferSwap.set(i,true); + } + else + { + overflowBuffer = bufferB[i]; + backupBuffer = bufferA[i]; - if (samplesToCopy > 0) - { + bufferSwap.set(i,false); + } - buffer.addFrom(0, // destination channel - 0, // destination start sample - *overflowBuffer, // source - 0, // source channel - 0, // source start sample - samplesToCopy, // number of samples - 1.0f // gain to apply - ); + backupBuffer->clear(); - buffer.addFrom(1, // destination channel - 0, // destination start sample - *overflowBuffer, // source - 1, // source channel - 0, // source start sample - samplesToCopy, // number of samples - 1.0f // gain to apply - ); + samplesInOverflowBuffer.set(i,samplesInBackupBuffer[i]); // size of buffer after last round + samplesInBackupBuffer.set(i,0); + int orphanedSamples = 0; - int leftoverSamples = samplesInOverflowBuffer - samplesToCopy; + // 1. copy overflow buffer - // std::cout << "Samples remaining in overflow buffer: " << leftoverSamples << std::endl; + int samplesToCopyFromOverflowBuffer = + ((samplesInOverflowBuffer[i] <= numSamplesExpected[i]) ? + samplesInOverflowBuffer[i] : + numSamplesExpected[i]); - if (leftoverSamples > 0) - { + //std::cout << "Copying " << samplesToCopyFromOverflowBuffer << " samples from overflow buffer of " << samplesInOverflowBuffer[i] << " samples." << std::endl; - // move remaining samples to the backup buffer + if (samplesToCopyFromOverflowBuffer > 0) // need to re-add samples from backup buffer + { - backupBuffer->addFrom(0, // destination channel - 0, // destination start sample - *overflowBuffer, // source - 0, // source channel - samplesToCopy, // source start sample - leftoverSamples, // number of samples - 1.0f // gain to apply - ); + tempBuffer->addFrom(i, // destination channel + 0, // destination start sample + *overflowBuffer, // source + 0, // source channel + 0, // source start sample + samplesToCopyFromOverflowBuffer, // number of samples + 1.0f // gain to apply + ); - backupBuffer->addFrom(1, // destination channel - 0, // destination start sample - *overflowBuffer, // source - 1, // source channel - samplesToCopy, // source start sample - leftoverSamples, // number of samples - 1.0f // gain to apply - ); + int leftoverSamples = samplesInOverflowBuffer[i] - samplesToCopyFromOverflowBuffer; - } + // std::cout << "Samples remaining in overflow buffer: " << leftoverSamples << std::endl; - samplesInBackupBuffer = leftoverSamples; + if (leftoverSamples > 0) // move remaining samples to the backup buffer + { + backupBuffer->addFrom(0, // destination channel + 0, // destination start sample + *overflowBuffer, // source + 0, // source channel + samplesToCopyFromOverflowBuffer, // source start sample + leftoverSamples, // number of samples + 1.0f // gain to apply + ); } - copiedBuffer = true; - - } // copying buffer + samplesInBackupBuffer.set(i,leftoverSamples); + } - gain = volume/(float(0x7fff) * channelPointers[i-2]->bitVolts); + gain = volume/(float(0x7fff) * channelPointers[i]->bitVolts); // Data are floats in units of microvolts, so dividing by bitVolts and 0x7fff (max value for 16b signed) // rescales to between -1 and +1. Audio output starts So, maximum gain applied to maximum data would be 10. - int remainingSamples = numSamplesExpected - samplesToCopy; + int remainingSamples = numSamplesExpected[i] - samplesToCopyFromOverflowBuffer; - // std::cout << "Copying " << remainingSamples << " samples from incoming buffer of " << nSamples << " samples." << std::endl; + int samplesAvailable = numSamples.at(channelPointers[i]->sourceNodeId); - int samplesToCopy2 = ((remainingSamples <= nSamples) ? - remainingSamples : - nSamples); + int samplesToCopyFromIncomingBuffer = ((remainingSamples <= samplesAvailable) ? + remainingSamples : + samplesAvailable); - if (samplesToCopy2 > 0) + //std::cout << "Copying " << samplesToCopyFromIncomingBuffer << " samples from incoming buffer of " << samplesAvailable << " samples." << std::endl; + + + if (samplesToCopyFromIncomingBuffer > 0) { - buffer.addFrom(0, // destination channel - samplesToCopy, // destination start sample - buffer, // source - i, // source channel - 0, // source start sample - remainingSamples, // number of samples - gain // gain to apply - ); - - buffer.addFrom(1, // destination channel - samplesToCopy, // destination start sample - buffer, // source - i, // source channel - 0, // source start sample - remainingSamples, // number of samples - gain // gain to apply - ); + tempBuffer->addFrom(i, // destination channel + samplesToCopyFromOverflowBuffer, // destination start sample + buffer, // source + i+2, // source channel (add 2 to account for output channels) + 0, // source start sample + samplesToCopyFromIncomingBuffer, // number of samples + gain // gain to apply + ); + + //if (destBufferPos == 0) + // std::cout << "Temp buffer 0 value: " << *tempBuffer->getReadPointer(i,0) << std::endl; } - orphanedSamples = nSamples - samplesToCopy2; + orphanedSamples = samplesAvailable - samplesToCopyFromIncomingBuffer; // std::cout << "Samples remaining in incoming buffer: " << orphanedSamples << std::endl; - - if (orphanedSamples > 0 && (samplesInBackupBuffer + orphanedSamples < backupBuffer->getNumSamples())) + if (orphanedSamples > 0 && (samplesInBackupBuffer[i] + orphanedSamples < backupBuffer->getNumSamples())) { - backupBuffer->addFrom(0, // destination channel - samplesInBackupBuffer, // destination start sample - buffer, // source - i, // source channel - remainingSamples, // source start sample - orphanedSamples, // number of samples - gain // gain to apply - ); - backupBuffer->addFrom(0, // destination channel - samplesInBackupBuffer, // destination start sample - buffer, // source - i, // source channel - remainingSamples, // source start sample - orphanedSamples, // number of samples - gain // gain to apply + backupBuffer->addFrom(0, // destination channel + samplesInBackupBuffer[i], // destination start sample + buffer, // source + i+2, // source channel (add 2 to account for output channels) + remainingSamples, // source start sample + orphanedSamples, // number of samples + gain // gain to apply ); - } - else { - samplesInBackupBuffer = 0; // just throw out the buffer in the case of an overrun - // not ideal, but the output still sounds fine - } + samplesInBackupBuffer.set(i, samplesInBackupBuffer[i] + orphanedSamples); - // Simple implementation of a "noise gate" on audio output - expander.process(buffer.getWritePointer(0), // left channel - buffer.getWritePointer(1), // right channel - buffer.getNumSamples()); + } - } - } + // now that our tempBuffer is ready, we can filter it and copy it into the + // original buffer - } + //std::cout << "Ratio = " << ratio[i] << ", gain = " << gain << std::endl; + //std::cout << "Values needed = " << valuesNeeded << ", channel = " << i << std::endl; - samplesInBackupBuffer += orphanedSamples; - nSamples = numSamplesExpected; + if (ratio[i] > 1.00001) + { + // pre-apply filter before downsampling + float* ptr = tempBuffer->getWritePointer(i); + filters[i]->process(numSamplesExpected[i], &ptr); + } + // initialize variables + int sourceBufferPos = 0; + int sourceBufferSize = numSamplesExpected[i]; + float subSampleOffset = 0.0; + int nextPos = (sourceBufferPos + 1) % sourceBufferSize; + + int destBufferPos; + + // code modified from "juce_ResamplingAudioSource.cpp": + + for (destBufferPos = 0; destBufferPos < valuesNeeded; destBufferPos++) + { + float gain = 1.0; + float alpha = (float) subSampleOffset; + float invAlpha = 1.0f - alpha; + + // std::cout << "Copying sample " << sourceBufferPos << std::endl; + + buffer.addFrom(0, // destChannel + destBufferPos, // destSampleOffset + *tempBuffer, // source + i, // sourceChannel + sourceBufferPos,// sourceSampleOffset + 1, // number of samples + invAlpha*gain); // gain to apply to source + + buffer.addFrom(0, // destChannel + destBufferPos, // destSampleOffset + *tempBuffer, // source + i, // sourceChannel + nextPos, // sourceSampleOffset + 1, // number of samples + alpha*gain); // gain to apply to source + + // if (destBufferPos == 0) + //std::cout << "Output buffer 0 value: " << *buffer.getReadPointer(i+2,destBufferPos) << std::endl; + + subSampleOffset += ratio[i]; + + while (subSampleOffset >= 1.0) + { + if (++sourceBufferPos >= sourceBufferSize) + sourceBufferPos = 0; + + nextPos = (sourceBufferPos + 1) % sourceBufferSize; + subSampleOffset -= 1.0; + } + } + + if (ratio[i] < 0.99999) + { + // apply the filter after upsampling + float* ptr = buffer.getWritePointer(0); + filters[i]->process(destBufferPos, &ptr); + } + + // now copy the channel into the output zone + + // buffer.addFrom(0, // destChannel + // 0, // destSampleOffset + // buffer, // source + // i+2, // sourceChannel + // 0,// sourceSampleOffset + // valuesNeeded, // number of samples + // 1.0); // gain to apply to source + + } // if channelPointers[i]->isMonitored + } // end cycling through channels + + // Simple implementation of a "noise gate" on audio output + expander.process(buffer.getWritePointer(0), // expand the left channel + buffer.getNumSamples()); + + // copy the signal into the right channel (no stereo audio yet!) + buffer.addFrom(1, // destChannel + 0, // destSampleOffset + buffer, // source + 0, // sourceChannel + 0,// sourceSampleOffset + valuesNeeded, // number of samples + 1.0); // gain to apply to source + } } } @@ -381,15 +468,15 @@ void AudioNode::process(AudioSampleBuffer& buffer, Expander::Expander() { - threshold = 1.f; - output = 1.f; - - env = 0.f; - gain = 1.f; - - setAttack(1.0f); - setRelease(1.0f); - setRatio(1.2); // ratio > 1.0 will decrease gain below threshold + threshold = 1.f; + output = 1.f; + + env = 0.f; + gain = 1.f; + + setAttack(1.0f); + setRelease(1.0f); + setRatio(1.2); // ratio > 1.0 will decrease gain below threshold } void Expander::setThreshold(float value) @@ -422,24 +509,23 @@ void Expander::setRelease(float value) } -void Expander::process(float* leftChan, float* rightChan, int numSamples) +void Expander::process(float* sampleData, int numSamples) { - float det, transfer_gain; + float det, transfer_gain; - for(int i = 0; i < numSamples; i++) - { - det = jmax(fabs(leftChan[i]),fabs(rightChan[i])); - det += 10e-30f; /* add tiny DC offset (-600dB) to prevent denormals */ + for (int i = 0; i < numSamples; i++) + { + det = fabs(sampleData[i]); + det += 10e-30f; /* add tiny DC offset (-600dB) to prevent denormals */ - env = det >= env ? det : det + envelope_decay*(env-det); + env = det >= env ? det : det + envelope_decay*(env-det); - transfer_gain = env < threshold ? pow(env, transfer_A) * transfer_B : output; + transfer_gain = env < threshold ? pow(env, transfer_A) * transfer_B : output; - gain = transfer_gain < gain ? - transfer_gain + attack * (gain - transfer_gain) : - transfer_gain + release * (gain - transfer_gain); + gain = transfer_gain < gain ? + transfer_gain + attack * (gain - transfer_gain) : + transfer_gain + release * (gain - transfer_gain); - leftChan[i] = leftChan[i] * gain; - rightChan[i] = rightChan[i] * gain; - } + sampleData[i] = sampleData[i] * gain; + } } \ No newline at end of file diff --git a/Source/Processors/AudioNode/AudioNode.h b/Source/Processors/AudioNode/AudioNode.h index c6fda84453558d968420e3f5abe250bc1a1f1639..2f65e6a3009980ad6af4a67fe3de12936799fe70 100755 --- a/Source/Processors/AudioNode/AudioNode.h +++ b/Source/Processors/AudioNode/AudioNode.h @@ -30,6 +30,7 @@ #include "../GenericProcessor/GenericProcessor.h" #include "AudioEditor.h" +#include "../Dsp/Dsp.h" #include "../Channel/Channel.h" @@ -67,7 +68,7 @@ public: void setRelease(float); void reset(); - void process(float* leftChan, float* rightChan, int numSamples); + void process(float* sampleData, int numSamples); private: float threshold; @@ -88,7 +89,7 @@ public: /** Handle incoming data and decide which channels to monitor */ - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); /** Used to change audio monitoring parameters (such as channels to monitor and volume) while acquisition is active. */ @@ -119,7 +120,12 @@ public: void prepareToPlay(double sampleRate_, int estimatedSamplesPerBlock); + void updateFilter(int i); + + bool enable(); + private: + void recreateBuffers(); Array<int> leftChan; Array<int> rightChan; @@ -129,18 +135,30 @@ private: /** An array of pointers to the channels that feed into the AudioNode. */ Array<Channel*> channelPointers; - AudioSampleBuffer bufferA; - AudioSampleBuffer bufferB; + OwnedArray<AudioSampleBuffer> bufferA; + OwnedArray<AudioSampleBuffer> bufferB; - int numSamplesExpected; + Array<int> numSamplesExpected; - int samplesInBackupBuffer; - int samplesInOverflowBuffer; + Array<int> samplesInBackupBuffer; + Array<int> samplesInOverflowBuffer; + Array<double> sourceBufferSampleRate; + double destBufferSampleRate; + int estimatedSamples; - bool bufferSwap; + Array<bool> bufferSwap; Expander expander; + // sample rate, timebase, and ratio info: + Array<double> ratio; + + // major objects: + OwnedArray<Dsp::Filter> filters; + + // Temporary buffer for data + ScopedPointer<AudioSampleBuffer> tempBuffer; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioNode); }; diff --git a/Source/Processors/AudioResamplingNode/AudioResamplingNode.cpp b/Source/Processors/AudioResamplingNode/AudioResamplingNode.cpp index 3fb680a5217d94b5c6d474196c6ea3b952aab330..69fa7cbaba6472f532437b756782efa62d974166 100644 --- a/Source/Processors/AudioResamplingNode/AudioResamplingNode.cpp +++ b/Source/Processors/AudioResamplingNode/AudioResamplingNode.cpp @@ -140,11 +140,10 @@ void AudioResamplingNode::releaseResources() } void AudioResamplingNode::process(AudioSampleBuffer& buffer, - MidiBuffer& midiMessages, - int& nSamples) + MidiBuffer& midiMessages) { - int nSamps = nSamples; + int nSamps = buffer.getNumSamples(); // WRONG!!!! int valuesNeeded; if (destBufferIsTempBuffer) diff --git a/Source/Processors/AudioResamplingNode/AudioResamplingNode.h b/Source/Processors/AudioResamplingNode/AudioResamplingNode.h index 77cda548eaa6c289bbcc27162632b62881a9c740..2d2ef308676b5658691696a53e248e3b37dd5d1d 100644 --- a/Source/Processors/AudioResamplingNode/AudioResamplingNode.h +++ b/Source/Processors/AudioResamplingNode/AudioResamplingNode.h @@ -59,7 +59,7 @@ public: void prepareToPlay(double sampleRate, int estimatedSamplesPerBlock); void releaseResources(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); AudioSampleBuffer* getContinuousBuffer() diff --git a/Source/Processors/Channel/Channel.cpp b/Source/Processors/Channel/Channel.cpp index f5cdd31deeddbd0177f1227bc04bdd10e24d8178..d7f7ec265734b0310c7d4fc56ec50eef66d8ab61 100644 --- a/Source/Processors/Channel/Channel.cpp +++ b/Source/Processors/Channel/Channel.cpp @@ -24,49 +24,63 @@ #include "Channel.h" -Channel::Channel(GenericProcessor* p, int n) : num(n), eventType(0), processor(p), sampleRate(44100.0), - isEventChannel(false), isADCchannel(false), isMonitored(false), isEnabled(true), recordIndex(-1), - type(DATA_CHANNEL),bitVolts(1.0f), isRecording(false) +Channel::Channel(GenericProcessor* p, int n, ChannelType t) : index(n), processor(p), type(t), nodeIndex(0) { - nodeId = p->getNodeId(); + reset(); +} +void Channel::reset() +{ createDefaultName(); + + nodeId = processor->getNodeId(); + + sampleRate = 44100.0f; + bitVolts = 1.0f; + sourceNodeId = -1; + isMonitored = false; + isEnabled = true; + recordIndex = -1; + probeId = -1; + x = 0.0f; + y = 0.0f; + z = 0.0f; + impedance = 0.0f; + isRecording = false; + } Channel::Channel(const Channel& ch) { + index = ch.index; + nodeIndex = ch.nodeIndex; + nodeId = ch.nodeId; processor = ch.processor; - isEventChannel = ch.isEventChannel; - isEnabled = ch.isEnabled; - isMonitored = false; - isADCchannel = ch.isADCchannel; sampleRate = ch.sampleRate; bitVolts = ch.bitVolts; + type = ch.type; + sourceNodeId = ch.sourceNodeId; + isMonitored = ch.isMonitored; + isEnabled = ch.isEnabled; + recordIndex = ch.recordIndex; name = ch.name; - eventType = ch.eventType; - nodeId = ch.nodeId; - num = ch.num; - type = ch.type; - - originalStream = ch.originalStream; - originalChannel = ch.originalChannel; + probeId = ch.probeId; + x = ch.x; + y = ch.y; + z = ch.z; + impedance = ch.impedance; setRecordState(false); } -float Channel::getChannelGain() +float Channel::getBitVolts() { return bitVolts; } -String Channel::getChannelName() +void Channel::setBitVolts(float bv) { - return name; -} - -void Channel::setGain(float gain) -{ - bitVolts = gain; + bitVolts = bv; } @@ -85,19 +99,19 @@ String Channel::getName() void Channel::setRecordState(bool t) { - isRecording = t; - //std::cout << "Setting record status for channel " << - // nodeId << " - " << num << " to " << t << std::endl; + isRecording = t; + //std::cout << "Setting record status for channel " << + // nodeId << " - " << num << " to " << t << std::endl; } -void Channel::setType(channelType t) +void Channel::setType(ChannelType t) { type = t; } -channelType Channel::getType() +ChannelType Channel::getType() { return type; } @@ -107,17 +121,34 @@ void Channel::setName(String name_) name = name_; } -void Channel::reset() -{ - createDefaultName(); - - sampleRate = 44100.0f; - bitVolts = 1.0f; -} void Channel::createDefaultName() { - name = String("CH"); - name += (num + 1); + switch (type) + { + case HEADSTAGE_CHANNEL: + name = String("CH"); + break; + case AUX_CHANNEL: + name = String("AUX"); + break; + case ADC_CHANNEL: + name = String("ADC"); + break; + case EVENT_CHANNEL: + name = String("EVENT"); + break; + case SINGLE_ELECTRODE: + name = String("SE"); + break; + case STEREOTRODE: + name = String("ST"); + break; + case TETRODE: + name = String("TT"); + break; + } + + name += index; } diff --git a/Source/Processors/Channel/Channel.h b/Source/Processors/Channel/Channel.h index 737f1bb2835d0b4feb842b891a7de7a9366527b2..da60b7105b2a4481b7d8f361c3b173e1e861b575 100644 --- a/Source/Processors/Channel/Channel.h +++ b/Source/Processors/Channel/Channel.h @@ -43,6 +43,11 @@ class GenericProcessor; AudioNode and RecordNode, which need to access/update Channel information for multiple processors at once. + Every processor has a Channel object for each channel it must deal with. + Usually, settings for each channel will be copied from a source + node to its destination, but sometimes particular parameters will + be updated. + @see GenericProcessor, RecordNode, AudioNode */ @@ -53,26 +58,27 @@ class Channel { public: + //--------- CONSTRUCTOR / DESTRUCTOR --------// + /** Default constructor for creating Channels from scratch. */ - Channel(GenericProcessor* p, int n); + Channel(GenericProcessor*, int, ChannelType); /** Copy constructor. */ Channel(const Channel& ch); + //--------- GET / SET METHODS --------// + /** Returns the name of a given channel. */ String getName(); /** Sets the name of a given channel. */ void setName(String); - /** Sets the type of a given channel. */ - void setType(channelType t); + /** Sets the type of a given channel. */ + void setType(ChannelType t); - /** Sets the type of a given channel. */ - channelType getType(); - - /** Restores the default settings for a given channel. */ - void reset(); + /** Sets the type of a given channel. */ + ChannelType getType(); /** Sets the processor to which a channel belongs. */ void setProcessor(GenericProcessor*); @@ -81,53 +87,77 @@ public: void setRecordState(bool t); // {isRecording = t;} /** Sets whether or not the channel will record. */ - bool getRecordState() {return isRecording;} + bool getRecordState() + { + return isRecording; + } - /** Sets a new channel gain by modifying bitVolts */ - void setGain(float gain); + /** Sets the bitVolts value for this channel. */ + void setBitVolts(float bitVolts); - /** returns channel's name */ - String getChannelName(); + /** Returns the bitVolts value for this channel. */ + float getBitVolts(); - /** returns current gain */ - float getChannelGain(); + // -------- OTHER METHODS ---------// - /** The channel number.*/ - int num; + /** Restores the default settings for a given channel. */ + void reset(); + + //--------------PUBLIC MEMBERS ---------------- // + + /** Channel index within the source processor */ + int nodeIndex; + + /** Channel index within the source processor relative to channel type */ + int index; /** The ID of the channel's processor.*/ int nodeId; - /** Used for EventChannels only.*/ - int eventType; - /** Pointer to the channel's parent processor. */ GenericProcessor* processor; - int originalStream; - int originalChannel; + /** Sample rate expected for this channel. */ + float sampleRate; + /** Bit volts for this channel (i.e., by what must we multiply the ADC integer value to + convert to the original voltage measurement?). */ + float bitVolts; - // crucial information: - float sampleRate; - channelType type; - - // boolean values: - bool isEventChannel; - bool isADCchannel; + /** Channel "type": neural data, aux, adc, event **/ + ChannelType type; + + /** ID of source node. This is crucial for properly updating timestamps and sample counts. */ + int sourceNodeId; + + /** Toggled when audio monitoring of this channel is enabled or disabled. */ bool isMonitored; + + /** Toggled when a channel is disabled from further processing. */ bool isEnabled; - // file info (for disk writing). Meaning depends on RecordEngine - int recordIndex; + /** File info (for disk writing). Meaning depends on the RecordEngine being used. */ + int recordIndex; + /** Holds the name of this channel */ String name; - float bitVolts; + /** The ID of the probe that this channel belongs to (if any) */ + int probeId; + + /** x,y,z location of this channel in space */ + float x,y,z; + + /** Impedance of this channel. */ + float impedance; + private: - bool isRecording; + //-------------- PRIVATE MEMBERS ---------------- // + + /** Stores whether or not the channel is being recorded. */ + bool isRecording; /** Generates a default name, based on the channel number. */ void createDefaultName(); diff --git a/Source/Processors/ChannelMappingNode/ChannelMappingNode.cpp b/Source/Processors/ChannelMappingNode/ChannelMappingNode.cpp index fd632c8eef455da9859b51b0e2991ef8a3866f46..f783bac35032036fdd97d61406aae32623c2bc4f 100644 --- a/Source/Processors/ChannelMappingNode/ChannelMappingNode.cpp +++ b/Source/Processors/ChannelMappingNode/ChannelMappingNode.cpp @@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ChannelMappingNode::ChannelMappingNode() - : GenericProcessor("Channel Map"), previousChannelCount(0), channelBuffer(1,10000) + : GenericProcessor("Channel Map"), channelBuffer(1,10000) { referenceArray.resize(1024); // make room for 1024 channels channelArray.resize(1024); @@ -68,61 +68,25 @@ void ChannelMappingNode::updateSettings() if (getNumInputs() > 0) channelBuffer.setSize(getNumInputs(), 10000); - previousChannelCount = getNumInputs(); if (editorIsConfigured) { - OwnedArray<Channel> tempArray; - channels.swapWith(tempArray); - j=0; - for (int i=0; i < getNumInputs(); i++) - { - int realChan = channelArray[i]; - if (enabledChannelArray[realChan]) - { - channels.add(tempArray[realChan]); - j++; - } - } - tempArray.clear(false); - settings.numOutputs=j; + OwnedArray<Channel> oldChannels; + oldChannels.swapWith(channels); + channels.clear(); + + settings.numOutputs = 0; + + for (int i = 0; i < getNumInputs(); i++) + { + if (enabledChannelArray[channelArray[i]]) + { + channels.add(oldChannels[channelArray[i]]); + oldChannels.set(channelArray[i],nullptr,false); + settings.numOutputs++; + } + + } } - /* - if (getNumInputs() != previousChannelCount) - { - previousChannelCount = getNumInputs(); - if (editorIsConfigured) - { - j = 0; - for (int i = 0; i < getNumInputs(); i++) - { - if (enabledChannelArray[i]) - { - j++; - } - else - { - channels.remove(j); - } - } - settings.numOutputs = j; - } - } - else - { - j = 0; - for (int i = 0; i < getNumInputs(); i++) - { - if (enabledChannelArray[i]) - { - j++; - } - else - { - channels.remove(j); - } - } - settings.numOutputs=j; - }*/ } @@ -154,8 +118,7 @@ void ChannelMappingNode::setParameter(int parameterIndex, float newValue) } void ChannelMappingNode::process(AudioSampleBuffer& buffer, - MidiBuffer& midiMessages, - int& nSamples) + MidiBuffer& midiMessages) { int j=0; int i=0; @@ -177,7 +140,7 @@ void ChannelMappingNode::process(AudioSampleBuffer& buffer, channelBuffer, // source realChan, // sourceChannel 0, // sourceStartSample - nSamples, // numSamples + getNumSamples(j), // numSamples 1.0f // gain to apply to source (positive for original signal) ); @@ -190,7 +153,7 @@ void ChannelMappingNode::process(AudioSampleBuffer& buffer, channelBuffer, // source referenceChannels[referenceArray[realChan]], // sourceChannel 0, // sourceStartSample - nSamples, // numSamples + getNumSamples(j), // numSamples -1.0f // gain to apply to source (negative for reference) ); } diff --git a/Source/Processors/ChannelMappingNode/ChannelMappingNode.h b/Source/Processors/ChannelMappingNode/ChannelMappingNode.h index 46f5572589685ad9f1b81724c517aca99c06d638..0fa50e9c2cd977f3293cd7eb86395ad545aff7c2 100644 --- a/Source/Processors/ChannelMappingNode/ChannelMappingNode.h +++ b/Source/Processors/ChannelMappingNode/ChannelMappingNode.h @@ -50,7 +50,7 @@ public: ChannelMappingNode(); ~ChannelMappingNode(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); AudioProcessorEditor* createEditor(); @@ -69,7 +69,6 @@ private: Array<int> channelArray; Array<bool> enabledChannelArray; - int previousChannelCount; bool editorIsConfigured; AudioSampleBuffer channelBuffer; diff --git a/Source/Processors/DataThreads/DataThread.h b/Source/Processors/DataThreads/DataThread.h index e22a48622d39b6aaa204958af3a1aa570710297d..d6ae6e3faf006baa2662a3f8a86c662047a9092e 100755 --- a/Source/Processors/DataThreads/DataThread.h +++ b/Source/Processors/DataThreads/DataThread.h @@ -79,25 +79,31 @@ public: /** Stops data transfer.*/ virtual bool stopAcquisition() = 0; - /** Returns the number of continuous channels the data source can provide.*/ - virtual int getNumChannels() = 0; + /** Returns the number of continuous headstage channels the data source can provide.*/ + virtual int getNumHeadstageOutputs() = 0; + + /** Returns the number of continuous aux channels the data source can provide.*/ + virtual int getNumAuxOutputs() {return 0;} + + /** Returns the number of continuous ADC channels the data source can provide.*/ + virtual int getNumAdcOutputs() {return 0;} /** Returns the sample rate of the data source.*/ virtual float getSampleRate() = 0; /** Returns the volts per bit of the data source.*/ - virtual float getBitVolts(int chan) = 0; + virtual float getBitVolts(Channel* chan) = 0; /** Returns the number of event channels of the data source.*/ virtual int getNumEventChannels() { return 0; } - virtual int modifyChannelName(channelType t, int stream, int ch, String newName) + virtual int modifyChannelName(ChannelType t, int stream, int ch, String newName) { return -1; } - virtual int modifyChannelGain(channelType t, int stream, int ch, float gain) + virtual int modifyChannelGain(ChannelType t, int stream, int ch, float gain) { return -1; } @@ -105,7 +111,7 @@ public: { } - virtual void getChannelsInfo(StringArray &Names, Array<channelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains) + virtual void getChannelsInfo(StringArray &Names, Array<ChannelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains) { }; virtual void getEventChannelNames(StringArray &names) diff --git a/Source/Processors/DataThreads/EcubeThread.cpp b/Source/Processors/DataThreads/EcubeThread.cpp index d435cea3717c4ea9a331159be698cd50fbda33bf..536f836a376ae738a78e98ab5c0aca7f846d4e36 100644 --- a/Source/Processors/DataThreads/EcubeThread.cpp +++ b/Source/Processors/DataThreads/EcubeThread.cpp @@ -293,7 +293,7 @@ EcubeThread::EcubeThread(SourceNode* sn) : DataThread(sn), numberingScheme(1), a throw std::runtime_error(std::string(e.Description())); } } -void EcubeThread::getChannelsInfo(StringArray &Names_, Array<channelType> &type_, Array<int> &stream_, Array<int> &originalChannelNumber_, Array<float> &gains_) +void EcubeThread::getChannelsInfo(StringArray &Names_, Array<ChannelType> &type_, Array<int> &stream_, Array<int> &originalChannelNumber_, Array<float> &gains_) { Names_ = Names; type_ = type; @@ -312,14 +312,18 @@ void EcubeThread::setDefaultChannelNamesAndType() gains.clear(); originalChannelNumber.clear(); String prefix; - channelType common_type; + ChannelType common_type; int numch = getNumChannels(); if (pDevInt->data_format == EcubeDevInt::dfSeparateChannelsAnalog) { prefix = "HS_CH"; +<<<<<<< HEAD common_type = DATA_CHANNEL; +======= + common_type = HEADSTAGE_CHANNEL; +>>>>>>> multisamplerate } else if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog) { @@ -376,6 +380,29 @@ EcubeThread::~EcubeThread() waitForThreadToExit(-1); } +int EcubeThread::getNumHeadstageOutputs() +{ + if (pDevInt->data_format == EcubeDevInt::dfSeparateChannelsAnalog) + return pDevInt->n_channel_objects; + else + return 0; +} + +int EcubeThread::getNumAdcOutputs() +{ + if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog) + return 32; + else if (pDevInt->data_format == EcubeDevInt::dfDigital) + return 64; + else + return 0; +} + +int EcubeThread::getNumAuxOutputs() +{ + return 0; +} + int EcubeThread::getNumChannels() { if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog) @@ -410,6 +437,14 @@ float EcubeThread::getSampleRate() } float EcubeThread::getBitVolts(int chan) +{ + if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog || pDevInt->data_format == EcubeDevInt::dfDigital) + return 10.0/32768; // Volts per bit for front panel analog input and fictive v/bit for the digital input + else + return 6.25e3 / 32768; // Microvolts per bit for the headstage channels +} + +float EcubeThread::getBitVolts(Channel* chan) { if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog || pDevInt->data_format == EcubeDevInt::dfDigital) return 10.0 / 32768; // Volts per bit for front panel analog input and fictive v/bit for the digital input @@ -506,7 +541,11 @@ bool EcubeThread::updateBuffer() const short* pData = (const short*)dp; for (unsigned j = 0; j < datasize; j++) { +<<<<<<< HEAD pDevInt->interleaving_buffer[j] = pData[j] * 10.0 / 32768; // Convert into volts +======= + pDevInt->interleaving_buffer[j] = pData[j] * 10.0/32768; // Convert into volts +>>>>>>> multisamplerate } unsigned long datasam = datasize / 32; int64 cts = pDevInt->buf_timestamp64 / 3200; // Convert eCube's 80MHz timestamps into number of samples on the Panel Analog input (orig sample rate 1144) diff --git a/Source/Processors/DataThreads/EcubeThread.h b/Source/Processors/DataThreads/EcubeThread.h index 22ef74931ae18dffca2c5e38e5d6c535c818668f..44be9a7011cf4eb55de9fbc66ce2efb5ec9e1d70 100644 --- a/Source/Processors/DataThreads/EcubeThread.h +++ b/Source/Processors/DataThreads/EcubeThread.h @@ -76,6 +76,12 @@ public: /** Returns the number of continuous channels the data source can provide.*/ virtual int getNumChannels(); + virtual int getNumHeadstageOutputs(); + + virtual int getNumAdcOutputs(); + + virtual int getNumAuxOutputs(); + /** Returns the number of event channels of the data source.*/ virtual int getNumEventChannels(); @@ -88,7 +94,9 @@ public: /** Returns the volts per bit of a given data channel.*/ virtual float getBitVolts(int chan); - virtual void getChannelsInfo(StringArray &Names, Array<channelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains); + virtual float getBitVolts(Channel* chan); + + virtual void getChannelsInfo(StringArray &Names, Array<ChannelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains); void setDefaultNamingScheme(int scheme); /** Changes the names of channels, if the thread needs custom names. */ virtual void updateChannelNames(); @@ -100,7 +108,7 @@ private: // used for data stream names... int numberingScheme; StringArray Names; - Array<channelType> type; + Array<ChannelType> type; Array<float> gains; Array<int> stream; Array<int> originalChannelNumber; diff --git a/Source/Processors/DataThreads/RHD2000Editor.cpp b/Source/Processors/DataThreads/RHD2000Editor.cpp index b40c3519534614db5b67bb4861567a8ea3272735..b2c3fea9d80b0b74b06c037976b4d81b0e91b643 100644 --- a/Source/Processors/DataThreads/RHD2000Editor.cpp +++ b/Source/Processors/DataThreads/RHD2000Editor.cpp @@ -165,7 +165,7 @@ void FPGAchannelList::update() streamNames.add("Port D2"); streamNames.add("ADC"); - for (int k=0; k<MAX_NUM_DATA_STREAMS+1; k++) + for (int k = 0; k < MAX_NUM_DATA_STREAMS + 1; k++) { if (streamActive[k]) { @@ -181,12 +181,12 @@ void FPGAchannelList::update() } - // add buttons for all DATA,AUX,channels - for (int k=0; k<numChannels; k++) + // add buttons for all DATA, AUX, channels + for (int k = 0; k < numChannels; k++) { int channelGainIndex = 1; - float ch_gain = oldgains[k]/static_cast<SourceNode*>(proc)->getBitVolts(k); - for (int j=0; j<gains.size(); j++) + float ch_gain = 1.0f; ///%oldgains[k]/static_cast<SourceNode*>(proc)->getBitVolts(k); + for (int j = 0; j < gains.size(); j++) { if (fabs(gains[j]-ch_gain) < 1e-3) { @@ -244,7 +244,7 @@ void FPGAchannelList::enableAll() } -void FPGAchannelList::setNewGain(int stream, int channel, channelType type, float gain) +void FPGAchannelList::setNewGain(int stream, int channel, ChannelType type, float gain) { float newGain; int realChan; @@ -258,11 +258,11 @@ void FPGAchannelList::setNewGain(int stream, int channel, channelType type, floa { realChan = channel; } - newGain = p->getBitVolts(realChan)*gain; + //newGain = p->getBitVolts(realChan)*gain; p->modifyChannelGain(stream, channel, type, newGain, true); } -void FPGAchannelList::setNewName(int stream, int channelIndex, channelType t, String newName) +void FPGAchannelList::setNewName(int stream, int channelIndex, ChannelType t, String newName) { proc->modifyChannelName(t, stream, channelIndex, newName, true); } @@ -301,7 +301,7 @@ void FPGAchannelList::updateImpedance(Array<int> streams, Array<int> channels, A { for (int j=k; j<stream.size(); j++) { - if (stream[j] == streams[k] && types[j] == DATA_CHANNEL && orig_number[j] == channels[k]) + if (stream[j] == streams[k] && types[j] == HEADSTAGE_CHANNEL && orig_number[j] == channels[k]) { channelComponents[j]->setImpedanceValues(magnitude[k],phase[k]); break; @@ -314,7 +314,7 @@ void FPGAchannelList::updateImpedance(Array<int> streams, Array<int> channels, A /****************************************************/ -FPGAchannelComponent::FPGAchannelComponent(FPGAchannelList* cl, int stream_, int ch, channelType t, int gainIndex_, String N, Array<float> gains_) : gains(gains_), channelList(cl), channel(ch), name(N), stream(stream_), type(t), gainIndex(gainIndex_) +FPGAchannelComponent::FPGAchannelComponent(FPGAchannelList* cl, int stream_, int ch, ChannelType t, int gainIndex_, String N, Array<float> gains_) : gains(gains_), channelList(cl), channel(ch), name(N), stream(stream_), type(t), gainIndex(gainIndex_) { Font f = Font("Small Text", 13, Font::plain); @@ -353,7 +353,7 @@ FPGAchannelComponent::FPGAchannelComponent(FPGAchannelList* cl, int stream_, int gainComboBox = nullptr; } - if (type == DATA_CHANNEL) + if (type == HEADSTAGE_CHANNEL) { impedance = new Label("Impedance","? Ohm"); impedance->setFont(Font("Default", 13, Font::plain)); @@ -710,7 +710,7 @@ void RHD2000Editor::measureImpedance() for (int i = 0; i < channel.size(); i++) { XmlElement* chan = new XmlElement("CHANNEL"); - chan->setAttribute("name",board->getChannelName(DATA_CHANNEL,stream[i],channel[i])); + chan->setAttribute("name",board->getChannelName(HEADSTAGE_CHANNEL,stream[i],channel[i])); chan->setAttribute("stream",stream[i]); chan->setAttribute("channel_number",channel[i]); chan->setAttribute("magnitude",magnitude[i]); diff --git a/Source/Processors/DataThreads/RHD2000Editor.h b/Source/Processors/DataThreads/RHD2000Editor.h index 4caa6630cf1633bf7e5a9f851e83cf075d79d7bb..6a997b6c5c3a469ff9a9bcc24e4c8eca09dca1e4 100644 --- a/Source/Processors/DataThreads/RHD2000Editor.h +++ b/Source/Processors/DataThreads/RHD2000Editor.h @@ -59,8 +59,8 @@ public: FPGAchannelList(GenericProcessor* proc, Viewport *p, FPGAcanvas*c); ~FPGAchannelList(); - void setNewName(int stream, int channelIndex, channelType t, String newName); - void setNewGain(int stream, int channel,channelType t, float gain); + void setNewName(int stream, int channelIndex, ChannelType t, String newName); + void setNewGain(int stream, int channel, ChannelType t, float gain); void disableAll(); void enableAll(); void paint(Graphics& g); @@ -74,7 +74,7 @@ public: private: Array<float> gains; - Array<channelType> types; + Array<ChannelType> types; Array<int> stream; Array<int> orig_number; @@ -94,7 +94,7 @@ private: class FPGAchannelComponent : public Component, public AccessClass, Button::Listener, public ComboBox::Listener, public Label::Listener { public: - FPGAchannelComponent(FPGAchannelList* cl,int stream, int ch, channelType t, int gainIndex_, String name_, Array<float> gains_); + FPGAchannelComponent(FPGAchannelList* cl,int stream, int ch, ChannelType t, int gainIndex_, String name_, Array<float> gains_); ~FPGAchannelComponent(); Colour getDefaultColor(int ID); void setImpedanceValues(float mag, float phase); @@ -122,7 +122,7 @@ private: int channel; String name; int stream; - channelType type; + ChannelType type; int gainIndex; int userDefinedData; Font font; @@ -146,8 +146,10 @@ public: void refreshState(); void update(); - void setParameter(int, float) ; - void setParameter(int, int, int, float) ; + + void setParameter(int, float); + void setParameter(int, int, int, float); + void updateImpedance(Array<int> streams, Array<int> channels, Array<float> magnitude, Array<float> phase); void resized(); @@ -196,10 +198,10 @@ private: ScopedPointer<AudioInterface> audioInterface; ScopedPointer<UtilityButton> rescanButton,dacTTLButton; - ScopedPointer<UtilityButton> adcButton; + ScopedPointer<UtilityButton> adcButton; - ScopedPointer<UtilityButton> dspoffsetButton; - ScopedPointer<ComboBox> ttlSettleCombo,dacHPFcombo; + ScopedPointer<UtilityButton> dspoffsetButton; + ScopedPointer<ComboBox> ttlSettleCombo,dacHPFcombo; ScopedPointer<Label> audioLabel,ttlSettleLabel,dacHPFlabel ; diff --git a/Source/Processors/DataThreads/RHD2000Thread.cpp b/Source/Processors/DataThreads/RHD2000Thread.cpp index 8d13a9299380914d8e9fe89c5024b60ab37d7bfb..6a6fb639228eaafb1caa84b3fab3518a3db8ca45 100644 --- a/Source/Processors/DataThreads/RHD2000Thread.cpp +++ b/Source/Processors/DataThreads/RHD2000Thread.cpp @@ -138,7 +138,9 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn), } evalBoard->getDacInformation(dacChannels,dacThresholds); - sn->setDefaultNamingScheme(numberingScheme); + + //sn->setDefaultNamingScheme(numberingScheme); + //setDefaultChannelNamesAndType(); } } @@ -671,24 +673,16 @@ void RHD2000Thread::setNumChannels(int hsNum, int numChannels) } -int RHD2000Thread::getNumADCchannels() -{ - if (acquireAdcChannels) - return 8; - else - return 0; -} - void RHD2000Thread::getEventChannelNames(StringArray& Names) { Names.clear(); - for (int k=0; k<8; k++) + for (int k = 0; k < 8; k++) { Names.add("TTL"+String(k+1)); } } -void RHD2000Thread::getChannelsInfo(StringArray& Names_, Array<channelType>& type_, Array<int>& stream_, Array<int>& originalChannelNumber_,Array<float>& gains_) +void RHD2000Thread::getChannelsInfo(StringArray& Names_, Array<ChannelType>& type_, Array<int>& stream_, Array<int>& originalChannelNumber_,Array<float>& gains_) { Names_ = Names; type_ = type; @@ -704,14 +698,14 @@ void RHD2000Thread::updateChannelNames() for (int i = 0; i < sn->channels.size(); i++) { sn->channels[i]->setName(Names[i]); - sn->channels[i]->setGain(gains[i]); + sn->channels[i]->bitVolts = gains[i]; sn->channels[i]->setType(type[i]); } } /* go over the old names and tests whether this particular channel name was changed. if so, return the old name */ -bool RHD2000Thread::channelModified(channelType t, int str, int ch, String& oldName, float& oldGain, int& index) +bool RHD2000Thread::channelModified(ChannelType t, int str, int ch, String& oldName, float& oldGain, int& index) { for (int k = 0; k < oldNames.size(); k++) { @@ -727,7 +721,7 @@ bool RHD2000Thread::channelModified(channelType t, int str, int ch, String& oldN } -int RHD2000Thread::modifyChannelName(channelType t, int str, int ch, String newName) +int RHD2000Thread::modifyChannelName(ChannelType t, int str, int ch, String newName) { String dummy; float dummyFloat = 0; @@ -738,17 +732,17 @@ int RHD2000Thread::modifyChannelName(channelType t, int str, int ch, String newN } else { - oldNames.add(newName); - oldType.add(t); - oldStream.add(str); - oldChannelNumber.add(ch); - if (t == ADC_CHANNEL) - oldGains.add(gains[getNumChannels()-getNumADCchannels()+ch]); - else - oldGains.add(gains[ch]); + // oldNames.add(newName); + // oldType.add(t); + // oldStream.add(str); + // oldChannelNumber.add(ch); + // if (t == ADC_CHANNEL) + // oldGains.add(gains[getNumChannels()-getNumADCchannels()+ch]); + // else + // oldGains.add(gains[ch]); } - for (int k=0; k<Names.size(); k++) + for (int k = 0; k < Names.size(); k++) { if (type[k] == t && stream[k] == str && originalChannelNumber[k] == ch) { @@ -759,7 +753,7 @@ int RHD2000Thread::modifyChannelName(channelType t, int str, int ch, String newN return -1; } -String RHD2000Thread::getChannelName(channelType t, int str, int ch) +String RHD2000Thread::getChannelName(ChannelType t, int str, int ch) { for (int k=0; k<Names.size(); k++) { @@ -770,10 +764,10 @@ String RHD2000Thread::getChannelName(channelType t, int str, int ch) } } -int RHD2000Thread::modifyChannelGain(channelType t, int str, int ch, float gain) +int RHD2000Thread::modifyChannelGain(ChannelType t, int str, int ch, float gain) { String dummy; - float dummyFloat=0; + float dummyFloat = 0; int index; if (channelModified(t, str, ch, dummy, dummyFloat, index)) { @@ -781,6 +775,7 @@ int RHD2000Thread::modifyChannelGain(channelType t, int str, int ch, float gain) } else { + if (t == ADC_CHANNEL) oldNames.add(Names[getNumChannels()-getNumADCchannels()+ch]); else @@ -789,6 +784,7 @@ int RHD2000Thread::modifyChannelGain(channelType t, int str, int ch, float gain) oldStream.add(str); oldChannelNumber.add(ch); oldGains.add(gain); + } for (int k=0; k<Names.size(); k++) @@ -843,9 +839,9 @@ void RHD2000Thread::setDefaultChannelNamesAndType() { for (int k = 0; k < numChannelsPerDataStream[i]; k++) { - type.add(DATA_CHANNEL); + type.add(HEADSTAGE_CHANNEL); - if (channelModified(DATA_CHANNEL,i,k, oldName,oldGain,dummy)) + if (channelModified(HEADSTAGE_CHANNEL,i,k, oldName,oldGain,dummy)) { Names.add(oldName); gains.add(oldGain); @@ -858,7 +854,7 @@ void RHD2000Thread::setDefaultChannelNamesAndType() else Names.add("CH_"+stream_prefix[i]+"_"+String(1+k)); - gains.add(getBitVolts(channelNumber)); + // gains.add(getBitVolts(channelNumber)); } stream.add(i); @@ -917,7 +913,7 @@ void RHD2000Thread::setDefaultChannelNamesAndType() else { Names.add("ADC" + String(k+1)); - gains.add(getADCBitVolts(k)); + gains.add(getAdcBitVolts(k)); } stream.add(MAX_NUM_DATA_STREAMS); @@ -929,6 +925,11 @@ void RHD2000Thread::setDefaultChannelNamesAndType() } int RHD2000Thread::getNumChannels() +{ + return getNumHeadstageOutputs() + getNumAdcOutputs() + getNumAuxOutputs(); +} + +int RHD2000Thread::getNumHeadstageOutputs() { numChannels = 0; for (int i = 0; i < MAX_NUM_DATA_STREAMS; i++) @@ -937,13 +938,8 @@ int RHD2000Thread::getNumChannels() if (numChannelsPerDataStream[i] > 0) { numChannels += numChannelsPerDataStream[i]; - numChannels += 3; // to account for aux inputs } } - if (acquireAdcChannels) - { - numChannels += 8; // add 8 channels for the ADCs - } if (numChannels > 0) return numChannels; @@ -951,7 +947,31 @@ int RHD2000Thread::getNumChannels() return 1; // to prevent crashing with 0 channels } +int RHD2000Thread::getNumAuxOutputs() +{ + int numAuxOutputs = 0; + + for (int i = 0; i < MAX_NUM_DATA_STREAMS; i++) + { + if (numChannelsPerDataStream[i] > 0) + { + numAuxOutputs += 3; + } + } + + return numAuxOutputs; + +} +int RHD2000Thread::getNumAdcOutputs() +{ + if (acquireAdcChannels) + { + return 8; + } else { + return 0; + } +} int RHD2000Thread::getNumEventChannels() { @@ -963,18 +983,22 @@ float RHD2000Thread::getSampleRate() return evalBoard->getSampleRate(); } -float RHD2000Thread::getBitVolts(int chan) +float RHD2000Thread::getBitVolts(Channel* ch) { - if (type[chan] == ADC_CHANNEL) - return 0.00015258789; + if (ch->type == ADC_CHANNEL) + return getAdcBitVolts(ch->index); + else if (ch->type == AUX_CHANNEL) + return 0.0000374; else return 0.195f; } -float RHD2000Thread::getADCBitVolts(int chan) +float RHD2000Thread::getAdcBitVolts(int chan) { - return 0.00015258789; - + if (chan < adcBitVolts.size()) + return adcBitVolts[chan]; + else + return 0.00015258789; } double RHD2000Thread::setUpperBandwidth(double upper) @@ -1131,7 +1155,7 @@ void RHD2000Thread::enableAdcs(bool t) acquireAdcChannels = t; dataBuffer->resize(getNumChannels(), 10000); - //updateChannelNames(); + } diff --git a/Source/Processors/DataThreads/RHD2000Thread.h b/Source/Processors/DataThreads/RHD2000Thread.h index 3bc7baca14fa8273ed4b4de9e49d5488f560e5e4..6eb6c031de3f59ef9346261b51a5ad3efed7e173 100644 --- a/Source/Processors/DataThreads/RHD2000Thread.h +++ b/Source/Processors/DataThreads/RHD2000Thread.h @@ -58,12 +58,17 @@ public: RHD2000Thread(SourceNode* sn); ~RHD2000Thread(); + // for communication with SourceNode processors: bool foundInputSource(); int getNumChannels(); + int getNumHeadstageOutputs(); + int getNumAuxOutputs(); + int getNumAdcOutputs(); float getSampleRate(); - float getBitVolts(int chan); - float getADCBitVolts(int chan); + float getBitVolts(Channel* chan); + float getAdcBitVolts(int channelNum); + // for internal use: bool isHeadstageEnabled(int hsNum); bool enableHeadstage(int hsNum, bool enabled); @@ -98,16 +103,15 @@ public: const std::vector<double> &data, int startIndex, int endIndex, double sampleRate, double frequency); int getNumEventChannels(); - int getNumADCchannels(); void assignAudioOut(int dacChannel, int dataChannel); void enableAdcs(bool); bool isAcquisitionActive(); - virtual int modifyChannelGain(channelType t, int str, int ch, float gain); - virtual int modifyChannelName(channelType t, int str, int k, String newName); - virtual void getChannelsInfo(StringArray &Names, Array<channelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains); + virtual int modifyChannelGain(ChannelType t, int str, int ch, float gain); + virtual int modifyChannelName(ChannelType t, int str, int k, String newName); + virtual void getChannelsInfo(StringArray &Names, Array<ChannelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains); virtual void getEventChannelNames(StringArray &Names); void updateChannelNames(); Array<int> getDACchannels(); @@ -115,11 +119,11 @@ public: void setDACthreshold(int dacOutput, float threshold); void setDefaultNamingScheme(int scheme); - String getChannelName(channelType t, int str, int ch); + String getChannelName(ChannelType t, int str, int ch); private: void setDefaultChannelNamesAndType(); - bool channelModified(channelType t, int str, int k, String &oldName, float &oldGain, int &index); + bool channelModified(ChannelType t, int str, int k, String &oldName, float &oldGain, int &index); ScopedPointer<Rhd2000EvalBoard> evalBoard; Rhd2000Registers chipRegisters; @@ -188,8 +192,9 @@ private: // used for data stream names... int numberingScheme ; StringArray Names, oldNames; - Array<channelType> type, oldType; + Array<ChannelType> type, oldType; Array<float> gains, oldGains; + Array<float> adcBitVolts; Array<int> stream, oldStream; Array<bool> modifiedName, oldModifiedName; Array<int> originalChannelNumber, oldChannelNumber; diff --git a/Source/Processors/Editors/ChannelSelector.cpp b/Source/Processors/Editors/ChannelSelector.cpp index aa17fde9099cc32d0c4fe132b50b5121a809f795..0c5b243d728800ee8af867a01e0e511c10a3b0df 100755 --- a/Source/Processors/Editors/ChannelSelector.cpp +++ b/Source/Processors/Editors/ChannelSelector.cpp @@ -132,12 +132,12 @@ void ChannelSelector::setNumChannels(int numChans) //Reassign numbers according to the actual channels (useful for channel mapper) for (int n = 0; n < parameterButtons.size(); n++) { - int num = ((GenericEditor*)getParentComponent())->getChannel(n)->num + 1; - parameterButtons[n]->setChannel(num); + int num = ((GenericEditor*)getParentComponent())->getChannel(n)->nodeIndex; + parameterButtons[n]->setChannel(n+1, num+1); if (isNotSink) { - recordButtons[n]->setChannel(num); - audioButtons[n]->setChannel(num); + recordButtons[n]->setChannel(n+1, num+1); + audioButtons[n]->setChannel(n+1, num+1); } } @@ -596,7 +596,7 @@ void ChannelSelector::buttonClicked(Button* button) //int channelNum = editor->getStartChannel() + b->getChannel() - 1; bool status = b->getToggleState(); - std::cout << "Requesting audio monitor for channel " << ch->num << std::endl; + std::cout << "Requesting audio monitor for channel " << ch->nodeIndex+1 << std::endl; if (acquisitionIsActive) // use setParameter to change parameter safely { @@ -820,6 +820,7 @@ ChannelSelectorButton::ChannelSelectorButton(int num_, int type_, Font& f) : But { isActive = true; num = num_; + displayNum = num_; type = type_; setClickingTogglesState(true); @@ -855,7 +856,7 @@ void ChannelSelectorButton::paintButton(Graphics& g, bool isMouseOver, bool isBu // g.drawRect(0,0,getWidth(),getHeight(),1.0); - g.drawText(String(num),0,0,getWidth(),getHeight(),Justification::centred,true); + g.drawText(String(displayNum),0,0,getWidth(),getHeight(),Justification::centred,true); } void ChannelSelectorButton::setActive(bool t) diff --git a/Source/Processors/Editors/ChannelSelector.h b/Source/Processors/Editors/ChannelSelector.h index 3eff6ca7b6f410af7883f27c4374844204472f2d..a8cad65f21c90c8e63d80319d81327c9b12d607f 100755 --- a/Source/Processors/Editors/ChannelSelector.h +++ b/Source/Processors/Editors/ChannelSelector.h @@ -306,6 +306,12 @@ public: void setChannel(int n) { num = n; + displayNum = n; + } + void setChannel(int n, int d) + { + num = n; + displayNum = d; } private: @@ -315,6 +321,7 @@ private: int type; int num; + int displayNum; Font buttonFont; bool isActive; }; diff --git a/Source/Processors/Editors/PeriStimulusTimeHistogramEditor.cpp b/Source/Processors/Editors/PeriStimulusTimeHistogramEditor.cpp index 2de456adcc5fb0ba548270e70c268481955384ad..d79d3edcec8f705414808b060f0b5cfa08644c9c 100644 --- a/Source/Processors/Editors/PeriStimulusTimeHistogramEditor.cpp +++ b/Source/Processors/Editors/PeriStimulusTimeHistogramEditor.cpp @@ -154,9 +154,12 @@ void PeriStimulusTimeHistogramEditor::loadVisualizerParameters(XmlElement* xml) void PeriStimulusTimeHistogramEditor::comboBoxChanged(ComboBox* comboBox) { + if (comboBox == hardwareTrialAlignment) { - // TODO + std::cout << "Setting hardware trigger alignment channel to " << comboBox->getSelectedId()-2 << std::endl; + PeriStimulusTimeHistogramNode* processor = (PeriStimulusTimeHistogramNode*) getProcessor(); + processor->setHardwareTriggerAlignmentChannel(comboBox->getSelectedId()-2); } } @@ -363,8 +366,8 @@ Visualizer* PeriStimulusTimeHistogramEditor::createNewCanvas() { PeriStimulusTimeHistogramNode* processor = (PeriStimulusTimeHistogramNode*) getProcessor(); periStimulusTimeHistogramCanvas = new PeriStimulusTimeHistogramCanvas(processor); -// ActionListener* listener = (ActionListener*) periStimulusTimeHistogramCanvas; -// getUIComponent()->registerAnimatedComponent(listener); + //ActionListener* listener = (ActionListener*) periStimulusTimeHistogramCanvas; + //getUIComponent()->registerAnimatedComponent(listener); return periStimulusTimeHistogramCanvas; } @@ -462,7 +465,9 @@ PeriStimulusTimeHistogramCanvas::~PeriStimulusTimeHistogramCanvas() void PeriStimulusTimeHistogramCanvas::beginAnimation() { - //startCallbacks(); + + std::cout << "PeriStimulusTimeHistogramCanvas starting animation." << std::endl; + startCallbacks(); } @@ -502,9 +507,9 @@ void PeriStimulusTimeHistogramCanvas::buttonClicked(Button* button) void PeriStimulusTimeHistogramCanvas::endAnimation() { - std::cout << "SpikeDisplayCanvas ending animation." << std::endl; + std::cout << "PeriStimulusTimeHistogramCanvas ending animation." << std::endl; - //stopCallbacks(); + stopCallbacks(); } void PeriStimulusTimeHistogramCanvas::setRasterMode(bool rasterModeActive) @@ -617,7 +622,7 @@ void PeriStimulusTimeHistogramCanvas::update() widthPerUnit = 300; int maxUnitsPerRow = (screenWidth-conditionWidth)/ widthPerUnit; updateNeeded = false; - for (int k=0; k < psthDisplay->psthPlots.size();k++) + for (int k = 0; k < psthDisplay->psthPlots.size(); k++) { delete psthDisplay->psthPlots[k]; } @@ -635,7 +640,7 @@ void PeriStimulusTimeHistogramCanvas::update() numCols = 0; numRows = 0; int plotID = 0; - for (int e=0;e<numElectrodes;e++) + for (int e = 0; e < numElectrodes; e++) { int offset = 0; bool plottedSomething = false; @@ -782,12 +787,10 @@ void PeriStimulusTimeHistogramCanvas::resized() visualizationButton->setBounds(20,5,150,20); clearAllButton->setBounds(200,5,150,20); - zoomButton->setBounds(360,5,60,20); panButton->setBounds(440,5,60,20); resetAxesButton->setBounds(510,5,150,20); - } void PeriStimulusTimeHistogramCanvas::paint(Graphics& g) @@ -831,7 +834,6 @@ void PeriStimulusTimeHistogramDisplay::refresh() } - void PeriStimulusTimeHistogramDisplay::paint(Graphics &g) { g.setColour(Colours::white); @@ -845,7 +847,6 @@ void PeriStimulusTimeHistogramDisplay::paint(Graphics &g) */ } - void PeriStimulusTimeHistogramDisplay::setAutoRescale(bool state) { // draw n by m grid @@ -881,7 +882,6 @@ void PeriStimulusTimeHistogramDisplay::resized() } } - void PeriStimulusTimeHistogramDisplay::focusOnPlot(int plotID) { int plotIndex = -1; diff --git a/Source/Processors/Editors/PeriStimulusTimeHistogramEditor.h b/Source/Processors/Editors/PeriStimulusTimeHistogramEditor.h index add3a2128865eabf435dcbd963f390c046eb53d2..b184a5e32b6627462dcfd3d56e7b411805effdbc 100644 --- a/Source/Processors/Editors/PeriStimulusTimeHistogramEditor.h +++ b/Source/Processors/Editors/PeriStimulusTimeHistogramEditor.h @@ -65,7 +65,6 @@ class PeriStimulusTimeHistogramDisplay : public Component public: PeriStimulusTimeHistogramDisplay(PeriStimulusTimeHistogramNode* n, Viewport *p, PeriStimulusTimeHistogramCanvas*c); ~PeriStimulusTimeHistogramDisplay(); - void setAutoRescale(bool state); void resized(); @@ -81,21 +80,14 @@ public: juce::Font font; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PeriStimulusTimeHistogramDisplay); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PeriStimulusTimeHistogramDisplay); }; - - - - - class ProcessorListItem; class UIComponent; - class ConditionList : public Component, public AccessClass, Button::Listener @@ -129,9 +121,6 @@ private: }; - - - class PeriStimulusTimeHistogramCanvas: public Visualizer, public Button::Listener { public: @@ -173,7 +162,7 @@ public: int heightPerElectrodePix; int widthPerUnit; bool updateNeeded; - int screenHeight, screenWidth; + int screenHeight, screenWidth; private: int conditionWidth; @@ -187,13 +176,11 @@ public: float gaussianStandardDeviationMS; int numRows,numCols; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PeriStimulusTimeHistogramCanvas); }; - class PeriStimulusTimeHistogramEditor : public VisualizerEditor, public ComboBox::Listener { @@ -251,7 +238,6 @@ private: void paintLFPraster(Graphics &g); void paintLFP(Graphics &g); - ScopedPointer<MatlabLikePlot> mlp; PeriStimulusTimeHistogramDisplay* display; TrialCircularBuffer *tcb; diff --git a/Source/Processors/EventDetector/EventDetector.cpp b/Source/Processors/EventDetector/EventDetector.cpp index 4afe33258a5e9c1c87e3c02bf39ea6cfa9532850..89198cd9e65d272e93aa936d22abedc06e1102fa 100755 --- a/Source/Processors/EventDetector/EventDetector.cpp +++ b/Source/Processors/EventDetector/EventDetector.cpp @@ -57,14 +57,13 @@ void EventDetector::setParameter(int parameterIndex, float newValue) } void EventDetector::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { //std::cout << *buffer.getReadPointer(0, 0) << std::endl; - for (int i = 0; i < nSamples; i++) + for (int i = 0; i < getNumSamples(channels[0]->sourceNodeId); i++) { if ((*buffer.getReadPointer(0, i) < -threshold) && !state) diff --git a/Source/Processors/EventDetector/EventDetector.h b/Source/Processors/EventDetector/EventDetector.h index d99efdc26e54da857e02bda0ccdc926bab96c8d2..2d8e44bfe93ecaf34926f6382878c0cedd90e5e4 100755 --- a/Source/Processors/EventDetector/EventDetector.h +++ b/Source/Processors/EventDetector/EventDetector.h @@ -43,7 +43,7 @@ public: EventDetector(); ~EventDetector(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); private: diff --git a/Source/Processors/EventNode/EventNode.cpp b/Source/Processors/EventNode/EventNode.cpp index 4c96d18b78fa3e046efce1d9f889e78815ee94e9..4420a1baa0e8bd3087aab9eda9a11067551936e7 100755 --- a/Source/Processors/EventNode/EventNode.cpp +++ b/Source/Processors/EventNode/EventNode.cpp @@ -55,8 +55,8 @@ void EventNode::updateSettings() { // add event channels - Channel* ch = new Channel(this, 1); - ch->name = "Trigger"; + Channel* ch = new Channel(this, 1, EVENT_CHANNEL); + ch->setName("Trigger"); eventChannels.add(ch); @@ -71,8 +71,7 @@ void EventNode::updateSettings() void EventNode::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { events.clear(); diff --git a/Source/Processors/EventNode/EventNode.h b/Source/Processors/EventNode/EventNode.h index 8f5e03f5fa582097972eb7afbe7960bcc9112162..b0e2a6e82d3915b998cf8b09dcf014c45654c6e2 100755 --- a/Source/Processors/EventNode/EventNode.h +++ b/Source/Processors/EventNode/EventNode.h @@ -44,7 +44,7 @@ public: EventNode(); ~EventNode(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); //void setParameter (int parameterIndex, float newValue); bool isSource() @@ -52,7 +52,7 @@ public: return true; } - int getDefaultNumOutputs() + int getNumHeadstageOutputs() { return 0; } diff --git a/Source/Processors/ExampleProcessor/ExampleProcessor.cpp b/Source/Processors/ExampleProcessor/ExampleProcessor.cpp index 2ebc64073b709fe6e2ef9a954e1bcd82139e285c..fa26ecd40ddf3028db62b58bc1948656c474c66b 100644 --- a/Source/Processors/ExampleProcessor/ExampleProcessor.cpp +++ b/Source/Processors/ExampleProcessor/ExampleProcessor.cpp @@ -56,11 +56,10 @@ void ExampleProcessor::setParameter(int parameterIndex, float newValue) } void ExampleProcessor::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { - // for (int i = 0; i < nSamples; i++) + // for (int i = 0; i < getNumSamples(channels[0]->sourceNodeId); i++) // { // // if ((*buffer.getReadPointer(0, i) < -threshold) && !state) diff --git a/Source/Processors/ExampleProcessor/ExampleProcessor.h b/Source/Processors/ExampleProcessor/ExampleProcessor.h index 7bf796cef1dd14f9eca571bacadad22ef1b11d1d..9307bbe029e0777951a6f7c556e84e9cd5bf0fdb 100644 --- a/Source/Processors/ExampleProcessor/ExampleProcessor.h +++ b/Source/Processors/ExampleProcessor/ExampleProcessor.h @@ -77,7 +77,7 @@ public: number of continous samples in the current buffer (which may differ from the size of the buffer). */ - void process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& events); /** Any variables used by the "process" function _must_ be modified only through this method while data acquisition is active. If they are modified in any diff --git a/Source/Processors/FPGAOutput/FPGAOutput.cpp b/Source/Processors/FPGAOutput/FPGAOutput.cpp index 6e313cea80263e8b1158d592cb47fa93a3582125..089eeb02c5b865dae8d775dc5b69c9dc187ee83a 100755 --- a/Source/Processors/FPGAOutput/FPGAOutput.cpp +++ b/Source/Processors/FPGAOutput/FPGAOutput.cpp @@ -157,14 +157,10 @@ void FPGAOutput::setParameter(int parameterIndex, float newValue) } void FPGAOutput::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { - checkForEvents(events); - - } void FPGAOutput::timerCallback() diff --git a/Source/Processors/FPGAOutput/FPGAOutput.h b/Source/Processors/FPGAOutput/FPGAOutput.h index 8c1b3d5ae7f235f36acbf869b42da0866f8aabdd..b81479a028b731881247d2f929c277deef392226 100755 --- a/Source/Processors/FPGAOutput/FPGAOutput.h +++ b/Source/Processors/FPGAOutput/FPGAOutput.h @@ -49,7 +49,7 @@ public: FPGAOutput(); ~FPGAOutput(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); void handleEvent(int eventType, MidiMessage& event, int sampleNum); diff --git a/Source/Processors/FileReader/FileReader.cpp b/Source/Processors/FileReader/FileReader.cpp index edb0d18c6c4df5a4789fcf91b1972e64236dcd12..bdeb3f014c73d893052b4cfa9d0e69b8421ff432 100644 --- a/Source/Processors/FileReader/FileReader.cpp +++ b/Source/Processors/FileReader/FileReader.cpp @@ -35,6 +35,7 @@ FileReader::FileReader() enabledState(false); + counter = 0; } @@ -72,7 +73,7 @@ float FileReader::getDefaultSampleRate() return 44100.0; } -int FileReader::getDefaultNumOutputs() +int FileReader::getNumHeadstageOutputs() { if (input) return currentNumChannels; @@ -80,10 +81,15 @@ int FileReader::getDefaultNumOutputs() return 16; } -float FileReader::getBitVolts(int chan) +int FileReader::getNumEventChannels() +{ + return 8; +} + +float FileReader::getBitVolts(Channel* chan) { if (input) - return channelInfo[chan].bitVolts; + return chan->bitVolts; else return 0.05f; } @@ -158,74 +164,45 @@ String FileReader::getFile() void FileReader::updateSettings() { - if (!input) return; + // if (!input) return; - for (int i=0; i < currentNumChannels; i++) - { - channels[i]->bitVolts = channelInfo[i].bitVolts; - channels[i]->name = channelInfo[i].name; - } + // for (int i=0; i < currentNumChannels; i++) + // { + // channels[i]->bitVolts = channelInfo[i].bitVolts; + // channels[i]->name = channelInfo[i].name; + // } } -void FileReader::process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples) +void FileReader::process(AudioSampleBuffer& buffer, MidiBuffer& events) { - uint8 data[8]; - memcpy(data, ×tamp, 8); - - // generate timestamp - addEvent(events, // MidiBuffer - TIMESTAMP, // eventType - 0, // sampleNum - nodeId, // eventID - 0, // eventChannel - 8, // numBytes - data // data - ); + setTimestamp(events, timestamp); + int samplesNeeded = (int) float(buffer.getNumSamples()) * (getDefaultSampleRate()/44100.0f); // FIXME: needs to account for the fact that the ratio might not be an exact // integer value - // code for testing events: - // if (counter > 100) - // { - // addEvent(events, // MidiBuffer - // TTL, // eventType - // 0, // sampleNum - // 1, // eventID - // 0 // eventChannel - // ); - // counter = 0; - // } else { - // counter++; - - // } - - - - int samplesNeeded = (int) float(buffer.getNumSamples()) * (getDefaultSampleRate()/44100.0f); - - int samplesReaded = 0; + int samplesRead = 0; - while (samplesReaded < samplesNeeded) + while (samplesRead < samplesNeeded) { - int samplesToRead = samplesNeeded - samplesReaded; + int samplesToRead = samplesNeeded - samplesRead; if ((currentSample + samplesToRead) > stopSample) { samplesToRead = stopSample - currentSample; if (samplesToRead > 0) - input->readData(readBuffer+samplesReaded,samplesToRead); + input->readData(readBuffer+samplesRead,samplesToRead); input->seekTo(startSample); currentSample = startSample; } else { - input->readData(readBuffer+samplesReaded,samplesToRead); + input->readData(readBuffer+samplesRead,samplesToRead); currentSample += samplesToRead; } - samplesReaded += samplesToRead; + samplesRead += samplesToRead; } for (int i=0; i < currentNumChannels; i++) { @@ -233,8 +210,34 @@ void FileReader::process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSa } timestamp += samplesNeeded; - static_cast<FileReaderEditor*>(getEditor())->setCurrentTime(samplesToMilliseconds(currentSample)); - nSamples = samplesNeeded; + setNumSamples(events, samplesNeeded); + + // code for testing events: + if (counter == 100) + { + std::cout << "Adding on event for node id: " << nodeId << std::endl; + addEvent(events, // MidiBuffer + TTL, // eventType + 0, // sampleNum + 1, // eventID + 1 // eventChannel + ); + + counter++; + } else if (counter > 120) + { + std::cout << "Adding off event!" << std::endl; + addEvent(events, // MidiBuffer + TTL, // eventType + 0, // sampleNum + 0, // eventID + 1 // eventChannel + ); + + counter = 0; + } else { + counter++; + } } diff --git a/Source/Processors/FileReader/FileReader.h b/Source/Processors/FileReader/FileReader.h index ffd54c21206bd499009ad97ba9a7db668b5fc652..369a92ab46c02749fd556db03fcb0b35c400ff0c 100644 --- a/Source/Processors/FileReader/FileReader.h +++ b/Source/Processors/FileReader/FileReader.h @@ -49,7 +49,7 @@ public: FileReader(); ~FileReader(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); AudioProcessorEditor* createEditor(); @@ -71,8 +71,9 @@ public: void enabledState(bool t); float getDefaultSampleRate(); - int getDefaultNumOutputs(); - float getBitVolts(int chan); + int getNumHeadstageOutputs(); + int getNumEventChannels(); + float getBitVolts(Channel* chan); bool setFile(String fullpath); String getFile(); @@ -90,6 +91,8 @@ private: int64 currentSample; + int counter; // for testing purposes only + ScopedPointer<FileSource> input; HeapBlock<int16> readBuffer; diff --git a/Source/Processors/FilterNode/FilterNode.cpp b/Source/Processors/FilterNode/FilterNode.cpp index 04b92d3c607a4e16961349d47ff37e46424f0734..9d2716b701c0453d6f6c786778635789625eb2a5 100755 --- a/Source/Processors/FilterNode/FilterNode.cpp +++ b/Source/Processors/FilterNode/FilterNode.cpp @@ -207,7 +207,7 @@ void FilterNode::setFilterParameters(double lowCut, double highCut, int chan) { Dsp::Params params; - params[0] = getSampleRate(); // sample rate + params[0] = channels[chan]->sampleRate; // sample rate params[1] = 2; // order params[2] = (highCut + lowCut)/2; // center frequency params[3] = highCut - lowCut; // bandwidth @@ -261,8 +261,7 @@ void FilterNode::setParameter(int parameterIndex, float newValue) } void FilterNode::process(AudioSampleBuffer& buffer, - MidiBuffer& midiMessages, - int& nSamples) + MidiBuffer& midiMessages) { for (int n = 0; n < getNumOutputs(); n++) @@ -270,7 +269,7 @@ void FilterNode::process(AudioSampleBuffer& buffer, if (shouldFilterChannel[n]) { float* ptr = buffer.getWritePointer(n); - filters[n]->process(nSamples, &ptr); + filters[n]->process(getNumSamples(n), &ptr); } } diff --git a/Source/Processors/FilterNode/FilterNode.h b/Source/Processors/FilterNode/FilterNode.h index 4a0b9886f5ccbd55caae574b493aa6ca59defff2..c026537acc60c8286b38173380e0cd4d5125754e 100755 --- a/Source/Processors/FilterNode/FilterNode.h +++ b/Source/Processors/FilterNode/FilterNode.h @@ -46,7 +46,7 @@ public: FilterNode(); ~FilterNode(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); AudioProcessorEditor* createEditor(); diff --git a/Source/Processors/GenericProcessor/GenericProcessor.cpp b/Source/Processors/GenericProcessor/GenericProcessor.cpp index 8cd369d65f30890b92a7edae0600f331e641ea1c..dd148c568c03065f7fff7224e4b8a81cf0671c61 100755 --- a/Source/Processors/GenericProcessor/GenericProcessor.cpp +++ b/Source/Processors/GenericProcessor/GenericProcessor.cpp @@ -24,10 +24,12 @@ #include "GenericProcessor.h" #include "../../UI/UIComponent.h" +#include <exception> + GenericProcessor::GenericProcessor(const String& name_) : AccessClass(), sourceNode(0), destNode(0), isEnabled(true), wasConnected(false), nextAvailableChannel(0), saveOrder(-1), loadOrder(-1), currentChannel(-1), - editor(0), parametersAsXml(nullptr), sendSampleCount(true), name(name_), paramsWereLoaded(false) + editor(0), parametersAsXml(nullptr), sendSampleCount(true), name(name_), paramsWereLoaded(false) { settings.numInputs = settings.numOutputs = settings.sampleRate = 0; @@ -303,16 +305,21 @@ void GenericProcessor::update() std::cout << getName() << " updating settings." << std::endl; // SO patched here to keep original channel names + // save original channel names int oldNumChannels = channels.size(); + StringArray oldNames; + for (int k = 0; k < oldNumChannels; k++) { oldNames.add(channels[k]->getName()); } + // ---- RESET EVERYTHING ---- /// clearSettings(); - if (sourceNode != 0) + + if (sourceNode != 0) // copy settings from source node { // everything is inherited except numOutputs settings = sourceNode->settings; @@ -324,8 +331,7 @@ void GenericProcessor::update() Channel* sourceChan = sourceNode->channels[i]; Channel* ch = new Channel(*sourceChan); ch->setProcessor(this); - ch->bitVolts = ch->bitVolts*getBitVolts(i); - ch->num = i; + ch->nodeIndex = i; if (i < recordStatus.size()) { @@ -340,63 +346,96 @@ void GenericProcessor::update() { Channel* sourceChan = sourceNode->eventChannels[i]; Channel* ch = new Channel(*sourceChan); - ch->sampleRate = getDefaultSampleRate(); - ch->bitVolts = getDefaultBitVolts(); + ch->setProcessor(this); eventChannels.add(ch); } } - else + else // generate new settings { - settings.numOutputs = getDefaultNumOutputs(); settings.sampleRate = getDefaultSampleRate(); + settings.numOutputs = getNumHeadstageOutputs() + getNumAdcOutputs() + getNumAuxOutputs(); - int numChan = getNumOutputs(); - int numADC_Chan = getDefaultADCoutputs(); - - Array<channelType> types; - Array<int> stream, orig; - Array<float> gains; - StringArray names; - getChannelsInfo(names, types, stream, orig, gains); + std::cout << getName() << " setting num outputs to " << settings.numOutputs << std::endl; + int nidx = 0; - for (int i = 0; i < numChan; i++) + for (int i = 0; i < getNumHeadstageOutputs(); i++) { - Channel* ch = new Channel(this, i); + Channel* ch = new Channel(this, i+1, HEADSTAGE_CHANNEL); + ch->setProcessor(this); + ch->sampleRate = getDefaultSampleRate(); + ch->bitVolts = getBitVolts(ch); + ch->sourceNodeId = nodeId; + ch->nodeIndex = nidx; - // if (i < oldNumChannels) - // ch->setName(oldNames[i]); - //else if (i >= numChan-numADC_Chan) - // ch->setName("ADC"+String(1+i-(numChan-numADC_Chan))); + if (i < recordStatus.size()) + { + ch->setRecordState(recordStatus[i]); + } + else + { + if (isSource()) + ch->setRecordState(true); + } - if (i >= numChan-numADC_Chan) - ch->setName("ADC" + String(1+i-(numChan-numADC_Chan))); + channels.add(ch); + nidx++; + } - if (i >= numChan-numADC_Chan) - ch->setType(ADC_CHANNEL); + for (int j = 0; j < getNumAuxOutputs(); j++) + { + Channel* ch = new Channel(this, j+1, AUX_CHANNEL); + ch->setProcessor(this); + ch->sampleRate = getDefaultSampleRate(); + ch->bitVolts = getBitVolts(ch); + ch->sourceNodeId = nodeId; + ch->nodeIndex = nidx; + + if (j < recordStatus.size()) + { + ch->setRecordState(recordStatus[j]); + } + else + { + if (isSource()) + ch->setRecordState(true); + } - if (i < stream.size()) - { - ch->originalStream = stream[i]; - ch->originalChannel = orig[i]; - } + channels.add(ch); + nidx++; + } + + for (int k = 0; k < getNumAdcOutputs(); k++) + { + Channel* ch = new Channel(this, k+1, ADC_CHANNEL); + ch->setProcessor(this); ch->sampleRate = getDefaultSampleRate(); + ch->bitVolts = getBitVolts(ch); + ch->sourceNodeId = nodeId; + ch->nodeIndex = nidx; - // if (ch->isADCchannel) - ch->bitVolts = getDefaultBitVolts(); - // else - // ch->bitVolts = getDefaultAdcBitVolts(); // should implement this + if (k < recordStatus.size()) + { - if (i < recordStatus.size()) + ch->setRecordState(recordStatus[k]); + } + else { - ch->setRecordState(recordStatus[i]); - ch->isMonitored = monitorStatus[i]; - } else { - if (this->isSource()) + if (isSource()) ch->setRecordState(true); } channels.add(ch); + nidx++; + } + + for (int m = 0; m < getNumEventChannels(); m++) + { + Channel* ch = new Channel(this, m+1, EVENT_CHANNEL); + ch->sourceNodeId = nodeId; + ch->nodeIndex = nidx; + eventChannels.add(ch); + ch->sampleRate = getDefaultSampleRate(); } } @@ -406,7 +445,7 @@ void GenericProcessor::update() settings.numOutputs = 0; } - updateSettings(); // custom settings code + updateSettings(); // allow processors to change custom settings // required for the ProcessorGraph to know the // details of this processor: @@ -415,16 +454,16 @@ void GenericProcessor::update() 44100.0, // sampleRate 128); // blockSize - editor->update(); // update editor settings + editor->update(); // allow the editor to update its settings } void GenericProcessor::setAllChannelsToRecord() { - recordStatus.resize(getDefaultNumOutputs()); + recordStatus.resize(channels.size()); - for (int i = 0; i < getDefaultNumOutputs(); i++) + for (int i = 0; i < channels.size(); i++) { recordStatus.set(i,true); } @@ -435,19 +474,19 @@ void GenericProcessor::setAllChannelsToRecord() void GenericProcessor::setRecording(bool state) { - GenericEditor* ed = getEditor(); - if (state) - { - if (ed != 0) - ed->startRecording(); - startRecording(); - } - else - { - if (ed != 0) - ed->stopRecording(); - stopRecording(); - } + GenericEditor* ed = getEditor(); + if (state) + { + if (ed != 0) + ed->startRecording(); + startRecording(); + } + else + { + if (ed != 0) + ed->stopRecording(); + stopRecording(); + } } void GenericProcessor::enableEditor() @@ -469,7 +508,105 @@ void GenericProcessor::disableEditor() ed->stopAcquisition(); } -int GenericProcessor::getNumSamples(MidiBuffer& events) +/** Used to get the number of samples in a given buffer, for a given channel. */ +int GenericProcessor::getNumSamples(int channelNum) +{ + int sourceNodeId, nSamples; + + if (channelNum >= 0 && channelNum < channels.size()) + sourceNodeId = channels[channelNum]->sourceNodeId; + else + return 0; + + // std::cout << "Requesting samples for channel " << channelNum << " with source node " << sourceNodeId << std::endl; + + try + { + nSamples = numSamples.at(sourceNodeId); + } + catch (std::exception& e) + { + return 0; + } + + //std::cout << nSamples << " were found." << std::endl; + + return nSamples; +} + + +/** Used to get the number of samples in a given buffer, for a given source node. */ +void GenericProcessor::setNumSamples(MidiBuffer& events, int sampleIndex) +{ + + // This amounts to adding a "buffer size" flag at a particular sample number, + // and a new flag is added each time "setNumSamples" is called. + // Thus, if the number of samples changes somewhere in the processing pipeline, + // the old sample number will remain. This is a problem if the number of + // samples gets smaller. + // If we allow the sample rate to change (e.g., with a resampling node), + // this code will have to be updated. The easiest approach will be for each + // processor to ignore any buffer size events that don't come from its + // immediate source. + // + + uint8 data[4]; + + int16 si = (int16) sampleIndex; + + data[0] = BUFFER_SIZE; // most-significant byte + data[1] = nodeId; // least-significant byte + memcpy(data+2, &si, 2); + + events.addEvent(data, // spike data + 4, // total bytes + 0); // sample index +} + +/** Used to get the timestamp for a given buffer, for a given source node. */ +int64 GenericProcessor::getTimestamp(int channelNum) +{ + int sourceNodeId; + int64 ts; + + if (channelNum >= 0 && channelNum < channels.size()) + sourceNodeId = channels[channelNum]->sourceNodeId; + else + return 0; + + try + { + ts = timestamps.at(sourceNodeId); + } + catch (std::exception& e) + { + return 0; + } + + return ts; +} + +/** Used to set the timestamp for a given buffer, for a given channel. */ +void GenericProcessor::setTimestamp(MidiBuffer& events, int64 timestamp) +{ + + //std::cout << "Setting timestamp to " << timestamp << std:;endl; + + uint8 data[8]; + memcpy(data, ×tamp, 8); + + // generate timestamp + addEvent(events, // MidiBuffer + TIMESTAMP, // eventType + 0, // sampleNum + nodeId, // eventID + 0, // eventChannel + 8, // numBytes + data // data + ); +} + +int GenericProcessor::processEventBuffer(MidiBuffer& events) { // // This loops through all events in the buffer, and uses the BUFFER_SIZE @@ -508,54 +645,49 @@ int GenericProcessor::getNumSamples(MidiBuffer& events) numRead = nr; + uint8 sourceNodeId; + memcpy(&sourceNodeId, dataptr + 1, 1); + + numSamples[sourceNodeId] = numRead; + + //if (nodeId < 900) + // std::cout << nodeId << " got " << numRead << " samples for " << (int) sourceNodeId << std::endl; + + + } + else if (*dataptr == TIMESTAMP) + { + int64 ts; + memcpy(&ts, dataptr+4, 8); + + uint8 sourceNodeId; + memcpy(&sourceNodeId, dataptr + 1, 1); + + timestamps[sourceNodeId] = ts; + + //if (nodeId < 900) + // std::cout << nodeId << " got " << ts << " timestamp for " << (int) sourceNodeId << std::endl; + } else + { if (*dataptr == TTL && // a TTL event getNodeId() < 900 && // not handled by a specialized processor (e.g. AudioNode)) - *(dataptr+1) > 0) // that's flagged for saving + *(dataptr+4) > 0) // that's flagged for saving { // changing the const cast is dangerous, but probably necessary: uint8* ptr = const_cast<uint8*>(dataptr); - *(ptr + 1) = 0; // set second byte of raw data to 0, so the event - // won't be saved twice + *(ptr + 4) = 0; // set fifth byte of raw data to 0, so the event + // won't be saved twice } + } } } return numRead; } -void GenericProcessor::setNumSamples(MidiBuffer& events, int sampleIndex) -{ - // - // This amounts to adding a "buffer size" flag at a particular sample number, - // and a new flag is added each time "setNumSamples" is called. - // Thus, if the number of samples changes somewhere in the processing pipeline, - // the old sample number will remain. This is a problem if the number of - // samples gets smaller. - // If we allow the sample rate to change (e.g., with a resampling node), - // this code will have to be updated. The easiest approach will be for each - // processor to ignore any buffer size events that don't come from its - // immediate source. - // - - uint8 data[4]; - - int16 si = (int16) sampleIndex; - - data[0] = BUFFER_SIZE; // most-significant byte - data[1] = nodeId; // least-significant byte - memcpy(data+2, &si, 2); - - events.addEvent(data, // spike data - 4, // total bytes - 0); // sample index - - // std::cout << "Processor " << getNodeId() << " adding a new sample count of " << sampleIndex << std::endl; - -} - int GenericProcessor::checkForEvents(MidiBuffer& midiMessages) { @@ -595,16 +727,19 @@ void GenericProcessor::addEvent(MidiBuffer& eventBuffer, uint8 numBytes, uint8* eventData) { - uint8* data = new uint8[4+numBytes]; + uint8* data = new uint8[5+numBytes]; data[0] = type; // event type data[1] = nodeId; // processor ID automatically added - data[2] = eventId; // event ID + data[2] = eventId; // event ID (1 = on, 0 = off, usually) data[3] = eventChannel; // event channel - memcpy(data + 4, eventData, numBytes); + data[4] = 1; // saving flag + memcpy(data + 5, eventData, numBytes); + + //std::cout << "Node id: " << data[1] << std::endl; eventBuffer.addEvent(data, // raw data - 4 + numBytes, // total bytes + 5 + numBytes, // total bytes sampleNum); // sample index //if (type == TTL) @@ -622,14 +757,10 @@ void GenericProcessor::addEvent(MidiBuffer& eventBuffer, void GenericProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer) { - int nSamples = getNumSamples(eventBuffer); // finds buffer size and sets save - // flag on all TTL events to zero - - process(buffer, eventBuffer, nSamples); + processEventBuffer(eventBuffer); // extract buffer sizes and timestamps, + // set flag on all TTL events to zero - if (sendSampleCount) - setNumSamples(eventBuffer, nSamples); // adds it back, - // even if it's unchanged + process(buffer, eventBuffer); } diff --git a/Source/Processors/GenericProcessor/GenericProcessor.h b/Source/Processors/GenericProcessor/GenericProcessor.h index 8c3f2719fbd03a5e2f6852dd64a8ec86e542839e..ce62e607d0a5d2bc61302b92b4dc26397994ba5d 100755 --- a/Source/Processors/GenericProcessor/GenericProcessor.h +++ b/Source/Processors/GenericProcessor/GenericProcessor.h @@ -24,8 +24,9 @@ #ifndef __GENERICPROCESSOR_H_1F469DAF__ #define __GENERICPROCESSOR_H_1F469DAF__ -enum channelType {DATA_CHANNEL = 0, AUX_CHANNEL = 1, ADC_CHANNEL = 2, EVENT_CHANNEL = 3}; - +enum ChannelType {HEADSTAGE_CHANNEL = 0, AUX_CHANNEL = 1, ADC_CHANNEL = 2, EVENT_CHANNEL = 3, + SINGLE_ELECTRODE = 4, STEREOTRODE = 5, TETRODE = 6 + }; #include "../../../JuceLibraryCode/JuceHeader.h" #include "../Editors/GenericEditor.h" @@ -35,6 +36,7 @@ enum channelType {DATA_CHANNEL = 0, AUX_CHANNEL = 1, ADC_CHANNEL = 2, EVENT_CHAN #include <time.h> #include <stdio.h> +#include <map> class EditorViewport; class DataViewport; @@ -60,7 +62,6 @@ class Channel; */ - class GenericProcessor : public AudioProcessor, public AccessClass @@ -137,23 +138,23 @@ public: { return GenericProcessor::unusedNameString; } - + /** returns the names and types of all data, aux and adc channels */ - virtual void getChannelsInfo(StringArray &Names, Array<channelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains) + virtual void getChannelsInfo(StringArray& Names, Array<ChannelType>& type, Array<int>& stream, Array<int>& originalChannelNumber, Array<float>& gains) { } - virtual int modifyChannelName(channelType t, int stream, int ch, String newName, bool updateSignalChain) + virtual int modifyChannelName(ChannelType t, int stream, int ch, String newName, bool updateSignalChain) { return -1; } - virtual int modifyChannelGain(channelType t, int stream, int ch, float newGain, bool updateSignalChain) + virtual int modifyChannelGain(ChannelType t, int stream, int ch, float newGain, bool updateSignalChain) { return -1; } - virtual void getEventChannelNames(StringArray &Names) + virtual void getEventChannelNames(StringArray& Names) { } @@ -260,8 +261,7 @@ public: the number of samples in the current buffer. */ virtual void process(AudioSampleBuffer& continuousBuffer, - MidiBuffer& eventBuffer, - int& nSamples) = 0; + MidiBuffer& eventBuffer) = 0; /** Pointer to a processor's immediate source node.*/ GenericProcessor* sourceNode; @@ -293,13 +293,26 @@ public: return settings.numOutputs; } - /** Returns the default number of outputs, in case a processor has no source (or is itself a source).*/ - virtual int getDefaultNumOutputs() + /** Returns the default number of headstage (neural data) outputs, in case a processor has no source (or is itself a source).*/ + virtual int getNumHeadstageOutputs() { return 2; } - virtual int getDefaultADCoutputs() + /** Returns the default number of ADC (typically 0-5V, or -5 to +5V) outputs. */ + virtual int getNumAdcOutputs() + { + return 0; + } + + /** Returns the default number of auxiliary (e.g. accelerometer) outputs. */ + virtual int getNumAuxOutputs() + { + return 0; + } + + /** Returns the default number of event channels. */ + virtual int getNumEventChannels() { return 0; } @@ -310,11 +323,11 @@ public: return 1.0; } - /** Returns the bit volts for a given channel **/ - virtual float getBitVolts(int chan) - { - return 1.0; - } + /** Returns the bit volts for a given channel **/ + virtual float getBitVolts(Channel* chan) + { + return 1.0; + } /** Returns the next available channel (and increments the channel if the input is set to 'true'. */ @@ -394,7 +407,7 @@ public: { return false; } - + /** Returns true if a processor is a utility (non-merger or splitter), false otherwise.*/ virtual bool isUtility() { @@ -428,9 +441,9 @@ public: return true; } - /** Called when recording starts/stops **/ - void setRecording(bool state); - + /** Called when recording starts/stops **/ + void setRecording(bool state); + /** Called from setRecording whenever recording has started. */ virtual void startRecording() { } @@ -513,14 +526,6 @@ public: MESSAGE = 10 }; - enum eventChannelTypes - { - GENERIC_EVENT = 100, - SINGLE_ELECTRODE = 1, - STEREOTRODE = 2, - TETRODE = 4 - }; - /** Variable used to orchestrate saving the ProcessorGraph. */ int saveOrder; @@ -617,7 +622,10 @@ public: virtual void loadCustomChannelParametersFromXml(XmlElement* channelElement, bool isEventChannel=false); /** handle messages from other processors */ - virtual String interProcessorCommunication(String command) { return String("OK"); }; + virtual String interProcessorCommunication(String command) + { + return String("OK"); + }; /** Holds loaded parameters */ XmlElement* parametersAsXml; @@ -625,6 +633,21 @@ public: /** When set to false, this disables the sending of sample counts through the event buffer. */ bool sendSampleCount; + /** Used to get the number of samples in a given buffer, for a given channel. */ + int getNumSamples(int channelNumber); + + /** Used to get the number of samples in a given buffer, for a given source node. */ + void setNumSamples(MidiBuffer&, int numSamples); + + /** Used to get the timestamp for a given buffer, for a given channel. */ + int64 getTimestamp(int channelNumber); + + /** Used to set the timestamp for a given buffer, for a given source node. */ + void setTimestamp(MidiBuffer&, int64 timestamp); + + std::map<uint8, int> numSamples; + std::map<uint8, int64> timestamps; + private: /** Automatically extracts the number of samples in the buffer, then @@ -638,13 +661,8 @@ private: Array<bool> recordStatus; Array<bool> monitorStatus; - /** Returns the number of samples for the current continuous buffer (assumed to be - the same for all channels).*/ - int getNumSamples(MidiBuffer&); - - /** Updates the number of samples for the current continuous buffer (assumed to be - the same for all channels).*/ - void setNumSamples(MidiBuffer&, int); + /** Extracts sample counts and timestamps from the MidiBuffer. */ + int processEventBuffer(MidiBuffer&); /** For getInputChannelName() and getOutputChannelName() */ static const String unusedNameString; diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.cpp b/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.cpp index 712a71987ba6d891e55f358cded0baeeec0dcb19..d6337a50b611d901f0f1a1a988e94f543fea3c45 100755 --- a/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.cpp +++ b/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.cpp @@ -26,13 +26,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <math.h> LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : - screenBufferIndex(0), timebase(1.0f), displayGain(1.0f), timeOffset(0.0f), - processor(processor_), selectedChannelType(DATA_CHANNEL), - displayBufferIndex(0) + timebase(1.0f), displayGain(1.0f), timeOffset(0.0f), + processor(processor_), selectedChannelType(HEADSTAGE_CHANNEL) { nChans = processor->getNumInputs(); - sampleRate = processor->getSampleRate(); std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl; displayBuffer = processor->getDisplayBufferAddress(); @@ -64,40 +62,39 @@ LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : //viewport->getVerticalScrollBar()->addListener(this->scrollBarMoved(viewport->getVerticalScrollBar(), 1.0)); - + UtilityButton* tbut; addAndMakeVisible(viewport); addAndMakeVisible(timescale); - UtilityButton* tbut; - //Ranges for neural data - voltageRanges[DATA_CHANNEL].add("25"); - voltageRanges[DATA_CHANNEL].add("50"); - voltageRanges[DATA_CHANNEL].add("100"); - voltageRanges[DATA_CHANNEL].add("250"); - voltageRanges[DATA_CHANNEL].add("400"); - voltageRanges[DATA_CHANNEL].add("500"); - voltageRanges[DATA_CHANNEL].add("750"); - voltageRanges[DATA_CHANNEL].add("1000"); - voltageRanges[DATA_CHANNEL].add("2000"); - voltageRanges[DATA_CHANNEL].add("5000"); - voltageRanges[DATA_CHANNEL].add("10000"); - selectedVoltageRange[DATA_CHANNEL] = 8; - rangeGain[DATA_CHANNEL] = 1; //uV - rangeSteps[DATA_CHANNEL] = 10; - rangeUnits.add("uV"); - typeNames.add("DATA"); - tbut = new UtilityButton("DATA",Font("Small Text", 9, Font::plain)); - tbut->setEnabledState(true); - tbut->setCorners(false,false,false,false); - tbut->addListener(this); - tbut->setClickingTogglesState(true); - tbut->setRadioGroupId(100,dontSendNotification); - tbut->setToggleState(true,dontSendNotification); - addAndMakeVisible(tbut); - typeButtons.add(tbut); - + voltageRanges[HEADSTAGE_CHANNEL].add("25"); + voltageRanges[HEADSTAGE_CHANNEL].add("50"); + voltageRanges[HEADSTAGE_CHANNEL].add("100"); + voltageRanges[HEADSTAGE_CHANNEL].add("250"); + voltageRanges[HEADSTAGE_CHANNEL].add("400"); + voltageRanges[HEADSTAGE_CHANNEL].add("500"); + voltageRanges[HEADSTAGE_CHANNEL].add("750"); + voltageRanges[HEADSTAGE_CHANNEL].add("1000"); + voltageRanges[HEADSTAGE_CHANNEL].add("2000"); + voltageRanges[HEADSTAGE_CHANNEL].add("5000"); + voltageRanges[HEADSTAGE_CHANNEL].add("10000"); + selectedVoltageRange[HEADSTAGE_CHANNEL] = 8; + rangeGain[HEADSTAGE_CHANNEL] = 1; //uV + rangeSteps[HEADSTAGE_CHANNEL] = 10; + rangeUnits.add("uV"); + typeNames.add("DATA"); + + tbut = new UtilityButton("DATA",Font("Small Text", 9, Font::plain)); + tbut->setEnabledState(true); + tbut->setCorners(false,false,false,false); + tbut->addListener(this); + tbut->setClickingTogglesState(true); + tbut->setRadioGroupId(100,dontSendNotification); + tbut->setToggleState(true,dontSendNotification); + addAndMakeVisible(tbut); + typeButtons.add(tbut); + //Ranges for AUX/accelerometer data voltageRanges[AUX_CHANNEL].add("25"); @@ -110,20 +107,21 @@ LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : voltageRanges[AUX_CHANNEL].add("1000"); voltageRanges[AUX_CHANNEL].add("2000"); voltageRanges[AUX_CHANNEL].add("5000"); - selectedVoltageRange[AUX_CHANNEL] = 6; - rangeGain[AUX_CHANNEL] = 1; //uV - rangeSteps[AUX_CHANNEL] = 10; - rangeUnits.add("uV"); - typeNames.add("AUX"); - tbut = new UtilityButton("AUX",Font("Small Text", 9, Font::plain)); - tbut->setEnabledState(true); - tbut->setCorners(false,false,false,false); - tbut->addListener(this); - tbut->setClickingTogglesState(true); - tbut->setRadioGroupId(100,dontSendNotification); - tbut->setToggleState(false,dontSendNotification); - addAndMakeVisible(tbut); - typeButtons.add(tbut); + selectedVoltageRange[AUX_CHANNEL] = 6; + rangeGain[AUX_CHANNEL] = 1; //uV + rangeSteps[AUX_CHANNEL] = 10; + rangeUnits.add("uV"); + typeNames.add("AUX"); + + tbut = new UtilityButton("AUX",Font("Small Text", 9, Font::plain)); + tbut->setEnabledState(true); + tbut->setCorners(false,false,false,false); + tbut->addListener(this); + tbut->setClickingTogglesState(true); + tbut->setRadioGroupId(100,dontSendNotification); + tbut->setToggleState(false,dontSendNotification); + addAndMakeVisible(tbut); + typeButtons.add(tbut); //Ranges for ADC data voltageRanges[ADC_CHANNEL].add("0.01"); @@ -132,28 +130,29 @@ LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : voltageRanges[ADC_CHANNEL].add("0.5"); voltageRanges[ADC_CHANNEL].add("1.0"); voltageRanges[ADC_CHANNEL].add("2.0"); - voltageRanges[ADC_CHANNEL].add("5.0"); - voltageRanges[ADC_CHANNEL].add("10.0"); - selectedVoltageRange[ADC_CHANNEL] = 8; - rangeGain[ADC_CHANNEL] = 1; //V - rangeSteps[ADC_CHANNEL] = 0.1; //in V - rangeUnits.add("V"); - typeNames.add("ADC"); - tbut = new UtilityButton("ADC",Font("Small Text", 9, Font::plain)); - tbut->setEnabledState(true); - tbut->setCorners(false,false,false,false); - tbut->addListener(this); - tbut->setClickingTogglesState(true); - tbut->setRadioGroupId(100,dontSendNotification); - tbut->setToggleState(false,dontSendNotification); - addAndMakeVisible(tbut); - typeButtons.add(tbut); - - selectedVoltageRangeValues[DATA_CHANNEL] = voltageRanges[DATA_CHANNEL][selectedVoltageRange[DATA_CHANNEL]-1]; - selectedVoltageRangeValues[AUX_CHANNEL] = voltageRanges[AUX_CHANNEL][selectedVoltageRange[AUX_CHANNEL]-1]; - selectedVoltageRangeValues[ADC_CHANNEL] = voltageRanges[ADC_CHANNEL][selectedVoltageRange[ADC_CHANNEL]-1]; - - timebases.add("0.25"); + voltageRanges[ADC_CHANNEL].add("5.0"); + voltageRanges[ADC_CHANNEL].add("10.0"); + selectedVoltageRange[ADC_CHANNEL] = 8; + rangeGain[ADC_CHANNEL] = 1; //V + rangeSteps[ADC_CHANNEL] = 0.1; //in V + rangeUnits.add("V"); + typeNames.add("ADC"); + + tbut = new UtilityButton("ADC",Font("Small Text", 9, Font::plain)); + tbut->setEnabledState(true); + tbut->setCorners(false,false,false,false); + tbut->addListener(this); + tbut->setClickingTogglesState(true); + tbut->setRadioGroupId(100,dontSendNotification); + tbut->setToggleState(false,dontSendNotification); + addAndMakeVisible(tbut); + typeButtons.add(tbut); + + selectedVoltageRangeValues[HEADSTAGE_CHANNEL] = voltageRanges[HEADSTAGE_CHANNEL][selectedVoltageRange[HEADSTAGE_CHANNEL]-1]; + selectedVoltageRangeValues[AUX_CHANNEL] = voltageRanges[AUX_CHANNEL][selectedVoltageRange[AUX_CHANNEL]-1]; + selectedVoltageRangeValues[ADC_CHANNEL] = voltageRanges[ADC_CHANNEL][selectedVoltageRange[ADC_CHANNEL]-1]; + + timebases.add("0.25"); timebases.add("0.5"); timebases.add("1.0"); timebases.add("2.0"); @@ -162,8 +161,8 @@ LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : timebases.add("5.0"); timebases.add("10.0"); timebases.add("20.0"); - selectedTimebase = 4; - selectedTimebaseValue = timebases[selectedTimebase-1]; + selectedTimebase = 4; + selectedTimebaseValue = timebases[selectedTimebase-1]; spreads.add("10"); spreads.add("20"); @@ -175,8 +174,8 @@ LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : spreads.add("80"); spreads.add("90"); spreads.add("100"); - selectedSpread = 5; - selectedSpreadValue = spreads[selectedSpread-1]; + selectedSpread = 5; + selectedSpreadValue = spreads[selectedSpread-1]; colorGroupings.add("1"); colorGroupings.add("2"); @@ -186,26 +185,26 @@ LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : rangeSelection = new ComboBox("Voltage range"); - rangeSelection->addItemList(voltageRanges[DATA_CHANNEL], 1); - rangeSelection->setSelectedId(selectedVoltageRange[DATA_CHANNEL], sendNotification); - rangeSelection->setEditableText(true); + rangeSelection->addItemList(voltageRanges[HEADSTAGE_CHANNEL], 1); + rangeSelection->setSelectedId(selectedVoltageRange[HEADSTAGE_CHANNEL], sendNotification); + rangeSelection->setEditableText(true); rangeSelection->addListener(this); addAndMakeVisible(rangeSelection); timebaseSelection = new ComboBox("Timebase"); timebaseSelection->addItemList(timebases, 1); - timebaseSelection->setSelectedId(selectedTimebase, sendNotification); - timebaseSelection->setEditableText(true); + timebaseSelection->setSelectedId(selectedTimebase, sendNotification); + timebaseSelection->setEditableText(true); timebaseSelection->addListener(this); addAndMakeVisible(timebaseSelection); spreadSelection = new ComboBox("Spread"); spreadSelection->addItemList(spreads, 1); - spreadSelection->setSelectedId(selectedSpread,sendNotification); + spreadSelection->setSelectedId(selectedSpread,sendNotification); spreadSelection->addListener(this); - spreadSelection->setEditableText(true); + spreadSelection->setEditableText(true); addAndMakeVisible(spreadSelection); colorGroupingSelection = new ComboBox("Color Grouping"); @@ -245,8 +244,8 @@ LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : lfpDisplay->setNumChannels(nChans); - lfpDisplay->setRange(voltageRanges[DATA_CHANNEL][selectedVoltageRange[DATA_CHANNEL]-1].getFloatValue()*rangeGain[DATA_CHANNEL] - ,DATA_CHANNEL); + lfpDisplay->setRange(voltageRanges[HEADSTAGE_CHANNEL][selectedVoltageRange[HEADSTAGE_CHANNEL]-1].getFloatValue()*rangeGain[HEADSTAGE_CHANNEL] + ,HEADSTAGE_CHANNEL); // add event display-specific controls (currently just an enable/disable button) for (int i = 0; i < 8; i++) @@ -302,12 +301,11 @@ void LfpDisplayCanvas::resized() eventDisplayInterfaces[i]->repaint(); } - int bh = 25/typeButtons.size(); - for (int i = 0; i < typeButtons.size(); i++) - { - typeButtons[i]->setBounds(110,getHeight()-30+i*bh,50,bh); - } - + int bh = 25/typeButtons.size(); + for (int i = 0; i < typeButtons.size(); i++) + { + typeButtons[i]->setBounds(110,getHeight()-30+i*bh,50,bh); + } // std::cout << "Canvas thinks LfpDisplay should be this high: " // << lfpDisplay->getTotalHeight() << std::endl; @@ -319,7 +317,10 @@ void LfpDisplayCanvas::beginAnimation() displayBufferSize = displayBuffer->getNumSamples(); - screenBufferIndex = 0; + for (int i = 0; i < screenBufferIndex.size(); i++) + { + screenBufferIndex.set(i,0); + } startCallbacks(); } @@ -334,18 +335,33 @@ void LfpDisplayCanvas::endAnimation() void LfpDisplayCanvas::update() { nChans = jmax(processor->getNumInputs(),1); - sampleRate = processor->getSampleRate(); - std::cout << "Setting sample rate of LfpDisplayCanvas to " << sampleRate << std::endl; + sampleRate.clear(); + screenBufferIndex.clear(); + lastScreenBufferIndex.clear(); + displayBufferIndex.clear(); - if (nChans != lfpDisplay->getNumChannels()) + for (int i = 0; i <= nChans; i++) // extra channel for events { - std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl; + if (i < nChans) + sampleRate.add(processor->channels[i]->sampleRate); + else + sampleRate.add(processor->channels[i-1]->sampleRate); // for event channel (IT'S A HACK -- BE CAREFUL!) + + // std::cout << "Sample rate for ch " << i << " = " << sampleRate[i] << std::endl; + displayBufferIndex.add(0); + screenBufferIndex.add(0); + lastScreenBufferIndex.add(0); + } - lfpDisplay->setNumChannels(nChans); + if (nChans != lfpDisplay->getNumChannels()) + { + //std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl; refreshScreenBuffer(); + lfpDisplay->setNumChannels(nChans); // add an extra channel for events + // update channel names for (int i = 0; i < processor->getNumInputs(); i++) { @@ -363,15 +379,15 @@ void LfpDisplayCanvas::update() resized(); } - else - { - for (int i = 0; i < processor->getNumInputs(); i++) + else + { + for (int i = 0; i < processor->getNumInputs(); i++) { - lfpDisplay->channels[i]->updateType(); - lfpDisplay->channelInfo[i]->updateType(); - } - - } + lfpDisplay->channels[i]->updateType(); + lfpDisplay->channelInfo[i]->updateType(); + } + + } } @@ -380,31 +396,32 @@ void LfpDisplayCanvas::buttonClicked(Button* b) if (b == invertInputButton) { lfpDisplay->setInputInverted(b->getToggleState()); - return; + return; } if (b == drawMethodButton) { lfpDisplay->setDrawMethod(b->getToggleState()); - return; + return; } if (b == pauseButton) { lfpDisplay->isPaused = b->getToggleState(); - return; + return; + } + + int idx = typeButtons.indexOf((UtilityButton*)b); + if ((idx >= 0) && (b->getToggleState())) + { + for (int i = 0; i < processor->getNumInputs(); i++) + { + if (lfpDisplay->channels[i]->getSelected()) + { + lfpDisplay->channels[i]->deselect(); + lfpDisplay->channels[i]->repaint(); + } + } + setSelectedType((ChannelType) idx, false); } - int idx = typeButtons.indexOf((UtilityButton*)b); - if ((idx >= 0) && (b->getToggleState())) - { - for (int i = 0; i < processor->getNumInputs(); i++) - { - if (lfpDisplay->channels[i]->getSelected()) - { - lfpDisplay->channels[i]->deselect(); - lfpDisplay->channels[i]->repaint(); - } - } - setSelectedType((channelType)idx,false); - } } @@ -414,126 +431,126 @@ void LfpDisplayCanvas::comboBoxChanged(ComboBox* cb) if (cb == timebaseSelection) { - if (cb->getSelectedId()) - { - timebase = timebases[cb->getSelectedId()-1].getFloatValue(); - } - else - { - timebase = cb->getText().getFloatValue(); - if (timebase) - { - if (timebase < timebases[0].getFloatValue()) - { - cb->setSelectedId(1,dontSendNotification); - timebase = timebases[0].getFloatValue(); - } - else if (timebase > timebases[timebases.size()-1].getFloatValue()) - { - cb->setSelectedId(timebases.size(),dontSendNotification); - timebase = timebases[timebases.size()-1].getFloatValue(); - } - else - cb->setText(String(timebase,1),dontSendNotification); - } - else - { - if (selectedSpread == 0) - { - cb->setText(selectedTimebaseValue,dontSendNotification); - timebase = selectedTimebaseValue.getFloatValue(); - } - else - { - cb->setSelectedId(selectedTimebase,dontSendNotification); - timebase = timebases[selectedTimebase-1].getFloatValue(); - } - - } - } + if (cb->getSelectedId()) + { + timebase = timebases[cb->getSelectedId()-1].getFloatValue(); + } + else + { + timebase = cb->getText().getFloatValue(); + if (timebase) + { + if (timebase < timebases[0].getFloatValue()) + { + cb->setSelectedId(1,dontSendNotification); + timebase = timebases[0].getFloatValue(); + } + else if (timebase > timebases[timebases.size()-1].getFloatValue()) + { + cb->setSelectedId(timebases.size(),dontSendNotification); + timebase = timebases[timebases.size()-1].getFloatValue(); + } + else + cb->setText(String(timebase,1),dontSendNotification); + } + else + { + if (selectedSpread == 0) + { + cb->setText(selectedTimebaseValue,dontSendNotification); + timebase = selectedTimebaseValue.getFloatValue(); + } + else + { + cb->setSelectedId(selectedTimebase,dontSendNotification); + timebase = timebases[selectedTimebase-1].getFloatValue(); + } + + } + } } else if (cb == rangeSelection) { - if (cb->getSelectedId()) - { - lfpDisplay->setRange(voltageRanges[selectedChannelType][cb->getSelectedId()-1].getFloatValue()*rangeGain[selectedChannelType] - ,selectedChannelType); - } - else - { - float vRange = cb->getText().getFloatValue(); - if (vRange) - { - if (vRange < voltageRanges[selectedChannelType][0].getFloatValue()) - { - cb->setSelectedId(1,dontSendNotification); - vRange = voltageRanges[selectedChannelType][0].getFloatValue(); - } - else if (vRange > voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue()) - { - cb->setSelectedId(voltageRanges[selectedChannelType].size(),dontSendNotification); - vRange = voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue(); - } - else - { - if (rangeGain[selectedChannelType] > 1) - cb->setText(String(vRange,1),dontSendNotification); - else - cb->setText(String(vRange),dontSendNotification); - } - lfpDisplay->setRange(vRange*rangeGain[selectedChannelType],selectedChannelType); - } - else - { - if (selectedVoltageRange[selectedChannelType]) - cb->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification); - else - cb->setSelectedId(selectedVoltageRange[selectedChannelType],dontSendNotification); - } - } - selectedVoltageRange[selectedChannelType] = cb->getSelectedId(); - selectedVoltageRangeValues[selectedChannelType] = cb->getText(); + if (cb->getSelectedId()) + { + lfpDisplay->setRange(voltageRanges[selectedChannelType][cb->getSelectedId()-1].getFloatValue()*rangeGain[selectedChannelType] + ,selectedChannelType); + } + else + { + float vRange = cb->getText().getFloatValue(); + if (vRange) + { + if (vRange < voltageRanges[selectedChannelType][0].getFloatValue()) + { + cb->setSelectedId(1,dontSendNotification); + vRange = voltageRanges[selectedChannelType][0].getFloatValue(); + } + else if (vRange > voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue()) + { + cb->setSelectedId(voltageRanges[selectedChannelType].size(),dontSendNotification); + vRange = voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue(); + } + else + { + if (rangeGain[selectedChannelType] > 1) + cb->setText(String(vRange,1),dontSendNotification); + else + cb->setText(String(vRange),dontSendNotification); + } + lfpDisplay->setRange(vRange*rangeGain[selectedChannelType],selectedChannelType); + } + else + { + if (selectedVoltageRange[selectedChannelType]) + cb->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification); + else + cb->setSelectedId(selectedVoltageRange[selectedChannelType],dontSendNotification); + } + } + selectedVoltageRange[selectedChannelType] = cb->getSelectedId(); + selectedVoltageRangeValues[selectedChannelType] = cb->getText(); //std::cout << "Setting range to " << voltageRanges[cb->getSelectedId()-1].getFloatValue() << std::endl; } else if (cb == spreadSelection) { - if (cb->getSelectedId()) - { - lfpDisplay->setChannelHeight(spreads[cb->getSelectedId()-1].getIntValue()); - resized(); - } - else - { - int spread = cb->getText().getIntValue(); - if (spread) - { - if (spread < spreads[0].getFloatValue()) - { - cb->setSelectedId(1,dontSendNotification); - spread = spreads[0].getFloatValue(); - } - else if (spread > spreads[spreads.size()-1].getFloatValue()) - { - cb->setSelectedId(spreads.size(),dontSendNotification); - spread = spreads[spreads.size()-1].getFloatValue(); - } - else - { - cb->setText(String(spread),dontSendNotification); - } - lfpDisplay->setChannelHeight(spread); - resized(); - } - else - { - if (selectedSpread == 0) - cb->setText(selectedSpreadValue,dontSendNotification); - else - cb->setSelectedId(selectedSpread,dontSendNotification); - } - } - selectedSpread = cb->getSelectedId(); - selectedSpreadValue = cb->getText(); + if (cb->getSelectedId()) + { + lfpDisplay->setChannelHeight(spreads[cb->getSelectedId()-1].getIntValue()); + resized(); + } + else + { + int spread = cb->getText().getIntValue(); + if (spread) + { + if (spread < spreads[0].getFloatValue()) + { + cb->setSelectedId(1,dontSendNotification); + spread = spreads[0].getFloatValue(); + } + else if (spread > spreads[spreads.size()-1].getFloatValue()) + { + cb->setSelectedId(spreads.size(),dontSendNotification); + spread = spreads[spreads.size()-1].getFloatValue(); + } + else + { + cb->setText(String(spread),dontSendNotification); + } + lfpDisplay->setChannelHeight(spread); + resized(); + } + else + { + if (selectedSpread == 0) + cb->setText(selectedSpreadValue,dontSendNotification); + else + cb->setSelectedId(selectedSpread,dontSendNotification); + } + } + selectedSpread = cb->getSelectedId(); + selectedSpreadValue = cb->getText(); //std::cout << "Setting spread to " << spreads[cb->getSelectedId()-1].getFloatValue() << std::endl; } else if (cb == colorGroupingSelection) @@ -571,19 +588,19 @@ void LfpDisplayCanvas::setParameter(int param, float val) void LfpDisplayCanvas:: setRangeSelection(float range, bool canvasMustUpdate) { - if (canvasMustUpdate) - { - rangeSelection->setText(String(range/rangeGain[selectedChannelType]), sendNotification); - } - else - { - rangeSelection->setText(String(range/rangeGain[selectedChannelType]),dontSendNotification); - selectedVoltageRange[selectedChannelType]=rangeSelection->getSelectedId(); - selectedVoltageRangeValues[selectedChannelType]=rangeSelection->getText(); + if (canvasMustUpdate) + { + rangeSelection->setText(String(range/rangeGain[selectedChannelType]), sendNotification); + } + else + { + rangeSelection->setText(String(range/rangeGain[selectedChannelType]),dontSendNotification); + selectedVoltageRange[selectedChannelType]=rangeSelection->getSelectedId(); + selectedVoltageRangeValues[selectedChannelType]=rangeSelection->getText(); - repaint(); - refresh(); - } + repaint(); + refresh(); + } } @@ -607,16 +624,21 @@ void LfpDisplayCanvas:: setSpreadSelection(int spread, bool canvasMustUpdate) void LfpDisplayCanvas::refreshState() { // called when the component's tab becomes visible again - displayBufferIndex = processor->getDisplayBufferIndex(); - screenBufferIndex = 0; + + for (int i = 0; i <= displayBufferIndex.size(); i++) // include event channel + { + + displayBufferIndex.set(i, processor->getDisplayBufferIndex(i)); + screenBufferIndex.set(i,0); + } } void LfpDisplayCanvas::refreshScreenBuffer() { - screenBufferIndex = 0; - displayBufferIndex = 0; + for (int i = 0; i <= screenBufferIndex.size(); i++) + screenBufferIndex.set(i,0); screenBuffer->clear(); screenBufferMin->clear(); @@ -643,130 +665,142 @@ void LfpDisplayCanvas::refreshScreenBuffer() void LfpDisplayCanvas::updateScreenBuffer() { - // copy new samples from the displayBuffer into the screenBuffer (waves) + // copy new samples from the displayBuffer into the screenBuffer int maxSamples = lfpDisplay->getWidth() - leftmargin; - if (screenBufferIndex >= maxSamples) // wrap around if we reached right edge before - screenBufferIndex = 0; - - lastScreenBufferIndex = screenBufferIndex; - - int index = processor->getDisplayBufferIndex(); - - int nSamples = index - displayBufferIndex; // N new samples (not pixels) to be added to displayBufferIndex - - if (nSamples < 0) // buffer has reset to 0 + for (int channel = 0; channel <= nChans; channel++) // pull one extra channel for event display { - nSamples = (displayBufferSize - displayBufferIndex) + index; - } - float ratio = sampleRate * timebase / float(getWidth() - leftmargin - scrollBarThickness); // samples / pixel - // this number is crucial: converting from samples to values (in px) for the screen buffer - int valuesNeeded = (int) float(nSamples) / ratio; // N pixels needed for this update + if (screenBufferIndex[channel] >= maxSamples) // wrap around if we reached right edge before + screenBufferIndex.set(channel, 0); - if (screenBufferIndex + valuesNeeded > maxSamples) // crop number of samples to fit cavas width - { - valuesNeeded = maxSamples - screenBufferIndex; - } + // hold these values locally for each channel + int sbi = screenBufferIndex[channel]; + int dbi = displayBufferIndex[channel]; - float subSampleOffset = 0.0; - - //std::cout << screenBufferIndex << " : " << index << " : " << displayBufferIndex << " : " << valuesNeeded << " : " << ratio << std::endl; + lastScreenBufferIndex.set(channel,sbi); - displayBufferIndex = displayBufferIndex % displayBufferSize; // make sure we're not overshooting - int nextPos = (displayBufferIndex +1) % displayBufferSize; // position next to displayBufferIndex in display buffer to copy from + int index = processor->getDisplayBufferIndex(channel); - if (valuesNeeded > 0 && valuesNeeded < 1000) - { - for (int i = 0; i < valuesNeeded; i++) // also fill one extra sample for line drawing interpolation to match across draws + int nSamples = index - dbi; // N new samples (not pixels) to be added to displayBufferIndex + + if (nSamples < 0) // buffer has reset to 0 { - //If paused don't update screen buffers, but update all indexes as needed - if (!lfpDisplay->isPaused) - { - float gain = 1.0; - float alpha = (float) subSampleOffset; - float invAlpha = 1.0f - alpha; + nSamples = (displayBufferSize - dbi) + index; + } - screenBuffer->clear(screenBufferIndex, 1); - screenBufferMin->clear(screenBufferIndex, 1); - screenBufferMean->clear(screenBufferIndex, 1); - screenBufferMax->clear(screenBufferIndex, 1); + //if (channel == 15 || channel == 16) + // std::cout << channel << " " << sbi << " " << dbi << " " << nSamples << std::endl; - displayBufferIndex = displayBufferIndex % displayBufferSize; // just to be sure + float ratio = sampleRate[channel] * timebase / float(getWidth() - leftmargin - scrollBarThickness); // samples / pixel + // this number is crucial: converting from samples to values (in px) for the screen buffer + int valuesNeeded = (int) float(nSamples) / ratio; // N pixels needed for this update - for (int channel = 0; channel <= nChans; channel++) // pull one extra channel for event display + if (sbi + valuesNeeded > maxSamples) // crop number of samples to fit canvas width + { + valuesNeeded = maxSamples - sbi; + } + float subSampleOffset = 0.0; + + dbi %= displayBufferSize; // make sure we're not overshooting + int nextPos = (dbi + 1) % displayBufferSize; // position next to displayBufferIndex in display buffer to copy from + + // if (channel == 0) + // std::cout << "Channel " + // << channel << " : " + // << sbi << " : " + // << index << " : " + // << dbi << " : " + // << valuesNeeded << " : " + // << ratio + // << std::endl; + + if (valuesNeeded > 0 && valuesNeeded < 10000) + { + for (int i = 0; i < valuesNeeded; i++) // also fill one extra sample for line drawing interpolation to match across draws + { + //If paused don't update screen buffers, but update all indexes as needed + if (!lfpDisplay->isPaused) { - - if (channel < displayBuffer->getNumChannels()) + float gain = 1.0; + float alpha = (float) subSampleOffset; + float invAlpha = 1.0f - alpha; + + screenBuffer->clear(channel, sbi, 1); + screenBufferMin->clear(channel, sbi, 1); + screenBufferMean->clear(channel, sbi, 1); + screenBufferMax->clear(channel, sbi, 1); + + dbi %= displayBufferSize; // just to be sure + + // interpolate between two samples with invAlpha and alpha + screenBuffer->addFrom(channel, // destChannel + sbi, // destStartSample + displayBuffer->getReadPointer(channel, dbi), // source + 1, // numSamples + invAlpha*gain); // gain + + + screenBuffer->addFrom(channel, // destChannel + sbi, // destStartSample + displayBuffer->getReadPointer(channel, nextPos), // source + 1, // numSamples + alpha*gain); // gain + + // same thing again, but this time add the min,mean, and max of all samples in current pixel + float sample_min = 1000000; + float sample_max = -1000000; + float sample_mean = 0; + int c = 0; + int nextpix = (dbi +(int)ratio) % displayBufferSize; // position to next pixels index + + for (int j = dbi; j < nextpix; j++) { - // interpolate between two samples with invAlpha and alpha - screenBuffer->addFrom(channel, // destChannel - screenBufferIndex, // destStartSample - displayBuffer->getReadPointer(channel, displayBufferIndex), // source - 1, // numSamples - invAlpha*gain); // gain - - - screenBuffer->addFrom(channel, // destChannel - screenBufferIndex, // destStartSample - displayBuffer->getReadPointer(channel, nextPos), // source - 1, // numSamples - alpha*gain); // gain - - // same thing again, but this time add the min,mean, and max of all samples in current pixel - float sample_min = 1000000; - float sample_max = -1000000; - float sample_mean = 0; - int c=0; - int nextpix = (displayBufferIndex +(int)ratio) % displayBufferSize; // position to next pixels index - for (int j = displayBufferIndex; j < nextpix; j++) - { - float sample_current = displayBuffer->getSample(channel, j); - sample_mean = sample_mean + sample_current; - - if (sample_min>sample_current) - { - sample_min=sample_current; - } - - if (sample_max<sample_current) - { - sample_max=sample_current; - } - c++; + float sample_current = displayBuffer->getSample(channel, j); + sample_mean = sample_mean + sample_current; + if (sample_min>sample_current) + { + sample_min=sample_current; + } + if (sample_max<sample_current) + { + sample_max=sample_current; } - sample_mean=sample_mean/c; - screenBufferMean->addSample(channel, screenBufferIndex, sample_mean*gain); - screenBufferMin->addSample(channel, screenBufferIndex, sample_min*gain); - screenBufferMax->addSample(channel, screenBufferIndex, sample_max*gain); + c++; + } + sample_mean = sample_mean/c; + screenBufferMean->addSample(channel, sbi, sample_mean*gain); + screenBufferMin->addSample(channel, sbi, sample_min*gain); + screenBufferMax->addSample(channel, sbi, sample_max*gain); + + sbi++; } - screenBufferIndex++; - } - + subSampleOffset += ratio; while (subSampleOffset >= 1.0) { - if (++displayBufferIndex > displayBufferSize) - displayBufferIndex = 0; + if (++dbi > displayBufferSize) + dbi = 0; - nextPos = (displayBufferIndex + 1) % displayBufferSize; + nextPos = (dbi + 1) % displayBufferSize; subSampleOffset -= 1.0; } } + // update values after we're done + screenBufferIndex.set(channel, sbi); + displayBufferIndex.set(channel, dbi); + } } - else - { - //std::cout << "Skip." << std::endl; - } + } const float LfpDisplayCanvas::getXCoord(int chan, int samp) @@ -843,12 +877,12 @@ void LfpDisplayCanvas::paint(Graphics& g) g.setColour(Colour(100,100,100)); - g.drawText("Voltage range ("+ rangeUnits[selectedChannelType] +")",5,getHeight()-55,300,20,Justification::left, false); + g.drawText("Voltage range ("+ rangeUnits[selectedChannelType] +")",5,getHeight()-55,300,20,Justification::left, false); g.drawText("Timebase (s)",175,getHeight()-55,300,20,Justification::left, false); g.drawText("Spread (px)",345,getHeight()-55,300,20,Justification::left, false); g.drawText("Color grouping",620,getHeight()-55,300,20,Justification::left, false); -// g.drawText(typeNames[selectedChannelType],110,getHeight()-30,50,20,Justification::centredLeft,false); + //g.drawText(typeNames[selectedChannelType],110,getHeight()-30,50,20,Justification::centredLeft,false); g.drawText("Event disp.",500,getHeight()-55,300,20,Justification::left, false); @@ -893,8 +927,8 @@ void LfpDisplayCanvas::saveVisualizerParameters(XmlElement* xml) XmlElement* xmlNode = xml->createNewChildElement("LFPDISPLAY"); - xmlNode->setAttribute("Range",selectedVoltageRangeValues[0]+","+selectedVoltageRangeValues[1]+ - ","+selectedVoltageRangeValues[2]); + xmlNode->setAttribute("Range",selectedVoltageRangeValues[0]+","+selectedVoltageRangeValues[1]+ + ","+selectedVoltageRangeValues[2]); xmlNode->setAttribute("Timebase",timebaseSelection->getText()); xmlNode->setAttribute("Spread",spreadSelection->getText()); xmlNode->setAttribute("colorGrouping",colorGroupingSelection->getSelectedId()); @@ -940,15 +974,15 @@ void LfpDisplayCanvas::loadVisualizerParameters(XmlElement* xml) { if (xmlNode->hasTagName("LFPDISPLAY")) { - StringArray ranges; - ranges.addTokens(xmlNode->getStringAttribute("Range"),",",String::empty); - selectedVoltageRangeValues[0] = ranges[0]; - selectedVoltageRangeValues[1] = ranges[1]; - selectedVoltageRangeValues[2] = ranges[2]; - selectedVoltageRange[0] = voltageRanges[0].indexOf(ranges[0])+1; - selectedVoltageRange[1] = voltageRanges[1].indexOf(ranges[1])+1; - selectedVoltageRange[2] = voltageRanges[2].indexOf(ranges[2])+1; - rangeSelection->setText(ranges[0]); + StringArray ranges; + ranges.addTokens(xmlNode->getStringAttribute("Range"),",",String::empty); + selectedVoltageRangeValues[0] = ranges[0]; + selectedVoltageRangeValues[1] = ranges[1]; + selectedVoltageRangeValues[2] = ranges[2]; + selectedVoltageRange[0] = voltageRanges[0].indexOf(ranges[0])+1; + selectedVoltageRange[1] = voltageRanges[1].indexOf(ranges[1])+1; + selectedVoltageRange[2] = voltageRanges[2].indexOf(ranges[2])+1; + rangeSelection->setText(ranges[0]); timebaseSelection->setText(xmlNode->getStringAttribute("Timebase")); spreadSelection->setText(xmlNode->getStringAttribute("Spread")); @@ -1002,43 +1036,42 @@ void LfpDisplayCanvas::loadVisualizerParameters(XmlElement* xml) } -channelType LfpDisplayCanvas::getChannelType(int n) +ChannelType LfpDisplayCanvas::getChannelType(int n) { - if (n < processor->channels.size()) - return processor->channels[n]->getType(); - else - return DATA_CHANNEL; + return processor->channels[n]->getType(); } -channelType LfpDisplayCanvas::getSelectedType() +ChannelType LfpDisplayCanvas::getSelectedType() { - return selectedChannelType; + return selectedChannelType; } -void LfpDisplayCanvas::setSelectedType(channelType type, bool toggleButton) +void LfpDisplayCanvas::setSelectedType(ChannelType type, bool toggleButton) { - if (selectedChannelType == type) - return; //Nothing to do here - selectedChannelType = type; - rangeSelection->clear(dontSendNotification); - rangeSelection->addItemList(voltageRanges[type],1); - int id = selectedVoltageRange[type]; - if (id) - rangeSelection->setSelectedId(id,sendNotification); - else - rangeSelection->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification); - if (toggleButton) - typeButtons[type]->setToggleState(true,dontSendNotification); + if (selectedChannelType == type) + return; //Nothing to do here + selectedChannelType = type; + rangeSelection->clear(dontSendNotification); + rangeSelection->addItemList(voltageRanges[type],1); + int id = selectedVoltageRange[type]; + if (id) + rangeSelection->setSelectedId(id,sendNotification); + else + rangeSelection->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification); + repaint(5,getHeight()-55,300,100); + + if (toggleButton) + typeButtons[type]->setToggleState(true,dontSendNotification); } -String LfpDisplayCanvas::getTypeName(channelType type) +String LfpDisplayCanvas::getTypeName(ChannelType type) { - return typeNames[type]; + return typeNames[type]; } -int LfpDisplayCanvas::getRangeStep(channelType type) +int LfpDisplayCanvas::getRangeStep(ChannelType type) { - return rangeSteps[type]; + return rangeSteps[type]; } // ------------------------------------------------------------- @@ -1103,9 +1136,9 @@ LfpDisplay::LfpDisplay(LfpDisplayCanvas* c, Viewport* v) : totalHeight = 0; colorGrouping=1; - range[0] = 1000; - range[1] = 500; - range[2] = 500000; + range[0] = 1000; + range[1] = 500; + range[2] = 500000; addMouseListener(this, true); @@ -1183,7 +1216,7 @@ void LfpDisplay::setNumChannels(int numChannels) LfpChannelDisplay* lfpChan = new LfpChannelDisplay(canvas, this, i); //lfpChan->setColour(channelColours[i % channelColours.size()]); - lfpChan->setRange(range[canvas->getChannelType(i)]); + lfpChan->setRange(range[canvas->getChannelType(i)]); lfpChan->setChannelHeight(canvas->getChannelHeight()); addAndMakeVisible(lfpChan); @@ -1200,8 +1233,6 @@ void LfpDisplay::setNumChannels(int numChannels) channelInfo.add(lfpInfo); - savedChannelState.add(true); - totalHeight += lfpChan->getChannelHeight(); } @@ -1299,7 +1330,7 @@ void LfpDisplay::refresh() } else { - channels[i]->repaint(canvas->lastScreenBufferIndex-2, 0, (canvas->screenBufferIndex-canvas->lastScreenBufferIndex)+3, getChildComponent(i)->getHeight()); //repaint only the updated portion + channels[i]->repaint(canvas->lastScreenBufferIndex[i]-2, 0, (canvas->screenBufferIndex[i]-canvas->lastScreenBufferIndex[i])+3, getChildComponent(i)->getHeight()); //repaint only the updated portion // we redraw from -2 to +1 relative to the real redraw window, the -2 makes sure that the lines join nicely, and the +1 draws the vertical update line } //std::cout << i << std::endl; @@ -1310,30 +1341,30 @@ void LfpDisplay::refresh() canvas->fullredraw = false; } -void LfpDisplay::setRange(float r, channelType type) +void LfpDisplay::setRange(float r, ChannelType type) { range[type] = r; for (int i = 0; i < numChans; i++) { - if (channels[i]->getType() == type) - channels[i]->setRange(range[type]); + if (channels[i]->getType() == type) + channels[i]->setRange(range[type]); } canvas->fullredraw = true; //issue full redraw } int LfpDisplay::getRange() { - return getRange(canvas->getSelectedType()); + return getRange(canvas->getSelectedType()); } -int LfpDisplay::getRange(channelType type) +int LfpDisplay::getRange(ChannelType type) { - for (int i=0; i < numChans; i++) - { - if (channels[i]->getType() == type) - return channels[i]->getRange(); - } + for (int i=0; i < numChans; i++) + { + if (channels[i]->getType() == type) + return channels[i]->getRange(); + } } @@ -1353,7 +1384,7 @@ void LfpDisplay::setChannelHeight(int r, bool resetSingle) singleChan = -1; for (int n = 0; n < numChans; n++) { - channelInfo[n]->setEnabledState(savedChannelState[n]); + channelInfo[n]->setEnabledState(true); } } @@ -1395,8 +1426,8 @@ void LfpDisplay::mouseWheelMove(const MouseEvent& e, const MouseWheelDetails& { //std::cout << "Mouse wheel " << e.mods.isCommandDown() << " " << wheel.deltaY << std::endl; - //TODO Changing ranges with the wheel is currently broken. With multiple ranges, most - //of the wheel range code needs updating + //TODO Changing ranges with the wheel is currently broken. With multiple ranges, most + //of the wheel range code needs updating if (e.mods.isCommandDown()) // CTRL + scroll wheel -> change channel spacing { int h = getChannelHeight(); @@ -1435,18 +1466,18 @@ void LfpDisplay::mouseWheelMove(const MouseEvent& e, const MouseWheelDetails& if (e.mods.isShiftDown()) // SHIFT + scroll wheel -> change channel range { int h = getRange(); - int step = canvas->getRangeStep(canvas->getSelectedType()); + int step = canvas->getRangeStep(canvas->getSelectedType()); std::cout << wheel.deltaY << std::endl; if (wheel.deltaY > 0) { - setRange(h+step,canvas->getSelectedType()); + setRange(h+step,canvas->getSelectedType()); } else { if (h > step+1) - setRange(h-step,canvas->getSelectedType()); + setRange(h-step,canvas->getSelectedType()); } canvas->setRangeSelection(h); // update combobox @@ -1474,14 +1505,12 @@ void LfpDisplay::toggleSingleChannel(int chan) { singleChan = chan; int newHeight = viewport->getHeight(); - channelInfo[chan]->setEnabledState(true); setChannelHeight(newHeight, false); setSize(getWidth(), numChans*getChannelHeight()); viewport->setScrollBarsShown(false,false); viewport->setViewPosition(Point<int>(0,chan*newHeight)); for (int n = 0; n < numChans; n++) { - savedChannelState.set(n,channels[n]->getEnabledState()); if (n != chan) channelInfo[n]->setEnabledState(false); } @@ -1528,7 +1557,7 @@ void LfpDisplay::mouseDown(const MouseEvent& event) //lcd->select(); channels[closest]->select(); - canvas->setSelectedType(channels[closest]->getType()); + canvas->setSelectedType(channels[closest]->getType()); if (event.getNumberOfClicks() == 2) toggleSingleChannel(closest); @@ -1601,8 +1630,8 @@ LfpChannelDisplay::LfpChannelDisplay(LfpDisplayCanvas* c, LfpDisplay* d, int cha lineColour = Colour(255,255,255); - type = c->getChannelType(channelNumber); - typeStr = c->getTypeName(type); + type = c->getChannelType(channelNumber); + typeStr = c->getTypeName(type); } @@ -1613,8 +1642,8 @@ LfpChannelDisplay::~LfpChannelDisplay() void LfpChannelDisplay::updateType() { - type = canvas->getChannelType(chan); - typeStr = canvas->getTypeName(type); + type = canvas->getChannelType(chan); + typeStr = canvas->getTypeName(type); } void LfpChannelDisplay::setEnabledState(bool state) @@ -1635,7 +1664,7 @@ void LfpChannelDisplay::paint(Graphics& g) //g.fillAll(Colours::grey); g.setColour(Colours::yellow); // draw most recent drawn sample position - g.drawLine(canvas->screenBufferIndex+1, 0, canvas->screenBufferIndex+1, getHeight()); + g.drawLine(canvas->screenBufferIndex[chan]+1, 0, canvas->screenBufferIndex[chan]+1, getHeight()); //g.setColour(Colours::red); // draw oldest drawn sample position @@ -1675,7 +1704,7 @@ void LfpChannelDisplay::paint(Graphics& g) int leftEdge = 150; - float r = range; + float r = range; g.setColour(Colours::lightgrey); g.setFont(channelFont); @@ -1683,10 +1712,10 @@ void LfpChannelDisplay::paint(Graphics& g) String unitString; if (getType() == ADC_CHANNEL) { - unitString = " V"; - //r = range / 1000.0f; + unitString = " V"; + //r = range / 1000.0f; } else { - unitString = " uV"; + unitString = " uV"; } g.drawText(String(0) + unitString, 20, center, leftEdge, 25, Justification::left, false); g.drawText(String(r/2) + unitString, 20, center-channelHeight/2, leftEdge, 25, Justification::left, false); @@ -1705,12 +1734,12 @@ void LfpChannelDisplay::paint(Graphics& g) int to = 0; //for (int i = 0; i < getWidth()-stepSize; i += stepSize) // redraw entire display - int ifrom = canvas->lastScreenBufferIndex - 3; // need to start drawing a bit before the actual redraw windowfor the interpolated line to join correctly + int ifrom = canvas->lastScreenBufferIndex[chan] - 3; // need to start drawing a bit before the actual redraw windowfor the interpolated line to join correctly if (ifrom < 0) ifrom = 0; - int ito = canvas->screenBufferIndex - 1; + int ito = canvas->screenBufferIndex[chan] - 1; if (fullredraw) { @@ -1724,12 +1753,17 @@ void LfpChannelDisplay::paint(Graphics& g) // draw event markers int rawEventState = canvas->getYCoord(canvas->getNumChannels(), i);// get last channel+1 in buffer (represents events) + + //if (i == ifrom) + // std::cout << rawEventState << std::endl; + for (int ev_ch = 0; ev_ch < 8 ; ev_ch++) // for all event channels { if (display->getEventDisplayState(ev_ch)) // check if plotting for this channel is enabled { if (rawEventState & (1 << ev_ch)) // events are representet by a bit code, so we have to extract the individual bits with a mask { + //std::cout << "Drawing event." << std::endl; g.setColour(display->channelColours[ev_ch*2]); // get color from lfp color scheme g.setOpacity(0.35f); g.drawLine(i, center-channelHeight/2 , i, center+channelHeight/2); @@ -1817,7 +1851,7 @@ void LfpChannelDisplay::paint(Graphics& g) void LfpChannelDisplay::setRange(float r) { - + range = r; //std::cout << "Range: " << r << std::endl; @@ -1841,7 +1875,7 @@ void LfpChannelDisplay::deselect() bool LfpChannelDisplay::getSelected() { - return isSelected; + return isSelected; } void LfpChannelDisplay::setColour(Colour c) @@ -1906,9 +1940,9 @@ void LfpChannelDisplay::setName(String name_) name = name_; } -channelType LfpChannelDisplay::getType() +ChannelType LfpChannelDisplay::getType() { - return type; + return type; } // ------------------------------- @@ -1934,9 +1968,9 @@ LfpChannelDisplayInfo::LfpChannelDisplayInfo(LfpDisplayCanvas* canvas_, LfpDispl void LfpChannelDisplayInfo::updateType() { - type = canvas->getChannelType(chan); - typeStr = canvas->getTypeName(type); - repaint(); + type = canvas->getChannelType(chan); + typeStr = canvas->getTypeName(type); + repaint(); } void LfpChannelDisplayInfo::buttonClicked(Button* button) @@ -1972,12 +2006,12 @@ void LfpChannelDisplayInfo::paint(Graphics& g) g.setColour(lineColour); //if (chan > 98) - // g.fillRoundedRectangle(5,center-8,51,22,8.0f); + // g.fillRoundedRectangle(5,center-8,51,22,8.0f); //else g.fillRoundedRectangle(5,center-8,41,22,8.0f); g.setFont(Font("Small Text", 13, Font::plain)); - g.drawText(typeStr,5,center+16,41,10,Justification::centred,false); + g.drawText(typeStr,5,center+16,41,10,Justification::centred,false); // g.setFont(channelHeightFloat*0.3); // g.drawText(name, 10, center-channelHeight/2, 200, channelHeight, Justification::left, false); @@ -1990,7 +2024,7 @@ void LfpChannelDisplayInfo::resized() int center = getHeight()/2; //if (chan > 98) - // enableButton->setBounds(8,center-5,45,16); + // enableButton->setBounds(8,center-5,45,16); //else enableButton->setBounds(8,center-5,35,16); } @@ -2066,13 +2100,13 @@ void EventDisplayInterface::paint(Graphics& g) // Lfp Viewport ------------------------------------------- LfpViewport::LfpViewport(LfpDisplayCanvas *canvas) - : Viewport() + : Viewport() { - this->canvas = canvas; + this->canvas = canvas; } void LfpViewport::visibleAreaChanged(const Rectangle<int>& newVisibleArea) { - canvas->fullredraw = true; - canvas->refresh(); + canvas->fullredraw = true; + canvas->refresh(); } diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.h b/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.h index 4c326e42a1aa24b0d446cdc9794ffcadbd6bcf28..d814232a6e3e6fc2695e7605c01e6a2b40ad12fe 100755 --- a/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.h +++ b/Source/Processors/LfpDisplayNode/LfpDisplayCanvas.h @@ -64,8 +64,8 @@ public: void setParameter(int, float); void setParameter(int, int, int, float) {} - void setRangeSelection(float range, bool canvasMustUpdate = false); // set range selection combo box to correct value if it has been changed by scolling etc. - void setSpreadSelection(int spread, bool canvasMustUpdate = false); // set spread selection combo box to correct value if it has been changed by scolling etc. + void setRangeSelection(float range, bool canvasMustUpdate = false); // set range selection combo box to correct value if it has been changed by scolling etc. + void setSpreadSelection(int spread, bool canvasMustUpdate = false); // set spread selection combo box to correct value if it has been changed by scolling etc. void paint(Graphics& g); @@ -86,8 +86,8 @@ public: const float getYCoordMean(int chan, int samp); const float getYCoordMax(int chan, int samp); - int screenBufferIndex; - int lastScreenBufferIndex; + Array<int> screenBufferIndex; + Array<int> lastScreenBufferIndex; void comboBoxChanged(ComboBox* cb); void buttonClicked(Button* button); @@ -98,12 +98,12 @@ public: bool keyPressed(const KeyPress& key); bool keyPressed(const KeyPress& key, Component* orig); - channelType getChannelType(int n); - channelType getSelectedType(); - String getTypeName(channelType type); - int getRangeStep(channelType type); + ChannelType getChannelType(int n); + ChannelType getSelectedType(); + String getTypeName(ChannelType type); + int getRangeStep(ChannelType type); - void setSelectedType(channelType type, bool toggleButton = true); + void setSelectedType(ChannelType type, bool toggleButton = true); //void scrollBarMoved(ScrollBar *scrollBarThatHasMoved, double newRangeStart); @@ -112,18 +112,18 @@ public: Array<bool> isChannelEnabled; - int nChans; + int nChans; private: - float sampleRate; + Array<float> sampleRate; float timebase; float displayGain; float timeOffset; //int spread ; // vertical spacing between channels - static const int MAX_N_CHAN = 1028; // maximum number of channels + static const int MAX_N_CHAN = 2048; // maximum number of channels static const int MAX_N_SAMP = 5000; // maximum display size in pixels //float waves[MAX_N_CHAN][MAX_N_SAMP*2]; // we need an x and y point for each sample @@ -150,36 +150,36 @@ private: ScopedPointer<UtilityButton> invertInputButton; ScopedPointer<UtilityButton> drawMethodButton; ScopedPointer<UtilityButton> pauseButton; - OwnedArray<UtilityButton> typeButtons; + OwnedArray<UtilityButton> typeButtons; StringArray voltageRanges[CHANNEL_TYPES]; StringArray timebases; StringArray spreads; // option for vertical spacing between channels StringArray colorGroupings; // option for coloring every N channels the same - channelType selectedChannelType; - int selectedVoltageRange[CHANNEL_TYPES]; - String selectedVoltageRangeValues[CHANNEL_TYPES]; - float rangeGain[CHANNEL_TYPES]; - StringArray rangeUnits; - StringArray typeNames; - int rangeSteps[CHANNEL_TYPES]; + ChannelType selectedChannelType; + int selectedVoltageRange[CHANNEL_TYPES]; + String selectedVoltageRangeValues[CHANNEL_TYPES]; + float rangeGain[CHANNEL_TYPES]; + StringArray rangeUnits; + StringArray typeNames; + int rangeSteps[CHANNEL_TYPES]; - int selectedSpread; - String selectedSpreadValue; + int selectedSpread; + String selectedSpreadValue; - int selectedTimebase; - String selectedTimebaseValue; + int selectedTimebase; + String selectedTimebaseValue; OwnedArray<EventDisplayInterface> eventDisplayInterfaces; void refreshScreenBuffer(); void updateScreenBuffer(); - int displayBufferIndex; + Array<int> displayBufferIndex; int displayBufferSize; - int scrollBarThickness; + int scrollBarThickness; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayCanvas); @@ -228,11 +228,11 @@ public: void mouseWheelMove(const MouseEvent& event, const MouseWheelDetails& wheel) ; - void setRange(float range, channelType type); - - //Withouth parameters returns selected type + void setRange(float range, ChannelType type); + + //Withouth parameters returns selected type int getRange(); - int getRange(channelType type); + int getRange(ChannelType type); void setChannelHeight(int r, bool resetSingle = true); int getChannelHeight(); @@ -251,7 +251,7 @@ public: bool getEnabledState(int); void enableChannel(bool, int); - bool getSingleChannelState(); + bool getSingleChannelState(); Array<Colour> channelColours; @@ -262,9 +262,8 @@ public: bool isPaused; // simple pause function, skips screen bufer updates private: - void toggleSingleChannel(int chan); - int singleChan; - Array<bool> savedChannelState; + void toggleSingleChannel(int chan); + int singleChan; int numChans; @@ -290,7 +289,8 @@ public: void select(); void deselect(); - bool getSelected(); + + bool getSelected(); void setName(String); @@ -316,8 +316,8 @@ public: return isEnabled; } - channelType getType(); - void updateType(); + ChannelType getType(); + void updateType(); bool fullredraw; // used to indicate that a full redraw is required. is set false after each full redraw @@ -347,8 +347,8 @@ protected: bool canBeInverted; bool drawMethod; - channelType type; - String typeStr; + ChannelType type; + String typeStr; }; @@ -365,7 +365,7 @@ public: void resized(); void setEnabledState(bool); - void updateType(); + void updateType(); private: @@ -402,11 +402,11 @@ private: class LfpViewport : public Viewport { public: - LfpViewport(LfpDisplayCanvas* canvas); - void visibleAreaChanged(const Rectangle<int>& newVisibleArea); + LfpViewport(LfpDisplayCanvas* canvas); + void visibleAreaChanged(const Rectangle<int>& newVisibleArea); private: - LfpDisplayCanvas* canvas; + LfpDisplayCanvas* canvas; }; diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayNode.cpp b/Source/Processors/LfpDisplayNode/LfpDisplayNode.cpp index bc6b8dd153d91e5791bc86c0cb24c7e274d84533..06b4acd31ecb3888f9349810b877c594e885289c 100755 --- a/Source/Processors/LfpDisplayNode/LfpDisplayNode.cpp +++ b/Source/Processors/LfpDisplayNode/LfpDisplayNode.cpp @@ -27,12 +27,11 @@ LfpDisplayNode::LfpDisplayNode() : GenericProcessor("LFP Viewer"), - displayBufferIndex(0), displayGain(1), bufferLength(5.0f), - abstractFifo(100), ttlState(0) + displayGain(1), bufferLength(5.0f), + abstractFifo(100) { //std::cout << " LFPDisplayNodeConstructor" << std::endl; displayBuffer = new AudioSampleBuffer(8, 100); - eventBuffer = new MidiBuffer(); arrayOfOnes = new float[5000]; @@ -58,7 +57,38 @@ AudioProcessorEditor* LfpDisplayNode::createEditor() void LfpDisplayNode::updateSettings() { - // std::cout << "Setting num inputs on LfpDisplayNode to " << getNumInputs() << std::endl; + std::cout << "Setting num inputs on LfpDisplayNode to " << getNumInputs() << std::endl; + + channelForEventSource.clear(); + eventSourceNodes.clear(); + ttlState.clear(); + + for (int i = 0; i < eventChannels.size(); i++) + { + if (!eventSourceNodes.contains(eventChannels[i]->sourceNodeId)) + { + eventSourceNodes.add(eventChannels[i]->sourceNodeId); + + } + } + + numEventChannels = eventSourceNodes.size(); + + std::cout << "Found " << numEventChannels << " event channels." << std::endl; + + for (int i = 0; i < eventSourceNodes.size(); i++) + { + std::cout << "Adding channel " << getNumInputs() + i << " for event source node " << eventSourceNodes[i] << std::endl; + channelForEventSource[eventSourceNodes[i]] = getNumInputs() + i; + ttlState[eventSourceNodes[i]] = 0; + Channel* eventChan = new Channel(this, getNumInputs() + i, EVENT_CHANNEL); + eventChan->sourceNodeId = eventSourceNodes[i]; + channels.add(eventChan); // add a channel for event data for each source node + } + + displayBufferIndex.clear(); + displayBufferIndex.insertMultiple(0, 0, getNumInputs() + numEventChannels); + } bool LfpDisplayNode::resizeBuffer() @@ -71,7 +101,7 @@ bool LfpDisplayNode::resizeBuffer() if (nSamples > 0 && nInputs > 0) { abstractFifo.setTotalSize(nSamples); - displayBuffer->setSize(nInputs+1, nSamples); // add an extra channel for TTLs + displayBuffer->setSize(nInputs + numEventChannels, nSamples); // add extra channels for TTLs return true; } else @@ -108,8 +138,8 @@ void LfpDisplayNode::setParameter(int parameterIndex, float newValue) { editor->updateParameterButtons(parameterIndex); //Sets Parameter in parameters array for processor - Parameter* parameterPointer=parameters.getRawDataPointer(); - parameterPointer=parameterPointer+parameterIndex; + Parameter* parameterPointer = parameters.getRawDataPointer(); + parameterPointer = parameterPointer+parameterIndex; parameterPointer->setValue(newValue, currentChannel); //std::cout << "Saving Parameter from " << currentChannel << ", channel "; @@ -125,61 +155,64 @@ void LfpDisplayNode::handleEvent(int eventType, MidiMessage& event, int sampleNu { const uint8* dataptr = event.getRawData(); - // int eventNodeId = *(dataptr+1); + int eventSourceNode = *(dataptr+1); int eventId = *(dataptr+2); int eventChannel = *(dataptr+3); int eventTime = event.getTimeStamp(); - int samplesLeft = totalSamples - eventTime; + int nSamples = numSamples.at(eventSourceNode); - // std::cout << "Received event from " << eventNodeId << ", channel " - // << eventChannel << ", with ID " << eventId << std::endl; - // - int bufferIndex = (displayBufferIndex + eventTime);// % displayBuffer->getNumSamples(); + int samplesToFill = nSamples - eventTime; + + // std::cout << "Received event from " << eventSourceNode << ", channel " + // << eventChannel << ", with ID " << eventId << ", copying to " + // << channelForEventSource[eventSourceNode] << std::endl; + //// + int bufferIndex = (displayBufferIndex[channelForEventSource[eventSourceNode]] + eventTime) % displayBuffer->getNumSamples(); if (eventId == 1) { - ttlState |= (1L << eventChannel); + ttlState[eventSourceNode] |= (1L << eventChannel); } else { - ttlState &= ~(1L << eventChannel); + ttlState[eventSourceNode] &= ~(1L << eventChannel); } - if (samplesLeft + bufferIndex < displayBuffer->getNumSamples()) + if (samplesToFill + bufferIndex < displayBuffer->getNumSamples()) { - // std::cout << bufferIndex << " " << samplesLeft << " " << ttlState << std::endl; + //std::cout << bufferIndex << " " << samplesToFill << " " << ttlState[eventSourceNode] << std::endl; - displayBuffer->copyFrom(displayBuffer->getNumChannels()-1, // destChannel + displayBuffer->copyFrom(channelForEventSource[eventSourceNode], // destChannel bufferIndex, // destStartSample arrayOfOnes, // source - samplesLeft, // numSamples - float(ttlState)); // gain + samplesToFill, // numSamples + float(ttlState[eventSourceNode])); // gain } else { - int block2Size = (samplesLeft + bufferIndex) % displayBuffer->getNumSamples(); - int block1Size = samplesLeft - block2Size; + int block2Size = (samplesToFill + bufferIndex) % displayBuffer->getNumSamples(); + int block1Size = samplesToFill - block2Size; //std::cout << "OVERFLOW." << std::endl; //std::cout << bufferIndex << " " << block1Size << " " << ttlState << std::endl; - displayBuffer->copyFrom(displayBuffer->getNumChannels()-1, // destChannel + displayBuffer->copyFrom(channelForEventSource[eventSourceNode], // destChannel bufferIndex, // destStartSample arrayOfOnes, // source block1Size, // numSamples - float(ttlState)); // gain + float(ttlState[eventSourceNode])); // gain //std::cout << 0 << " " << block2Size << " " << ttlState << std::endl; - displayBuffer->copyFrom(displayBuffer->getNumChannels()-1, // destChannel - 0, // destStartSample + displayBuffer->copyFrom(channelForEventSource[eventSourceNode], // destChannel + 0, // destStartSample arrayOfOnes, // source block2Size, // numSamples - float(ttlState)); // gain + float(ttlState[eventSourceNode])); // gain } @@ -194,132 +227,108 @@ void LfpDisplayNode::handleEvent(int eventType, MidiMessage& event, int sampleNu } - else if (eventType == TIMESTAMP) - { - - const uint8* dataptr = event.getRawData(); - - // int eventNodeId = *(dataptr+1); - // int eventId = *(dataptr+2); - // int eventChannel = *(dataptr+3); - - // update the timestamp for the current buffer: - memcpy(&bufferTimestamp, dataptr+4, 4); - - - // double timeInSeconds = double(ts)/Time::getHighResolutionTicksPerSecond(); - // //int64 timestamp = ts[0] << 32 + - // // ts[1] << 16 + - // // ts[2] << 8 + - // // ts[3]; - // //memcpy(ts, dataptr+4, 1); - - // std::cout << "Time in seconds is " << timeInSeconds << std::endl; - - // // std::cout << "Received event from " << eventNodeId << - // // " on channel " << eventChannel << - // // " with value " << eventId << - // // " for time: " << ts << std::endl; - } } -void LfpDisplayNode::initializeEventChannel() +void LfpDisplayNode::initializeEventChannels() { - if (displayBufferIndex + totalSamples < displayBuffer->getNumSamples()) - { - // std::cout << getNumInputs()+1 << " " << displayBufferIndex << " " << totalSamples << " " << ttlState << std::endl; - // - displayBuffer->copyFrom(displayBuffer->getNumChannels()-1, // destChannel - displayBufferIndex, // destStartSample - arrayOfOnes, // source - totalSamples, // numSamples - float(ttlState)); // gain - } - else + for (int i = 0; i < eventSourceNodes.size(); i++) { - int block2Size = (displayBufferIndex + totalSamples) % displayBuffer->getNumSamples(); - int block1Size = totalSamples - block2Size; + int chan = channelForEventSource[eventSourceNodes[i]]; + int index = displayBufferIndex[15]; //displayBufferIndex[chan]; - // std::cout << "OVERFLOW." << std::endl; + int samplesLeft = displayBuffer->getNumSamples() - index; + int nSamples = numSamples.at(eventSourceNodes[i]); - // std::cout << bufferIndex << " " << block1Size << " " << ttlState << std::endl; + if (nSamples < samplesLeft) + { - displayBuffer->copyFrom(displayBuffer->getNumChannels()-1, // destChannel - displayBufferIndex, // destStartSample - arrayOfOnes, // source - block1Size, // numSamples - float(ttlState)); // gain - // std::cout << 0 << " " << block2Size << " " << ttlState << std::endl; + // std::cout << getNumInputs()+1 << " " << displayBufferIndex << " " << totalSamples << " " << ttlState << std::endl; + // + displayBuffer->copyFrom(chan, // destChannel + index, // destStartSample + arrayOfOnes, // source + nSamples, // numSamples + float(ttlState[eventSourceNodes[i]])); // gain + + displayBufferIndex.set(chan, index + nSamples); + } + else + { - displayBuffer->copyFrom(displayBuffer->getNumChannels()-1, // destChannel - 0, // destStartSample - arrayOfOnes, // source - block2Size, // numSamples - float(ttlState)); // gain + int extraSamples = nSamples - samplesLeft; + // std::cout << "OVERFLOW." << std::endl; + // std::cout << bufferIndex << " " << block1Size << " " << ttlState << std::endl; - } + displayBuffer->copyFrom(chan, // destChannel + index, // destStartSample + arrayOfOnes, // source + samplesLeft, // numSamples + float(ttlState[eventSourceNodes[i]])); // gain + // std::cout << 0 << " " << block2Size << " " << ttlState << std::endl; + + displayBuffer->copyFrom(chan, // destChannel + 0, // destStartSample + arrayOfOnes, // source + extraSamples, // numSamples + float(ttlState[eventSourceNodes[i]])); // gain + + displayBufferIndex.set(chan, extraSamples); + } + } } -void LfpDisplayNode::process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples) +void LfpDisplayNode::process(AudioSampleBuffer& buffer, MidiBuffer& events) { // 1. place any new samples into the displayBuffer //std::cout << "Display node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl; - totalSamples = nSamples; - displayBufferIndexEvents = displayBufferIndex; - - initializeEventChannel(); - - checkForEvents(events); // update timestamp, see if we got any TTL events + initializeEventChannels(); - int samplesLeft = displayBuffer->getNumSamples() - displayBufferIndex; + checkForEvents(events); // see if we got any TTL events - if (nSamples < samplesLeft) + for (int chan = 0; chan < buffer.getNumChannels(); chan++) { + int samplesLeft = displayBuffer->getNumSamples() - displayBufferIndex[chan]; + int nSamples = getNumSamples(chan); - for (int chan = 0; chan < buffer.getNumChannels(); chan++) + if (nSamples < samplesLeft) { + displayBuffer->copyFrom(chan, // destChannel - displayBufferIndex, // destStartSample + displayBufferIndex[chan], // destStartSample buffer, // source chan, // source channel 0, // source start sample nSamples); // numSamples - + + displayBufferIndex.set(chan, displayBufferIndex[chan] + nSamples); } - displayBufferIndex += (nSamples); - - } - else - { + else + { - int extraSamples = nSamples - samplesLeft; + int extraSamples = nSamples - samplesLeft; - for (int chan = 0; chan < buffer.getNumChannels(); chan++) - { displayBuffer->copyFrom(chan, // destChannel - displayBufferIndex, // destStartSample - buffer, // source - chan, // source channel - 0, // source start sample - samplesLeft); // numSamples - - displayBuffer->copyFrom(chan, - 0, - buffer, - chan, - samplesLeft, - extraSamples); + displayBufferIndex[chan], // destStartSample + buffer, // source + chan, // source channel + 0, // source start sample + samplesLeft); // numSamples + + displayBuffer->copyFrom(chan, + 0, + buffer, + chan, + samplesLeft, + extraSamples); + + displayBufferIndex.set(chan, extraSamples); } - - displayBufferIndex = extraSamples; } - - } diff --git a/Source/Processors/LfpDisplayNode/LfpDisplayNode.h b/Source/Processors/LfpDisplayNode/LfpDisplayNode.h index 6a061d44d482980328178747ec256ef5fe79480c..a475e19f35f5849822b23b5833da402389c00b99 100755 --- a/Source/Processors/LfpDisplayNode/LfpDisplayNode.h +++ b/Source/Processors/LfpDisplayNode/LfpDisplayNode.h @@ -55,7 +55,7 @@ public: return true; } - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int, float); @@ -70,20 +70,22 @@ public: { return displayBuffer; } - int getDisplayBufferIndex() + int getDisplayBufferIndex(int chan) { - return displayBufferIndex; + return displayBufferIndex[chan]; } private: - void initializeEventChannel(); + void initializeEventChannels(); ScopedPointer<AudioSampleBuffer> displayBuffer; - ScopedPointer<MidiBuffer> eventBuffer; - int displayBufferIndex; - int displayBufferIndexEvents; + Array<int> displayBufferIndex; + Array<int> eventSourceNodes; + std::map<int, int> channelForEventSource; + + int numEventChannels; float displayGain; // float bufferLength; // s @@ -91,12 +93,10 @@ private: AbstractFifo abstractFifo; int64 bufferTimestamp; - int ttlState; + std::map<int, int> ttlState; float* arrayOfOnes; int totalSamples; - //Time timer; - bool resizeBuffer(); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayNode); diff --git a/Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.cpp b/Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.cpp index 8e9773c270c8a59f93b835915fba22f70115ffd0..1562df5ce2e1c274d8554625135407932210f5ac 100755 --- a/Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.cpp +++ b/Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.cpp @@ -119,7 +119,7 @@ void LfpTriggeredAverageNode::setParameter(int parameterIndex, float newValue) ed->canvas->setParameter(parameterIndex, newValue); } -void LfpTriggeredAverageNode::handleEvent(int eventType, MidiMessage& event, int sampleNum) +void LfpTriggeredAverageNode::handleEvent(int eventType, MidiMessage& event) { if (eventType == TTL) { @@ -264,12 +264,14 @@ void LfpTriggeredAverageNode::initializeEventChannel() } } -void LfpTriggeredAverageNode::process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples) +void LfpTriggeredAverageNode::process(AudioSampleBuffer& buffer, MidiBuffer& events) { // 1. place any new samples into the displayBuffer //std::cout << "Display node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl; - totalSamples = nSamples; + int nSamples = 100; + + totalSamples = nSamples; //nSamples; displayBufferIndexEvents = displayBufferIndex; initializeEventChannel(); diff --git a/Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.h b/Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.h index 413a1732323a19eb5933ad34c0cc1a17e83fa6cb..3614c1ce4de0e5f5316cb6a22608063f735f7ca4 100755 --- a/Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.h +++ b/Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.h @@ -54,7 +54,7 @@ public: return true; } - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int, float); @@ -63,7 +63,7 @@ public: bool enable(); bool disable(); - void handleEvent(int, MidiMessage&, int); + void handleEvent(int, MidiMessage&); AudioSampleBuffer* getDisplayBufferAddress() { diff --git a/Source/Processors/Merger/Merger.cpp b/Source/Processors/Merger/Merger.cpp index 40ec6bc5439f0515bde717b2c5fdfcf073c02002..464d64a442fe25b0d67dcd1af98024e777dcb0e5 100755 --- a/Source/Processors/Merger/Merger.cpp +++ b/Source/Processors/Merger/Merger.cpp @@ -178,11 +178,11 @@ void Merger::updateSettings() { settings.sampleRate = getDefaultSampleRate(); - settings.numOutputs = getDefaultNumOutputs(); + settings.numOutputs = getNumHeadstageOutputs(); for (int i = 0; i < getNumOutputs(); i++) { - Channel* ch = new Channel(this, i); + Channel* ch = new Channel(this, i, HEADSTAGE_CHANNEL); ch->sampleRate = getDefaultSampleRate(); ch->bitVolts = getDefaultBitVolts(); diff --git a/Source/Processors/Merger/Merger.h b/Source/Processors/Merger/Merger.h index 90699a154da90ffb9e21f928939ba030a346e7a8..6c1bc679960948f4cce4e81b30656c9efe8f274c 100755 --- a/Source/Processors/Merger/Merger.h +++ b/Source/Processors/Merger/Merger.h @@ -52,7 +52,7 @@ public: AudioProcessorEditor* createEditor(); /** Nothing happens here, because Mergers are not part of the ProcessorGraph. */ - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples) {} + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages) {} bool isMerger() { diff --git a/Source/Processors/MessageCenter/MessageCenter.cpp b/Source/Processors/MessageCenter/MessageCenter.cpp index e07812744df37e0146153048db9617614c5649a8..30c7615b6b9708591a24fd09434b510c92cf0cb3 100644 --- a/Source/Processors/MessageCenter/MessageCenter.cpp +++ b/Source/Processors/MessageCenter/MessageCenter.cpp @@ -27,7 +27,7 @@ //--------------------------------------------------------------------- MessageCenter::MessageCenter() : - GenericProcessor("Message Center"), newEventAvailable(false), isRecording(false) + GenericProcessor("Message Center"), newEventAvailable(false), isRecording(false), sourceNodeId(0) { setPlayConfigDetails(0, // number of inputs @@ -65,27 +65,54 @@ void MessageCenter::setParameter(int parameterIndex, float newValue) } -void MessageCenter::process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer, int& nSamples) +void MessageCenter::setSourceNodeId(int id) +{ + sourceNodeId = id; +} + +int MessageCenter::getSourceNodeId() +{ + return sourceNodeId; +} + +void MessageCenter::process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer) { if (newEventAvailable) { int numBytes = 0; - + String eventString = messageCenterEditor->getLabelString(); CharPointer_UTF8 data = eventString.toUTF8(); + int realId = getNodeId(); + + //Fake node ID to the specified source for the event timestamps + if (sourceNodeId > 0) + setNodeId(sourceNodeId); addEvent(eventBuffer, - MESSAGE, - 0, - 0, - 0, - data.length()+1, //It doesn't hurt to send the end-string null and can help avoid issues - (uint8*) data.getAddress()); + MESSAGE, + 0, + 0, + 0, + data.length()+1, //It doesn't hurt to send the end-string null and can help avoid issues + (uint8*) data.getAddress()); + + setNodeId(realId); newEventAvailable = false; } - + } + +void MessageCenter::addSourceProcessor(GenericProcessor* p) +{ + messageCenterEditor->addSourceProcessor(p); +} + +void MessageCenter::removeSourceProcessor(GenericProcessor* p) +{ + messageCenterEditor->removeSourceProcessor(p); +} \ No newline at end of file diff --git a/Source/Processors/MessageCenter/MessageCenter.h b/Source/Processors/MessageCenter/MessageCenter.h index ec4218ce6ef12ddf33c8520d076197b1c06b47ac..82b9a11c59b1832d5ad3114fc3e7916cc4c6c7dd 100644 --- a/Source/Processors/MessageCenter/MessageCenter.h +++ b/Source/Processors/MessageCenter/MessageCenter.h @@ -50,7 +50,7 @@ public: ~MessageCenter(); /** Handle incoming data and decide which files and events to write to disk. */ - void process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer); /** Called when new events arrive. */ void setParameter(int parameterIndex, float newValue); @@ -61,8 +61,20 @@ public: /** A pointer to the Message Center editor. */ ScopedPointer<MessageCenterEditor> messageCenterEditor; - void startRecording() {isRecording = true;} - void stopRecording() {isRecording = false;} + void startRecording() + { + isRecording = true; + } + void stopRecording() + { + isRecording = false; + } + + void setSourceNodeId(int id); + int getSourceNodeId(); + + void addSourceProcessor(GenericProcessor* p); + void removeSourceProcessor(GenericProcessor* p); private: @@ -70,6 +82,8 @@ private: bool isRecording; + int sourceNodeId; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MessageCenter); }; diff --git a/Source/Processors/MessageCenter/MessageCenterEditor.cpp b/Source/Processors/MessageCenter/MessageCenterEditor.cpp index ab457e9906e0b7919189bf3ff7498e3f3bc6ca0d..ae76f9b37c9115186c498506c6009f33ae9e57bb 100644 --- a/Source/Processors/MessageCenter/MessageCenterEditor.cpp +++ b/Source/Processors/MessageCenter/MessageCenterEditor.cpp @@ -24,14 +24,14 @@ #include "MessageCenterEditor.h" MessageCenterEditor::MessageCenterEditor(MessageCenter* owner) : - AudioProcessorEditor(owner), - messageCenter(owner), + AudioProcessorEditor(owner), + messageCenter(owner), incomingBackground(100, 100, 100), outgoingBackground(100, 100, 100) { - incomingMessageDisplayArea = new Label("Message Display Area","No new messages."); - outgoingMessageDisplayArea = new Label("Message Display Area","Type a new message here."); + incomingMessageDisplayArea = new MessageLabel("Message Display Area","No new messages."); + outgoingMessageDisplayArea = new MessageLabel("Message Display Area","Type a new message here."); outgoingMessageDisplayArea->setEditable(true); addAndMakeVisible(incomingMessageDisplayArea); @@ -42,6 +42,8 @@ MessageCenterEditor::MessageCenterEditor(MessageCenter* owner) : sendMessageButton->setTooltip("Send a message to be saved by the record node"); addAndMakeVisible(sendMessageButton); + sourceMenu = new PopupMenu(); + } MessageCenterEditor::~MessageCenterEditor() @@ -52,7 +54,7 @@ MessageCenterEditor::~MessageCenterEditor() void MessageCenterEditor::buttonClicked(Button* button) { - messageCenter->setParameter(1,1); + messageCenter->setParameter(1,1); } @@ -64,62 +66,64 @@ void MessageCenterEditor::labelTextChanged(Label* label) void MessageCenterEditor::timerCallback() { - bool shouldRepaint = false; + bool shouldRepaint = false; - float incomingAlpha = incomingBackground.getFloatAlpha(); + float incomingAlpha = incomingBackground.getFloatAlpha(); - if (incomingAlpha > 0) - { - incomingAlpha -= 0.05; + if (incomingAlpha > 0) + { + incomingAlpha -= 0.05; - if (incomingAlpha < 0) - incomingAlpha = 0; + if (incomingAlpha < 0) + incomingAlpha = 0; - incomingBackground = incomingBackground.withAlpha(incomingAlpha); + incomingBackground = incomingBackground.withAlpha(incomingAlpha); - shouldRepaint = true; - } + shouldRepaint = true; + } - if (shouldRepaint) - repaint(); - else - stopTimer(); + if (shouldRepaint) + repaint(); + else + stopTimer(); } bool MessageCenterEditor::keyPressed(const KeyPress& key) { - return false; + return false; } String MessageCenterEditor::getLabelString() { - return outgoingMessageDisplayArea->getText(); + return outgoingMessageDisplayArea->getText(); } void MessageCenterEditor::enable() { - //sendMessageButton->setVisible(true); + //sendMessageButton->setVisible(true); } void MessageCenterEditor::disable() { - //sendMessageButton->setVisible(false); + //sendMessageButton->setVisible(false); } void MessageCenterEditor::messageReceived(bool state) { - if (!state) - { - incomingMessageDisplayArea->setText("Cannot save messages when recording is not active.", sendNotification); - incomingBackground = Colours::red; - } else { - incomingMessageDisplayArea->setText("Message sent.", sendNotification); - incomingBackground = Colours::green; - } + if (!state) + { + incomingMessageDisplayArea->setText("Cannot save messages when recording is not active.", sendNotification); + incomingBackground = Colours::red; + } + else + { + incomingMessageDisplayArea->setText("Message sent.", sendNotification); + incomingBackground = Colours::green; + } - startTimer(75); + startTimer(75); } void MessageCenterEditor::paint(Graphics& g) @@ -168,10 +172,70 @@ void MessageCenterEditor::actionListenerCallback(const String& message) void MessageCenterEditor::saveStateToXml(XmlElement* xml) { - + XmlElement* messageEditorState = xml->createNewChildElement("MESSAGECENTER"); + messageEditorState->setAttribute("sourceNodeId",messageCenter->getSourceNodeId()); } void MessageCenterEditor::loadStateFromXml(XmlElement* xml) { + forEachXmlChildElement(*xml, xmlNode) + { + if (xmlNode->hasTagName("MESSAGECENTER")) + { + messageCenter->setSourceNodeId(xmlNode->getIntAttribute("sourceNodeId")); + } + } +} +void MessageCenterEditor::addSourceProcessor(GenericProcessor* p) +{ + sourcesList.add(p); +} + +void MessageCenterEditor::removeSourceProcessor(GenericProcessor* p) +{ + sourcesList.removeAllInstancesOf(p); +} + +void MessageCenterEditor::mouseDown(const MouseEvent& event) +{ + int res; + if (event.mods.isPopupMenu()) + { + PopupMenu::dismissAllActiveMenus(); + sourceMenu->clear(); + if (sourcesList.size() > 0) + { + for (int i=0; i < sourcesList.size(); i++) + { + GenericProcessor* p = sourcesList[i]; + sourceMenu->addItem(i+1,p->getName(),true,(p->nodeId == messageCenter->getSourceNodeId())); + } + } + else + { + sourceMenu->addItem(-1,"No sources",false,false); + } + res = sourceMenu->show(0,50,0,0); + + if (res > 0) + { + GenericProcessor* p = sourcesList[res-1]; + std::cout << "Selecting " << p->getName() << " with id " << p->nodeId << " as message source" << std::endl; + messageCenter->setSourceNodeId(p->nodeId); + } + } +} + +MessageLabel::MessageLabel(const String& componentName, const String& labelText) + : Label(componentName,labelText) +{ +} + +void MessageLabel::mouseDown(const MouseEvent& event) +{ + if (event.mods.isPopupMenu()) + { + getParentComponent()->mouseDown(event.getEventRelativeTo(getParentComponent())); + } } diff --git a/Source/Processors/MessageCenter/MessageCenterEditor.h b/Source/Processors/MessageCenter/MessageCenterEditor.h index 81df70a72fedf4335398efbfb9df21ff35b75ace..800a14c899d98df9a3dd7608f4767c293d3cb5b4 100644 --- a/Source/Processors/MessageCenter/MessageCenterEditor.h +++ b/Source/Processors/MessageCenter/MessageCenterEditor.h @@ -28,6 +28,8 @@ #include "MessageCenter.h" #include <stdio.h> +class MessageLabel; + /** Holds the interface for adding events to the message queue @@ -61,8 +63,13 @@ public: void saveStateToXml(XmlElement* xml); void loadStateFromXml(XmlElement* xml); + void addSourceProcessor(GenericProcessor* p); + void removeSourceProcessor(GenericProcessor* p); + String getLabelString(); + void mouseDown(const MouseEvent& event); + private: void buttonClicked(Button* button); @@ -75,14 +82,17 @@ private: void actionListenerCallback(const String& message); /** A JUCE label used to display message text. */ - ScopedPointer<Label> incomingMessageDisplayArea; + ScopedPointer<MessageLabel> incomingMessageDisplayArea; /** A JUCE label used to display message text. */ - ScopedPointer<Label> outgoingMessageDisplayArea; + ScopedPointer<MessageLabel> outgoingMessageDisplayArea; /** A JUCE button used to send messages. */ ScopedPointer<Button> sendMessageButton; + ScopedPointer<PopupMenu> sourceMenu; + Array<GenericProcessor*> sourcesList; + MessageCenter* messageCenter; Colour incomingBackground; @@ -92,6 +102,11 @@ private: }; - +class MessageLabel : public Label +{ +public: + MessageLabel(const String& componentName=String::empty, const String& labelText=String::empty); + void mouseDown(const MouseEvent& event); +}; #endif // MESSAGECENTEREDITOR_H_INCLUDED diff --git a/Source/Processors/NetworkEvents/NetworkEvents.cpp b/Source/Processors/NetworkEvents/NetworkEvents.cpp index ba1e1c09ae2cd65d99ecb47df43f83e2b4309de9..0e04c91e22887ddab7fe685dd48fe76749c61f64 100644 --- a/Source/Processors/NetworkEvents/NetworkEvents.cpp +++ b/Source/Processors/NetworkEvents/NetworkEvents.cpp @@ -269,7 +269,7 @@ void NetworkEvents::postTimestamppedStringToMidiBuffer(StringTS s, MidiBuffer& e (uint8) NETWORK, 0, 0, - (uint8) GENERIC_EVENT, + 0, (uint8) s.len+8, msg_with_ts); @@ -380,8 +380,7 @@ String NetworkEvents::handleSpecialMessages(StringTS msg) } void NetworkEvents::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { //std::cout << "NETWORK NODE" << std::endl; @@ -399,8 +398,7 @@ void NetworkEvents::process(AudioSampleBuffer& buffer, networkMessagesQueue.pop(); } lock.exit(); - nSamples = -10; // make sure this is not processed; - //printf("Exitting NetworkEvents::process\n"); + } diff --git a/Source/Processors/NetworkEvents/NetworkEvents.h b/Source/Processors/NetworkEvents/NetworkEvents.h index 6dc9c4ac0cf8cd855c4d04fdd2e2f52f42a8e06f..0609d5d1bfaf93469d24b6933f10a297672e73b0 100644 --- a/Source/Processors/NetworkEvents/NetworkEvents.h +++ b/Source/Processors/NetworkEvents/NetworkEvents.h @@ -74,7 +74,7 @@ public: int64 getExtrapolatedHardwareTimestamp(int64 softwareTS); void initSimulation(); void simulateDesignAndTrials(juce::MidiBuffer& events); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); String handleSpecialMessages(StringTS msg); std::vector<String> splitString(String S, char sep); diff --git a/Source/Processors/PSTH/PeriStimulusTimeHistogramNode.cpp b/Source/Processors/PSTH/PeriStimulusTimeHistogramNode.cpp index 9fa3ecda7a50c086c5f7c7a56acc0932da381a96..b4659e074b5e3d89f8ecb3f209facc77b0cea0d5 100644 --- a/Source/Processors/PSTH/PeriStimulusTimeHistogramNode.cpp +++ b/Source/Processors/PSTH/PeriStimulusTimeHistogramNode.cpp @@ -126,7 +126,10 @@ void PeriStimulusTimeHistogramNode::updateSettings() // diskWriteLock = recordNode->getLock(); } - +void PeriStimulusTimeHistogramNode::setHardwareTriggerAlignmentChannel(int chan) +{ + trialCircularBuffer->setHardwareTriggerAlignmentChannel(chan); +} bool PeriStimulusTimeHistogramNode::enable() { @@ -157,7 +160,7 @@ void PeriStimulusTimeHistogramNode::toggleConditionVisibility(int cond) } } -void PeriStimulusTimeHistogramNode::process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples) +void PeriStimulusTimeHistogramNode::process(AudioSampleBuffer& buffer, MidiBuffer& events) { //printf("Entering PeriStimulusTimeHistogramNode::process\n"); // Update internal statistics @@ -169,7 +172,7 @@ void PeriStimulusTimeHistogramNode::process(AudioSampleBuffer& buffer, MidiBuffe syncInternalDataStructuresWithSpikeSorter(); } else if (trialCircularBuffer != nullptr) { - trialCircularBuffer->process(buffer,nSamples,hardware_timestamp,software_timestamp); + trialCircularBuffer->process(buffer,getNumSamples(0),hardware_timestamp,software_timestamp); } @@ -464,16 +467,20 @@ void PeriStimulusTimeHistogramNode::handleEvent(int eventType, MidiMessage& even } if (eventType == TTL) { - const uint8* dataptr = event.getRawData(); - bool ttl_raise = dataptr[2] > 0; - int channel = dataptr[3]; - int64 ttl_timestamp_software,ttl_timestamp_hardware; - memcpy(&ttl_timestamp_software, dataptr+4, 8); - memcpy(&ttl_timestamp_hardware, dataptr+12, 8); - if (ttl_raise) - trialCircularBuffer->addTTLevent(channel,ttl_timestamp_software,ttl_timestamp_hardware, ttl_raise, true); - if (isRecording && saveTTLs) - dumpTTLeventToDisk(channel,ttl_raise,ttl_timestamp_software,ttl_timestamp_hardware,samplePosition ); + Time t; + const uint8* dataptr = event.getRawData(); + int ttl_source = dataptr[1]; + bool ttl_raise = dataptr[2] > 0; + int channel = dataptr[3]; + int64 ttl_timestamp_hardware = timestamps[ttl_source] + samplePosition; // hardware time + int64 ttl_timestamp_software = t.getHighResolutionTicks(); // get software time + //int64 ttl_timestamp_software,ttl_timestamp_hardware; + //memcpy(&ttl_timestamp_software, dataptr+4, 8); + //memcpy(&ttl_timestamp_hardware, dataptr+12, 8); + if (ttl_raise) + trialCircularBuffer->addTTLevent(channel,ttl_timestamp_software,ttl_timestamp_hardware, ttl_raise, true); + if (isRecording && saveTTLs) + dumpTTLeventToDisk(channel,ttl_raise,ttl_timestamp_software,ttl_timestamp_hardware,samplePosition ); } if (eventType == SPIKE) @@ -534,7 +541,7 @@ String PeriStimulusTimeHistogramNode::generateHeader() header += "header.bitVolts = "; if (recordNode->channels.size() > 0) { - header += String(recordNode->channels[0]->getChannelGain()); + header += String(recordNode->channels[0]->bitVolts); } else { diff --git a/Source/Processors/PSTH/PeriStimulusTimeHistogramNode.h b/Source/Processors/PSTH/PeriStimulusTimeHistogramNode.h index 72bd2e016825f4711dd5f70d1ffc1610e8cdfbae..f5c3fdc8e46517fd0077bd781e5f57e0b3afdc82 100644 --- a/Source/Processors/PSTH/PeriStimulusTimeHistogramNode.h +++ b/Source/Processors/PSTH/PeriStimulusTimeHistogramNode.h @@ -39,8 +39,6 @@ class DataViewport; class SpikePlot; class TrialCircularBuffer; - - class PeriStimulusTimeHistogramNode : public GenericProcessor { public: @@ -57,11 +55,10 @@ public: return true; } - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void syncInternalDataStructuresWithSpikeSorter(); - void allocateTrialCircularBuffer(); void handleEvent(int, MidiMessage&, int); @@ -87,6 +84,8 @@ public: bool saveTTLs, saveNetworkEvents,saveEyeTracking ; int spikeSavingMode; bool saveNetworkEventsWhenNotRecording; + + void setHardwareTriggerAlignmentChannel(int chan); void handleNetworkMessage(StringTS s); private: @@ -106,7 +105,7 @@ private: int displayBufferSize; bool redrawRequested; int syncCounter; - int64 hardware_timestamp,software_timestamp; + int64 hardware_timestamp, software_timestamp; std::queue<StringTS> networkEventsHistory; RecordNode* recordNode; diff --git a/Source/Processors/PSTH/TrialCircularBuffer.cpp b/Source/Processors/PSTH/TrialCircularBuffer.cpp index 897f7e469fc79f97e7035b3cd47a4cf108f13089..1a14799b9f1a56f6f4c25c17636edb6453981373 100644 --- a/Source/Processors/PSTH/TrialCircularBuffer.cpp +++ b/Source/Processors/PSTH/TrialCircularBuffer.cpp @@ -57,7 +57,6 @@ void setDefaultColors(uint8 &R, uint8 &G, uint8 &B, int ID) {52, 73, 94}, {230, 126, 34}, {231, 76, 60}, - //{22, 160, 133}, {255, 0, 0}, {39, 174, 96}, {41, 128, 185}, @@ -66,24 +65,22 @@ void setDefaultColors(uint8 &R, uint8 &G, uint8 &B, int ID) {243, 156, 18}, {211, 84, 0}, {192, 57, 43}, - - {224,185,36}, - {214,210,182}, - {243,119,33}, - {186,157,168}, - {237,37,36}, - {179,122,79}, - {217,46,171}, - {217, 139,196}, - {101,31,255}, - {141,111,181}, - {48,117,255}, - {184,198,224}, - {116,227,156}, - {150,158,155}, - {82,173,0}, - {125,99,32}}; - + {224,185,36}, + {214,210,182}, + {243,119,33}, + {186,157,168}, + {237,37,36}, + {179,122,79}, + {217,46,171}, + {217, 139,196}, + {101,31,255}, + {141,111,181}, + {48,117,255}, + {184,198,224}, + {116,227,156}, + {150,158,155}, + {82,173,0}, + {125,99,32}}; /* { 0, 0, 255}, @@ -101,7 +98,7 @@ void setDefaultColors(uint8 &R, uint8 &G, uint8 &B, int ID) /******************************/ -PSTH::PSTH(int ID, TrialCircularBufferParams params_,bool vis) : conditionID(ID),params(params_),numTrials(0),visible(vis) +PSTH::PSTH(int ID, TrialCircularBufferParams params_, bool vis) : conditionID(ID),params(params_),numTrials(0),visible(vis) { // if approximate is on, we won't sample exactly xmin and xmax if (params.approximate) @@ -1355,14 +1352,15 @@ std::vector<int64> SmartSpikeCircularBuffer::getAlignedSpikes(Trial *trial, floa TrialCircularBuffer::~TrialCircularBuffer() { - delete lfpBuffer; - lfpBuffer = nullptr; - delete ttlBuffer; - ttlBuffer = nullptr; + //delete lfpBuffer; + //lfpBuffer = nullptr; + //delete ttlBuffer; + //ttlBuffer = nullptr; electrodesPSTH.clear(); - delete threadpool; - threadpool = nullptr; + //delete threadpool; + //threadpool = nullptr; } + TrialCircularBuffer::TrialCircularBuffer() { lfpBuffer = ttlBuffer = nullptr; @@ -1374,6 +1372,38 @@ TrialCircularBuffer::TrialCircularBuffer() useThreads = true; } +TrialCircularBuffer::TrialCircularBuffer(TrialCircularBufferParams params_) : params(params_) +{ + Time t; + numTicksPerSecond = t.getHighResolutionTicksPerSecond(); + useThreads = false; + conditionCounter = 0; + firstTime = true; + trialCounter = 0; + lastSimulatedTrialTS = 0; + lastTrialID = 0; + hardwareTriggerAlignmentChannel = -1; + uniqueIntervalID = 0; + // sampling them should be at least 600 Hz (Nyquist!) + // We typically sample everything at 30000, so a sub-sampling by a factor of 50 should be good + int subSample = params.sampleRate/ params.desiredSamplingRateHz; + float numSeconds = 2*(params.maxTrialTimeSeconds+params.preSec+params.postSec); + lfpBuffer = new SmartContinuousCircularBuffer(params.numChannels, params.sampleRate, subSample, numSeconds); + ttlBuffer = new SmartContinuousCircularBuffer(params.numTTLchannels, params.sampleRate, subSample, numSeconds); + lastTTLts.resize(params.numTTLchannels); + ttlChannelStatus.resize(params.numTTLchannels); + for (int k=0;k<params.numTTLchannels;k++) { + ttlChannelStatus[k] = false; + lastTTLts[k] = 0; + } + int numCpus = SystemStats::getNumCpus(); + // create a thead pool to analyze incoming trials + if (useThreads) + threadpool = new ThreadPool(numCpus); + + clearDesign(); +} + void TrialCircularBuffer::getLastTrial(int electrodeIndex, int channelIndex, int conditionIndex, float &x0, float &dx, std::vector<float> &y) { const ScopedLock myScopedLock (psthMutex); @@ -1452,37 +1482,6 @@ void TrialCircularBuffer::setHardwareTriggerAlignmentChannel(int k) hardwareTriggerAlignmentChannel = k; } -TrialCircularBuffer::TrialCircularBuffer(TrialCircularBufferParams params_) : params(params_) -{ - Time t; - numTicksPerSecond = t.getHighResolutionTicksPerSecond(); - useThreads = true; - conditionCounter = 0; - firstTime = true; - trialCounter = 0; - lastSimulatedTrialTS = 0; - lastTrialID = 0; - hardwareTriggerAlignmentChannel = -1; - uniqueIntervalID = 0; - // sampling them should be at least 600 Hz (Nyquist!) - // We typically sample everything at 30000, so a sub-sampling by a factor of 50 should be good - int subSample = params.sampleRate/ params.desiredSamplingRateHz; - float numSeconds = 2*(params.maxTrialTimeSeconds+params.preSec+params.postSec); - lfpBuffer = new SmartContinuousCircularBuffer(params.numChannels, params.sampleRate, subSample, numSeconds); - ttlBuffer = new SmartContinuousCircularBuffer(params.numTTLchannels, params.sampleRate, subSample, numSeconds); - lastTTLts.resize(params.numTTLchannels); - ttlChannelStatus.resize(params.numTTLchannels); - for (int k=0;k<params.numTTLchannels;k++) { - ttlChannelStatus[k] = false; - lastTTLts[k] = 0; - } - int numCpus = SystemStats::getNumCpus(); - // create a thead pool to analyze incoming trials - threadpool = new ThreadPool(numCpus); - clearDesign(); -} - - /* @@ -1514,6 +1513,7 @@ void TrialCircularBuffer::addDefaultTTLConditions(Array<bool> visibility) for (int channel = 0; channel < params.numTTLchannels; channel++) { StringTS simulatedConditionString; + if (visibility[channel]) simulatedConditionString = StringTS("addcondition name ttl"+String(channel+1)+" trialtypes "+String(TTL_TRIAL_OFFSET+channel)+" visible 1"); else @@ -1551,7 +1551,7 @@ void TrialCircularBuffer::clearAll() { const ScopedLock myScopedLock (psthMutex); //lockPSTH(); - for (int i=0;i<electrodesPSTH.size();i++) + for (int i = 0; i < electrodesPSTH.size(); i++) { for (int ch=0;ch<electrodesPSTH[i].channelsPSTHs.size();ch++) { @@ -1632,15 +1632,16 @@ void TrialCircularBuffer::modifyConditionVisibility(int cond, bool newstate) // lockPSTH(); conditions[cond].visible = newstate; - for (int i=0;i<electrodesPSTH.size();i++) + + for (int i = 0; i < electrodesPSTH.size(); i++) { - for (int ch=0;ch<electrodesPSTH[i].channelsPSTHs.size();ch++) + for (int ch = 0; ch < electrodesPSTH[i].channelsPSTHs.size(); ch++) { electrodesPSTH[i].channelsPSTHs[ch].conditionPSTHs[cond].visible = newstate; electrodesPSTH[i].channelsPSTHs[ch].redrawNeeded = true; } - for (int u=0;u<electrodesPSTH[i].unitsPSTHs.size();u++) + for (int u = 0; u < electrodesPSTH[i].unitsPSTHs.size(); u++) { electrodesPSTH[i].unitsPSTHs[u].conditionPSTHs[cond].visible = newstate; electrodesPSTH[i].unitsPSTHs[u].redrawNeeded = true; @@ -1656,6 +1657,7 @@ void TrialCircularBuffer::toggleConditionVisibility(int cond) //lockPSTH(); conditions[cond].visible = !conditions[cond].visible; + for (int i=0;i<electrodesPSTH.size();i++) { for (int ch=0;ch<electrodesPSTH[i].channelsPSTHs.size();ch++) @@ -1708,13 +1710,14 @@ void TrialCircularBuffer::syncInternalDataStructuresWithSpikeSorter(Array<Electr //lockConditions(); // note. This will erase all existing internal structures. Only call this in the constructor. electrodesPSTH.clear(); - for (int electrodeIter=0;electrodeIter<electrodes.size();electrodeIter++) + + for (int electrodeIter = 0; electrodeIter < electrodes.size(); electrodeIter++) { ElectrodePSTH electrodePSTH(electrodes[electrodeIter]->electrodeID,electrodes[electrodeIter]->name); int numChannels = electrodes[electrodeIter]->numChannels; - for (int k=0;k<numChannels;k++) { + for (int k = 0; k < numChannels; k++) { int channelID = electrodes[electrodeIter]->channels[k]; electrodePSTH.channels.push_back(channelID); ChannelPSTHs channelPSTH(channelID,params); @@ -1729,7 +1732,7 @@ void TrialCircularBuffer::syncInternalDataStructuresWithSpikeSorter(Array<Electr // add all known units std::vector<BoxUnit> boxUnits = electrodes[electrodeIter]->spikeSort->getBoxUnits(); std::vector<PCAUnit> pcaUnits = electrodes[electrodeIter]->spikeSort->getPCAUnits(); - for (int boxIter=0;boxIter<boxUnits.size();boxIter++) + for (int boxIter = 0; boxIter < boxUnits.size(); boxIter++) { int unitID = boxUnits[boxIter].UnitID; @@ -1742,13 +1745,13 @@ void TrialCircularBuffer::syncInternalDataStructuresWithSpikeSorter(Array<Electr electrodePSTH.unitsPSTHs.push_back(unitPSTHs); } - for (int pcaIter=0;pcaIter<pcaUnits.size();pcaIter++) + for (int pcaIter = 0; pcaIter < pcaUnits.size(); pcaIter++) { int unitID = pcaUnits[pcaIter].UnitID; UnitPSTHs unitPSTHs(unitID, params,pcaUnits[pcaIter].ColorRGB[0], pcaUnits[pcaIter].ColorRGB[1],pcaUnits[pcaIter].ColorRGB[2]); - for (int k=0;k<conditions.size();k++) + for (int k = 0; k < conditions.size(); k++) { unitPSTHs.conditionPSTHs.push_back(PSTH(conditions[k].conditionID, params,conditions[k].visible)); } @@ -1768,7 +1771,7 @@ void TrialCircularBuffer::addNewElectrode(Electrode *electrode) ElectrodePSTH e(electrode->electrodeID,electrode->name); int numChannels = electrode->numChannels; - for (int k=0;k<numChannels;k++) + for (int k = 0; k < numChannels; k++) { int channelID = electrode->channels[k]; e.channels.push_back(channelID); @@ -1782,17 +1785,16 @@ void TrialCircularBuffer::addNewElectrode(Electrode *electrode) } electrodesPSTH.push_back(e); - // Usually when we add a new electrode it doesn't have any units, unless it was added when loading an xml... if (electrode->spikeSort != nullptr) { std::vector<BoxUnit> boxUnits = electrode->spikeSort->getBoxUnits(); - for (int boxIter=0;boxIter < boxUnits.size();boxIter++) + for (int boxIter = 0; boxIter < boxUnits.size(); boxIter++) { addNewUnit(electrode->electrodeID, boxUnits[boxIter].UnitID, boxUnits[boxIter].ColorRGB[0],boxUnits[boxIter].ColorRGB[1],boxUnits[boxIter].ColorRGB[2]); } std::vector<PCAUnit> PcaUnits = electrode->spikeSort->getPCAUnits(); - for (int pcaIter=0;pcaIter < PcaUnits.size();pcaIter++) + for (int pcaIter = 0; pcaIter < PcaUnits.size(); pcaIter++) { addNewUnit(electrode->electrodeID, PcaUnits[pcaIter].UnitID, PcaUnits[pcaIter].ColorRGB[0],PcaUnits[pcaIter].ColorRGB[1],PcaUnits[pcaIter].ColorRGB[2]); } @@ -1804,14 +1806,14 @@ void TrialCircularBuffer::addNewUnit(int electrodeID, int unitID, uint8 r,uint8 { // build a new PSTH for all defined conditions //lockPSTH(); - const ScopedLock myScopedLock (psthMutex); + const ScopedLock myScopedLock (psthMutex); UnitPSTHs unitPSTHs(unitID, params,r,g,b); - for (int k=0;k<conditions.size();k++) + for (int k = 0; k < conditions.size(); k++) { unitPSTHs.conditionPSTHs.push_back(PSTH(conditions[k].conditionID, params,conditions[k].visible)); } - for (int k=0;k<electrodesPSTH.size();k++) { + for (int k = 0; k < electrodesPSTH.size(); k++) { if (electrodesPSTH[k].electrodeID == electrodeID) { electrodesPSTH[k].unitsPSTHs.push_back(unitPSTHs); break; @@ -1824,7 +1826,7 @@ void TrialCircularBuffer::addNewUnit(int electrodeID, int unitID, uint8 r,uint8 void TrialCircularBuffer::removeUnit(int electrodeID, int unitID) { //lockPSTH(); - const ScopedLock myScopedLock (psthMutex); + const ScopedLock myScopedLock (psthMutex); for (int e =0;e<electrodesPSTH.size();e++) { @@ -1873,8 +1875,6 @@ void TrialCircularBuffer::removeElectrode(int electrodeID) // unlockPSTH(); } - - bool TrialCircularBuffer::parseMessage(StringTS msg) { bool redrawNeeded = false; @@ -1900,6 +1900,9 @@ bool TrialCircularBuffer::parseMessage(StringTS msg) if (command == "trialstart") { + + std::cout << "Got start of trial!" << std::endl; + currentTrial.trialID = ++trialCounter; currentTrial.startTS = msg.timestamp; currentTrial.alignTS = 0; @@ -1913,7 +1916,7 @@ bool TrialCircularBuffer::parseMessage(StringTS msg) const ScopedLock myScopedLock (psthMutex); //lockPSTH(); - for (int i=0;i<electrodesPSTH.size();i++) + for (int i = 0; i < electrodesPSTH.size(); i++) { for (int u=0;u<electrodesPSTH[i].unitsPSTHs.size();u++) { @@ -1927,7 +1930,7 @@ bool TrialCircularBuffer::parseMessage(StringTS msg) } else if (command == "dropoutcomes") { dropOutcomes.clear(); - for (int k=1;k<input.size();k++) + for (int k = 1; k < input.size(); k++) { dropOutcomes.push_back(input[k].getIntValue()); } @@ -2002,14 +2005,14 @@ bool TrialCircularBuffer::parseMessage(StringTS msg) //unlockConditions(); // now add a new psth for this condition for all sorted units on all electrodes //lockPSTH(); - for (int i=0;i<electrodesPSTH.size();i++) + for (int i = 0; i < electrodesPSTH.size(); i++) { - for (int ch=0;ch<electrodesPSTH[i].channelsPSTHs.size();ch++) + for (int ch = 0; ch < electrodesPSTH[i].channelsPSTHs.size(); ch++) { electrodesPSTH[i].channelsPSTHs[ch].conditionPSTHs.push_back(PSTH(newcondition.conditionID, params, newcondition.visible)); } - for (int u=0;u<electrodesPSTH[i].unitsPSTHs.size();u++) + for (int u = 0; u < electrodesPSTH[i].unitsPSTHs.size(); u++) { electrodesPSTH[i].unitsPSTHs[u].conditionPSTHs.push_back(PSTH(newcondition.conditionID, params, newcondition.visible)); } @@ -2020,17 +2023,18 @@ bool TrialCircularBuffer::parseMessage(StringTS msg) } return redrawNeeded ; - } +} void TrialCircularBuffer::addSpikeToSpikeBuffer(SpikeObject newSpike) { //lockPSTH(); const ScopedLock myScopedLock (psthMutex); - for (int e=0;e<electrodesPSTH.size();e++) + + for (int e = 0; e < electrodesPSTH.size(); e++) { if (electrodesPSTH[e].electrodeID == newSpike.electrodeID) { - for (int u=0;u<electrodesPSTH[e].unitsPSTHs.size();u++) + for (int u = 0; u < electrodesPSTH[e].unitsPSTHs.size(); u++) { if (electrodesPSTH[e].unitsPSTHs[u].unitID == newSpike.sortedId) { @@ -2049,7 +2053,7 @@ void TrialCircularBuffer::addSpikeToSpikeBuffer(SpikeObject newSpike) bool TrialCircularBuffer::contains(std::vector<int> v, int x) { - for (int k=0;k<v.size();k++) + for (int k = 0; k < v.size(); k++) if (v[k] == x) return true; return false; @@ -2099,7 +2103,7 @@ void TrialCircularBuffer::updatePSTHwithTrial(Trial *trial) if (!useThreads) { // these two parts can be fully distributed along several threads because they are completely independent. - //printf("Calling updatePSTHwithTrial::update without streads\n"); + //printf("Calling updatePSTHwithTrial::update without threads\n"); tictoc.Tic(23); for (int i=0;i<electrodesPSTH.size();i++) @@ -2115,7 +2119,7 @@ void TrialCircularBuffer::updatePSTHwithTrial(Trial *trial) } } tictoc.Toc(23); - //printf("Finished updatePSTHwithTrial::update without streads\n"); + //printf("Finished updatePSTHwithTrial::update without threads\n"); } else { tictoc.Tic(24); @@ -2123,7 +2127,7 @@ void TrialCircularBuffer::updatePSTHwithTrial(Trial *trial) int numElectrodes = electrodesPSTH.size(); //printf("Calling updatePSTHwithTrial::update with threads\n"); - for (int i=0;i<numElectrodes;i++) + for (int i = 0; i < numElectrodes; i++) { TrialCircularBufferThread *job = new TrialCircularBufferThread(this,&conditionsNeedUpdating,trial,cnt++,0,i,-1); threadpool->addJob(job, true); @@ -2199,9 +2203,13 @@ void TrialCircularBuffer::addTTLevent(int channel,int64 ttl_timestamp_software, // and only if its above some threshold, simulate a ttl trial. // this is useful when sending train of pulses and you are interested in aligning things just // to the first pulse. + + std::cout << "Got that TTL event" << std::endl; + if (channel >= 0 && channel < lastTTLts.size()) { - ttlBuffer->update(channel, ttl_timestamp_software, ttl_timestamp_hardware,rise); + ttlBuffer->update(channel, ttl_timestamp_software, ttl_timestamp_hardware, rise); + if (params.reconstructTTL) { ttlStatus tmp; @@ -2211,7 +2219,7 @@ void TrialCircularBuffer::addTTLevent(int channel,int64 ttl_timestamp_software, ttlQueue.push(tmp); } - if (simulateTrial) + if (simulateTrial) { int64 tickdiff = ttl_timestamp_software-lastTTLts[channel]; float secElapsed = float(tickdiff) / numTicksPerSecond; @@ -2224,7 +2232,9 @@ void TrialCircularBuffer::addTTLevent(int channel,int64 ttl_timestamp_software, if (channel == hardwareTriggerAlignmentChannel) { - currentTrial.alignTS = ttl_timestamp_software; + + std::cout << "TTL channel matches alignment channel!" << std::endl; + currentTrial.alignTS = ttl_timestamp_software; currentTrial.alignTS_hardware = ttl_timestamp_hardware; currentTrial.hardwareAlignment = true; } @@ -3141,17 +3151,19 @@ void TrialCircularBuffer::process(AudioSampleBuffer& buffer,int nSamples,int64 h tictoc.Tic(1); lfpBuffer->update(buffer, hardware_timestamp,software_timestamp, nSamples); tictoc.Toc(1); - //printf("Exitting lfpBuffer->update\n"); + //printf("Exiting lfpBuffer->update\n"); //printf("Entering reconstructedTTLs\n"); tictoc.Tic(2); - // for oscilloscope purposes, it is easier to reconstruct TTL chnages to "continuous" form. + + // for oscilloscope purposes, it is easier to reconstruct TTL changes to "continuous" form. if (params.reconstructTTL) { std::vector<std::vector<bool>> reconstructedTTLs = reconstructTTLchannels(hardware_timestamp,nSamples); ttlBuffer->update(reconstructedTTLs,hardware_timestamp,software_timestamp,nSamples); } tictoc.Toc(2); - //printf("Exitting reconstructedTTLs\n"); + + //printf("Exiting reconstructedTTLs\n"); // now, check if a trial finished, and enough time has elapsed so we also // have post trial information diff --git a/Source/Processors/PSTH/TrialCircularBuffer.h b/Source/Processors/PSTH/TrialCircularBuffer.h index 317d429b573fee160a6386a2b94037a784e5106b..b297ea307895d45124ca5905714e28d525573462 100644 --- a/Source/Processors/PSTH/TrialCircularBuffer.h +++ b/Source/Processors/PSTH/TrialCircularBuffer.h @@ -398,11 +398,11 @@ private: std::queue<Trial> aliveTrials; std::vector<Condition> conditions; std::vector<ElectrodePSTH> electrodesPSTH; - SmartContinuousCircularBuffer *lfpBuffer; - SmartContinuousCircularBuffer *ttlBuffer; + ScopedPointer<SmartContinuousCircularBuffer> lfpBuffer; + ScopedPointer<SmartContinuousCircularBuffer> ttlBuffer; std::queue<ttlStatus> ttlQueue; TrialCircularBufferParams params; - ThreadPool *threadpool; + ScopedPointer<ThreadPool> threadpool; }; class TrialCircularBufferThread : public ThreadPoolJob diff --git a/Source/Processors/PhaseDetector/PhaseDetector.cpp b/Source/Processors/PhaseDetector/PhaseDetector.cpp index 069b76454b3786709a8fc7b15cc3101eba0f510b..b8673fd45fb7d2c1c2aca843af7f2fecec1cb933 100644 --- a/Source/Processors/PhaseDetector/PhaseDetector.cpp +++ b/Source/Processors/PhaseDetector/PhaseDetector.cpp @@ -167,8 +167,7 @@ void PhaseDetector::handleEvent(int eventType, MidiMessage& event, int sampleNum } void PhaseDetector::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { checkForEvents(events); @@ -184,7 +183,7 @@ void PhaseDetector::process(AudioSampleBuffer& buffer, module.inputChan < buffer.getNumChannels()) { - for (int i = 0; i < nSamples; i++) + for (int i = 0; i < getNumSamples(channels[module.inputChan]->sourceNodeId); i++) { const float sample = *buffer.getReadPointer(module.inputChan, i); diff --git a/Source/Processors/PhaseDetector/PhaseDetector.h b/Source/Processors/PhaseDetector/PhaseDetector.h index 6116e2f2fe6ef0de397f5ba3233a99659d7b5a28..ea099df2031e779422843eef221e359d142cc997 100644 --- a/Source/Processors/PhaseDetector/PhaseDetector.h +++ b/Source/Processors/PhaseDetector/PhaseDetector.h @@ -46,7 +46,7 @@ public: PhaseDetector(); ~PhaseDetector(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); AudioProcessorEditor* createEditor(); diff --git a/Source/Processors/ProcessorGraph/ProcessorGraph.cpp b/Source/Processors/ProcessorGraph/ProcessorGraph.cpp index e4f55a32fc4df6a225e1570ab53f4cba850565d1..ffef2749a216965a16f3cb12f766bdbf188e644a 100644 --- a/Source/Processors/ProcessorGraph/ProcessorGraph.cpp +++ b/Source/Processors/ProcessorGraph/ProcessorGraph.cpp @@ -33,19 +33,15 @@ #include "../FilterNode/FilterNode.h" #include "../RecordNode/RecordNode.h" #include "../ResamplingNode/ResamplingNode.h" -#include "../ReferenceNode/ReferenceNode.h" #include "../ChannelMappingNode/ChannelMappingNode.h" -#include "../AudioResamplingNode/AudioResamplingNode.h" #include "../SignalGenerator/SignalGenerator.h" #include "../SourceNode/SourceNode.h" #include "../EventDetector/EventDetector.h" #include "../SpikeDetector/SpikeDetector.h" #include "../SpikeSorter/SpikeSorter.h" #include "../PhaseDetector/PhaseDetector.h" -#include "../WiFiOutput/WiFiOutput.h" #include "../FileReader/FileReader.h" #include "../ArduinoOutput/ArduinoOutput.h" -#include "../FPGAOutput/FPGAOutput.h" #include "../PulsePalOutput/PulsePalOutput.h" #include "../SerialInput/SerialInput.h" #include "../MessageCenter/MessageCenter.h" @@ -94,15 +90,10 @@ void ProcessorGraph::createDefaultNodes() RecordNode* recn = new RecordNode(); recn->setNodeId(RECORD_NODE_ID); - // add audio node -- takes all inputs and selects those to be used for audio monitoring AudioNode* an = new AudioNode(); an->setNodeId(AUDIO_NODE_ID); - // add audio resampling node -- resamples continuous signals to 44.1kHz - AudioResamplingNode* arn = new AudioResamplingNode(); - arn->setNodeId(RESAMPLING_NODE_ID); - // add message center MessageCenter* msgCenter = new MessageCenter(); msgCenter->setNodeId(MESSAGE_CENTER_ID); @@ -110,7 +101,6 @@ void ProcessorGraph::createDefaultNodes() addNode(on, OUTPUT_NODE_ID); addNode(recn, RECORD_NODE_ID); addNode(an, AUDIO_NODE_ID); - addNode(arn, RESAMPLING_NODE_ID); addNode(msgCenter, MESSAGE_CENTER_ID); } @@ -155,6 +145,12 @@ void* ProcessorGraph::createNewProcessor(String& description, int id)//, { // by default, all source nodes record automatically processor->setAllChannelsToRecord(); + + getMessageCenter()->addSourceProcessor(processor); + if (getMessageCenter()->getSourceNodeId() == 0) + { + getMessageCenter()->setSourceNodeId(processor->getNodeId()); + } } return processor->createEditor(); @@ -199,7 +195,6 @@ void ProcessorGraph::refreshColors() if (nodeId != OUTPUT_NODE_ID && nodeId != AUDIO_NODE_ID && nodeId != RECORD_NODE_ID && - nodeId != RESAMPLING_NODE_ID && nodeId != MESSAGE_CENTER_ID) { GenericProcessor* p =(GenericProcessor*) node->getProcessor(); @@ -223,7 +218,6 @@ void ProcessorGraph::restoreParameters() if (nodeId != OUTPUT_NODE_ID && nodeId != AUDIO_NODE_ID && nodeId != RECORD_NODE_ID && - nodeId != RESAMPLING_NODE_ID && nodeId != MESSAGE_CENTER_ID) { GenericProcessor* p =(GenericProcessor*) node->getProcessor(); @@ -247,7 +241,6 @@ Array<GenericProcessor*> ProcessorGraph::getListOfProcessors() if (nodeId != OUTPUT_NODE_ID && nodeId != AUDIO_NODE_ID && nodeId != RECORD_NODE_ID && - nodeId != RESAMPLING_NODE_ID && nodeId != MESSAGE_CENTER_ID) { GenericProcessor* p =(GenericProcessor*) node->getProcessor(); @@ -267,8 +260,7 @@ void ProcessorGraph::clearConnections() Node* node = getNode(i); int nodeId = node->nodeId; - if (nodeId != OUTPUT_NODE_ID && - nodeId != RESAMPLING_NODE_ID) + if (nodeId != OUTPUT_NODE_ID) { if (nodeId != RECORD_NODE_ID && nodeId != AUDIO_NODE_ID) @@ -287,16 +279,10 @@ void ProcessorGraph::clearConnections() { addConnection(AUDIO_NODE_ID, n, - RESAMPLING_NODE_ID, n); - - addConnection(RESAMPLING_NODE_ID, n, OUTPUT_NODE_ID, n); } - addConnection(AUDIO_NODE_ID, midiChannelIndex, - RESAMPLING_NODE_ID, midiChannelIndex); - addConnection(MESSAGE_CENTER_ID, midiChannelIndex, RECORD_NODE_ID, midiChannelIndex); } @@ -465,7 +451,8 @@ void ProcessorGraph::connectProcessorToAudioAndRecordNodes(GenericProcessor* sou if (source == nullptr) return; - getRecordNode()->registerProcessor(source); + getRecordNode()->registerProcessor(source); + for (int chan = 0; chan < source->getNumOutputs(); chan++) { @@ -655,21 +642,11 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip processor = new SpikeDisplayNode(); } - else if (subProcessorType.equalsIgnoreCase("WiFi Output")) - { - std::cout << "Creating a WiFi node." << std::endl; - processor = new WiFiOutput(); - } else if (subProcessorType.equalsIgnoreCase("Arduino Output")) { std::cout << "Creating an Arduino node." << std::endl; processor = new ArduinoOutput(); } - else if (subProcessorType.equalsIgnoreCase("FPGA Output")) - { - std::cout << "Creating an FPGA output node." << std::endl; - processor = new FPGAOutput(); - } else if (subProcessorType.equalsIgnoreCase("Pulse Pal")) { std::cout << "Creating a Pulse Pal output node." << std::endl; @@ -709,8 +686,31 @@ void ProcessorGraph::removeProcessor(GenericProcessor* processor) std::cout << "Removing processor with ID " << processor->getNodeId() << std::endl; - disconnectNode(processor->getNodeId()); - removeNode(processor->getNodeId()); + int nodeId = processor->getNodeId(); + + if (processor->isSource()) + { + getMessageCenter()->removeSourceProcessor(processor); + } + + disconnectNode(nodeId); + removeNode(nodeId); + + if (getMessageCenter()->getSourceNodeId() == nodeId) + { + int newId = 0; + + //Look for the next source node. If none is found, set the sourceid to 0 + for (int i = 0; i < getNumNodes() && newId == 0; i++) + { + GenericProcessor* p = static_cast<GenericProcessor*>(getNode(i)->getProcessor()); + if (p->isSource()) + { + newId = p->nodeId; + } + } + getMessageCenter()->setSourceNodeId(newId); + } } @@ -822,7 +822,7 @@ void ProcessorGraph::setRecordState(bool isRecording) { GenericProcessor* p = (GenericProcessor*) node->getProcessor(); - p->setRecording(isRecording); + p->setRecording(isRecording); } } diff --git a/Source/Processors/ProcessorGraph/ProcessorGraph.h b/Source/Processors/ProcessorGraph/ProcessorGraph.h index 4bedf2bed8e08233dd1a8b3ddb32461dd4500c2c..cad797fcd5938de94b742feb3f4a8ec1103a6ee9 100644 --- a/Source/Processors/ProcessorGraph/ProcessorGraph.h +++ b/Source/Processors/ProcessorGraph/ProcessorGraph.h @@ -98,7 +98,6 @@ void* zmqcontext; RECORD_NODE_ID = 900, AUDIO_NODE_ID = 901, OUTPUT_NODE_ID = 902, - RESAMPLING_NODE_ID = 903, MESSAGE_CENTER_ID = 904 }; diff --git a/Source/Processors/PulsePalOutput/PulsePalOutput.cpp b/Source/Processors/PulsePalOutput/PulsePalOutput.cpp index a616bfcb59581859a3dd4ba374526d5b19edbebc..14ade399d1c2e8c79d228890c53e95155357a8c1 100644 --- a/Source/Processors/PulsePalOutput/PulsePalOutput.cpp +++ b/Source/Processors/PulsePalOutput/PulsePalOutput.cpp @@ -121,8 +121,7 @@ void PulsePalOutput::setParameter(int parameterIndex, float newValue) } void PulsePalOutput::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { checkForEvents(events); diff --git a/Source/Processors/PulsePalOutput/PulsePalOutput.h b/Source/Processors/PulsePalOutput/PulsePalOutput.h index e9f52a13b60178757136c5568e2db767424af58a..113cb202986c48e2272af3f09f8f79499377cc3c 100644 --- a/Source/Processors/PulsePalOutput/PulsePalOutput.h +++ b/Source/Processors/PulsePalOutput/PulsePalOutput.h @@ -46,7 +46,7 @@ public: PulsePalOutput(); ~PulsePalOutput(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); void handleEvent(int eventType, MidiMessage& event, int sampleNum); diff --git a/Source/Processors/RecordControl/RecordControl.cpp b/Source/Processors/RecordControl/RecordControl.cpp index b3ca5b019e3f32dc6a7252f140ed5f01a241a1ba..f230171af1a9ce8dad223630ffa0f992b50c5732 100644 --- a/Source/Processors/RecordControl/RecordControl.cpp +++ b/Source/Processors/RecordControl/RecordControl.cpp @@ -68,8 +68,7 @@ bool RecordControl::enable() } void RecordControl::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { checkForEvents(events); } diff --git a/Source/Processors/RecordControl/RecordControl.h b/Source/Processors/RecordControl/RecordControl.h index ffdfb4239694930dd6027cb8bace79c2216dc156..ee5ea3ed939fa6bd77f936aecd66f7f73b758b35 100644 --- a/Source/Processors/RecordControl/RecordControl.h +++ b/Source/Processors/RecordControl/RecordControl.h @@ -43,7 +43,7 @@ public: RecordControl(); ~RecordControl(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int, float); void updateTriggerChannel(int newChannel); void handleEvent(int eventType, MidiMessage& event, int); diff --git a/Source/Processors/RecordNode/HDF5FileFormat.cpp b/Source/Processors/RecordNode/HDF5FileFormat.cpp index 0e1d1e2c3c83482a08355566cc0fa0b778a5413f..83f967ad7991d64627f70e37189abdedb5e0d595 100644 --- a/Source/Processors/RecordNode/HDF5FileFormat.cpp +++ b/Source/Processors/RecordNode/HDF5FileFormat.cpp @@ -124,7 +124,9 @@ int HDF5FileBase::setAttribute(DataTypes type, void* data, String path, String n int HDF5FileBase::setAttributeArray(DataTypes type, void* data, int size, String path, String name) { - Group loc; + H5Location* loc; + Group gloc; + DataSet dloc; Attribute attr; DataType H5type; DataType origType; @@ -132,26 +134,35 @@ int HDF5FileBase::setAttributeArray(DataTypes type, void* data, int size, String if (!opened) return -1; try { - loc = file->openGroup(path.toUTF8()); + try + { + gloc = file->openGroup(path.toUTF8()); + loc = &gloc; + } + catch (FileIException error) //If there is no group with that path, try a dataset + { + dloc = file->openDataSet(path.toUTF8()); + loc = &dloc; + } H5type = getH5Type(type); origType = getNativeType(type); - if (size > 1) - { - hsize_t dims = size; - H5type = ArrayType(H5type,1,&dims); - origType = ArrayType(origType,1,&dims); - } + if (size > 1) + { + hsize_t dims = size; + H5type = ArrayType(H5type,1,&dims); + origType = ArrayType(origType,1,&dims); + } - if (loc.attrExists(name.toUTF8())) + if (loc->attrExists(name.toUTF8())) { - attr = loc.openAttribute(name.toUTF8()); + attr = loc->openAttribute(name.toUTF8()); } else { DataSpace attr_dataspace(H5S_SCALAR); - attr = loc.createAttribute(name.toUTF8(),H5type,attr_dataspace); + attr = loc->createAttribute(name.toUTF8(),H5type,attr_dataspace); } attr.write(origType,data); @@ -165,13 +176,23 @@ int HDF5FileBase::setAttributeArray(DataTypes type, void* data, int size, String { PROCESS_ERROR; } + catch (DataSetIException error) + { + PROCESS_ERROR; + } + catch (FileIException error) + { + PROCESS_ERROR; + } return 0; } int HDF5FileBase::setAttributeStr(String value, String path, String name) { - Group loc; + H5Location* loc; + Group gloc; + DataSet dloc; Attribute attr; if (!opened) return -1; @@ -179,9 +200,18 @@ int HDF5FileBase::setAttributeStr(String value, String path, String name) StrType type(PredType::C_S1, value.length()); try { - loc = file->openGroup(path.toUTF8()); + try + { + gloc = file->openGroup(path.toUTF8()); + loc = &gloc; + } + catch (FileIException error) //If there is no group with that path, try a dataset + { + dloc = file->openDataSet(path.toUTF8()); + loc = &dloc; + } - if (loc.attrExists(name.toUTF8())) + if (loc->attrExists(name.toUTF8())) { //attr = loc.openAttribute(name.toUTF8()); return -1; //string attributes cannot change size easily, better not allow overwritting. @@ -189,7 +219,7 @@ int HDF5FileBase::setAttributeStr(String value, String path, String name) else { DataSpace attr_dataspace(H5S_SCALAR); - attr = loc.createAttribute(name.toUTF8(), type, attr_dataspace); + attr = loc->createAttribute(name.toUTF8(), type, attr_dataspace); } attr.write(type,value.toUTF8()); @@ -206,6 +236,11 @@ int HDF5FileBase::setAttributeStr(String value, String path, String name) { PROCESS_ERROR; } + catch (DataSetIException error) + { + PROCESS_ERROR; + } + return 0; } @@ -378,9 +413,9 @@ H5::DataType HDF5FileBase::getNativeType(DataTypes type) case F32: return PredType::NATIVE_FLOAT; break; - case STR: - return StrType(PredType::C_S1,MAX_STR_SIZE); - break; + case STR: + return StrType(PredType::C_S1,MAX_STR_SIZE); + break; } return PredType::NATIVE_INT32; } @@ -416,9 +451,9 @@ H5::DataType HDF5FileBase::getH5Type(DataTypes type) case F32: return PredType::IEEE_F32LE; break; - case STR: - return StrType(PredType::C_S1,MAX_STR_SIZE); - break; + case STR: + return StrType(PredType::C_S1,MAX_STR_SIZE); + break; } return PredType::STD_I32LE; } @@ -449,8 +484,8 @@ HDF5RecordingData::HDF5RecordingData(DataSet* data) this->xChunkSize = chunk[0]; this->xPos = dims[0]; this->dSet = dataSet; - this->rowXPos = 0; - this->rowDataSize = 0; + this->rowXPos.clear(); + this->rowXPos.insertMultiple(0,0,this->size[1]); } HDF5RecordingData::~HDF5RecordingData() @@ -495,7 +530,7 @@ int HDF5RecordingData::writeDataBlock(int xDataSize, int yDataSize, HDF5FileBase offset[0]=xPos; offset[1]=0; offset[2]=0; - + fSpace.selectHyperslab(H5S_SELECT_SET, dim, offset); nativeType = HDF5FileBase::getNativeType(type); @@ -514,32 +549,6 @@ int HDF5RecordingData::writeDataBlock(int xDataSize, int yDataSize, HDF5FileBase return 0; } -int HDF5RecordingData::prepareDataBlock(int xDataSize) -{ - hsize_t dim[3]; - DataSpace fSpace; - if (dimension > 2) return -4; //We're not going to write rows in datasets bigger than 2d. - - dim[2] = size[2]; - dim[1] = size[1]; - dim[0] = xPos + xDataSize; - try - { - dSet->extend(dim); - - fSpace = dSet->getSpace(); - fSpace.getSimpleExtentDims(dim); - size[0]=dim[0]; - } - catch (DataSetIException error) - { - PROCESS_ERROR; - } - rowXPos = xPos; - rowDataSize = xDataSize; - xPos += xDataSize; - return 0; -} int HDF5RecordingData::writeDataRow(int yPos, int xDataSize, HDF5FileBase::DataTypes type, void* data) { @@ -547,17 +556,32 @@ int HDF5RecordingData::writeDataRow(int yPos, int xDataSize, HDF5FileBase::DataT DataSpace fSpace; DataType nativeType; if (dimension > 2) return -4; //We're not going to write rows in datasets bigger than 2d. - if (xDataSize != rowDataSize) return -2; - if ((yPos < 0) || (yPos >= size[1])) return -3; + // if (xDataSize != rowDataSize) return -2; + if ((yPos < 0) || (yPos >= size[1])) return -2; try { + if (rowXPos[yPos]+xDataSize > size[0]) + { + dim[1] = size[1]; + dim[0] = rowXPos[yPos] + xDataSize; + dSet->extend(dim); + + fSpace = dSet->getSpace(); + fSpace.getSimpleExtentDims(dim); + size[0]=dim[0]; + } + if (rowXPos[yPos]+xDataSize > xPos) + { + xPos = rowXPos[yPos]+xDataSize; + } + dim[0] = xDataSize; dim[1] = 1; DataSpace mSpace(dimension,dim); fSpace = dSet->getSpace(); - offset[0] = rowXPos; + offset[0] = rowXPos[yPos]; offset[1] = yPos; fSpace.selectHyperslab(H5S_SELECT_SET, dim, offset); @@ -565,6 +589,8 @@ int HDF5RecordingData::writeDataRow(int yPos, int xDataSize, HDF5FileBase::DataT dSet->write(data,nativeType,mSpace,fSpace); + + rowXPos.set(yPos,rowXPos[yPos] + xDataSize); } catch (DataSetIException error) { @@ -581,6 +607,12 @@ int HDF5RecordingData::writeDataRow(int yPos, int xDataSize, HDF5FileBase::DataT return 0; } +void HDF5RecordingData::getRowXPositions(Array<uint32>& rows) +{ + rows.clear(); + rows.addArray(rowXPos); +} + //KWD File KWDFile::KWDFile(int processorNumber, String basename) : HDF5FileBase() @@ -610,6 +642,8 @@ void KWDFile::startNewRecording(int recordingNumber, int nChannels, HDF5Recordin { this->recordingNumber = recordingNumber; this->nChannels = nChannels; + this->multiSample = info->multiSample; + uint8 mSample = info->multiSample ? 1 : 0; String recordPath = String("/recordings/")+String(recordingNumber); CHECK_ERROR(createGroup(recordPath)); @@ -618,8 +652,10 @@ void KWDFile::startNewRecording(int recordingNumber, int nChannels, HDF5Recordin // CHECK_ERROR(setAttribute(U32,&(info->start_sample),recordPath,String("start_sample"))); CHECK_ERROR(setAttribute(F32,&(info->sample_rate),recordPath,String("sample_rate"))); CHECK_ERROR(setAttribute(U32,&(info->bit_depth),recordPath,String("bit_depth"))); - CHECK_ERROR(createGroup(recordPath+"/application_data")); - CHECK_ERROR(setAttributeArray(F32,info->bitVolts.getRawDataPointer(),info->bitVolts.size(),recordPath+"/application_data",String("channel_bit_volts"))); + CHECK_ERROR(createGroup(recordPath+"/application_data")); + CHECK_ERROR(setAttributeArray(F32,info->bitVolts.getRawDataPointer(),info->bitVolts.size(),recordPath+"/application_data",String("channel_bit_volts"))); + CHECK_ERROR(setAttribute(U8,&mSample,recordPath+"/application_data",String("is_multiSampleRate_data"))); + CHECK_ERROR(setAttributeArray(F32,info->channelSampleRates.getRawDataPointer(),info->channelSampleRates.size(),recordPath+"/application_data",String("channel_sample_rates"))); recdata = createDataSet(I16,0,nChannels,CHUNK_XSIZE,recordPath+"/data"); if (!recdata.get()) std::cerr << "Error creating data set" << std::endl; @@ -628,6 +664,11 @@ void KWDFile::startNewRecording(int recordingNumber, int nChannels, HDF5Recordin void KWDFile::stopRecording() { + Array<uint32> samples; + String path = String("/recordings/")+String(recordingNumber)+String("/data"); + recdata->getRowXPositions(samples); + + CHECK_ERROR(setAttributeArray(U32,samples.getRawDataPointer(),samples.size(),path,"valid_samples")); //ScopedPointer does the deletion and destructors the closings recdata = nullptr; } @@ -649,7 +690,6 @@ void KWDFile::writeRowData(int16* data, int nSamples) { if (curChan >= nChannels) { - CHECK_ERROR(recdata->prepareDataBlock(nSamples)); curChan=0; } CHECK_ERROR(recdata->writeDataRow(curChan,nSamples,I16,data)); @@ -704,7 +744,7 @@ int KWIKFile::createFileStructure() if (!dSet) return -1; dSet = createDataSet(U8,0,EVENT_CHUNK_SIZE,path + "/nodeID"); if (!dSet) return -1; - dSet = createDataSet(eventTypes[i],0,EVENT_CHUNK_SIZE,path + "/" + eventDataNames[i]); + dSet = createDataSet(eventTypes[i],0,EVENT_CHUNK_SIZE,path + "/" + eventDataNames[i]); if (!dSet) return -1; } if (setAttribute(U16,(void*)&ver,"/","kwik_version")) return -1; @@ -745,7 +785,7 @@ void KWIKFile::startNewRecording(int recordingNumber, HDF5RecordingInfo* info) if (!dSet) std::cerr << "Error loading event node ID dataset for type " << i << std::endl; nodeID.add(dSet); - dSet = getDataSet(path + "/user_data/" + eventDataNames[i]); + dSet = getDataSet(path + "/user_data/" + eventDataNames[i]); if (!dSet) std::cerr << "Error loading event channel dataset for type " << i << std::endl; eventData.add(dSet); @@ -757,8 +797,8 @@ void KWIKFile::stopRecording() timeStamps.clear(); recordings.clear(); eventID.clear(); - nodeID.clear(); - eventData.clear(); + nodeID.clear(); + eventData.clear(); } void KWIKFile::writeEvent(int type, uint8 id, uint8 processor, void* data, uint64 timestamp) @@ -772,7 +812,7 @@ void KWIKFile::writeEvent(int type, uint8 id, uint8 processor, void* data, uint6 CHECK_ERROR(recordings[type]->writeDataBlock(1,I32,&recordingNumber)); CHECK_ERROR(eventID[type]->writeDataBlock(1,U8,&id)); CHECK_ERROR(nodeID[type]->writeDataBlock(1,U8,&processor)); - CHECK_ERROR(eventData[type]->writeDataBlock(1,eventTypes[type],data)); + CHECK_ERROR(eventData[type]->writeDataBlock(1,eventTypes[type],data)); } void KWIKFile::addKwdFile(String filename) @@ -785,8 +825,8 @@ void KWIKFile::addKwdFile(String filename) void KWIKFile::addEventType(String name, DataTypes type, String dataName) { eventNames.add(name); - eventTypes.add(type); - eventDataNames.add(dataName); + eventTypes.add(type); + eventDataNames.add(dataName); } //KWX File diff --git a/Source/Processors/RecordNode/HDF5FileFormat.h b/Source/Processors/RecordNode/HDF5FileFormat.h index c228647ef344a5565f75474ee3229daed6e79a5c..a29c019da74a179c522e22cecf3ad3584ca7a128 100644 --- a/Source/Processors/RecordNode/HDF5FileFormat.h +++ b/Source/Processors/RecordNode/HDF5FileFormat.h @@ -41,7 +41,9 @@ struct HDF5RecordingInfo uint32 start_sample; float sample_rate; uint32 bit_depth; - Array<float> bitVolts; + Array<float> bitVolts; + Array<float> channelSampleRates; + bool multiSample; }; class HDF5FileBase @@ -65,7 +67,7 @@ protected: int setAttribute(DataTypes type, void* data, String path, String name); int setAttributeStr(String value, String path, String name); - int setAttributeArray(DataTypes type, void* data, int size, String path, String name); + int setAttributeArray(DataTypes type, void* data, int size, String path, String name); int createGroup(String path); HDF5RecordingData* getDataSet(String path); @@ -97,19 +99,19 @@ public: int writeDataBlock(int xDataSize, HDF5FileBase::DataTypes type, void* data); int writeDataBlock(int xDataSize, int yDataSize, HDF5FileBase::DataTypes type, void* data); - int prepareDataBlock(int xDataSize); int writeDataRow(int yPos, int xDataSize, HDF5FileBase::DataTypes type, void* data); + void getRowXPositions(Array<uint32>& rows); + private: int xPos; int xChunkSize; int size[3]; int dimension; - int rowXPos; - int rowDataSize; + Array<uint32> rowXPos; ScopedPointer<H5::DataSet> dSet; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HDF5RecordingData); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HDF5RecordingData); }; class KWDFile : public HDF5FileBase @@ -133,9 +135,10 @@ private: int nChannels; int curChan; String filename; + bool multiSample; ScopedPointer<HDF5RecordingData> recdata; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWDFile); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWDFile); }; class KWIKFile : public HDF5FileBase @@ -164,11 +167,11 @@ private: OwnedArray<HDF5RecordingData> nodeID; OwnedArray<HDF5RecordingData> eventData; Array<String> eventNames; - Array<DataTypes> eventTypes; - Array<String> eventDataNames; + Array<DataTypes> eventTypes; + Array<String> eventDataNames; int kwdIndex; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWIKFile); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWIKFile); }; class KWXFile : public HDF5FileBase @@ -199,7 +202,7 @@ private: int numElectrodes; int16* transformVector; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWXFile); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWXFile); }; #endif // HDF5FILEFORMAT_H_INCLUDED diff --git a/Source/Processors/RecordNode/HDF5Recording.cpp b/Source/Processors/RecordNode/HDF5Recording.cpp index cbbf37700ec6a80eb134358f44f08d68ab3902a2..4a4938553a3fb728c4f1bf5db58b56fe4e72ae7d 100644 --- a/Source/Processors/RecordNode/HDF5Recording.cpp +++ b/Source/Processors/RecordNode/HDF5Recording.cpp @@ -26,7 +26,7 @@ HDF5Recording::HDF5Recording() : processorIndex(-1) { - timestamp = 0; + //timestamp = 0; scaledBuffer = new float[MAX_BUFFER_SIZE]; intBuffer = new int16[MAX_BUFFER_SIZE]; } @@ -39,22 +39,24 @@ HDF5Recording::~HDF5Recording() String HDF5Recording::getEngineID() { - return "KWIK"; + return "KWIK"; } -void HDF5Recording::updateTimeStamp(int64 timestamp) -{ - this->timestamp = timestamp; -} +// void HDF5Recording::updateTimeStamp(int64 timestamp) +// { +// this->timestamp = timestamp; +// } void HDF5Recording::registerProcessor(GenericProcessor* proc) { HDF5RecordingInfo* info = new HDF5RecordingInfo(); info->sample_rate = proc->getSampleRate(); info->bit_depth = 16; + info->multiSample = false; infoArray.add(info); fileArray.add(new KWDFile()); - bitVoltsArray.add(new Array<float>); + bitVoltsArray.add(new Array<float>); + sampleRatesArray.add(new Array<float>); processorIndex++; } @@ -62,7 +64,8 @@ void HDF5Recording::resetChannels() { processorIndex = -1; fileArray.clear(); - bitVoltsArray.clear(); + bitVoltsArray.clear(); + sampleRatesArray.clear(); processorMap.clear(); infoArray.clear(); if (spikesFile) @@ -103,7 +106,12 @@ void HDF5Recording::openFiles(File rootFolder, int experimentNumber, int record fileArray[index]->initFile(getChannel(i)->nodeId,basepath); fileArray[index]->open(); } - bitVoltsArray[index]->add(getChannel(i)->bitVolts); + bitVoltsArray[index]->add(getChannel(i)->bitVolts); + sampleRatesArray[index]->add(getChannel(i)->sampleRate); + if (getChannel(i)->sampleRate != infoArray[index]->sample_rate) + { + infoArray[index]->multiSample = true; + } } } for (int i = 0; i < fileArray.size(); i++) @@ -116,9 +124,11 @@ void HDF5Recording::openFiles(File rootFolder, int experimentNumber, int record infoArray[i]->name = String("Open-Ephys Recording #") + String(recordingNumber); infoArray[i]->start_time = timestamp; infoArray[i]->start_sample = 0; - infoArray[i]->bitVolts.clear(); - infoArray[i]->bitVolts.addArray(*bitVoltsArray[i]); - fileArray[i]->startNewRecording(recordingNumber,bitVoltsArray[i]->size(),infoArray[i]); + infoArray[i]->bitVolts.clear(); + infoArray[i]->bitVolts.addArray(*bitVoltsArray[i]); + infoArray[i]->channelSampleRates.clear(); + infoArray[i]->channelSampleRates.addArray(*sampleRatesArray[i]); + fileArray[i]->startNewRecording(recordingNumber,bitVoltsArray[i]->size(),infoArray[i]); } } } @@ -133,17 +143,21 @@ void HDF5Recording::closeFiles() { fileArray[i]->stopRecording(); fileArray[i]->close(); - bitVoltsArray[i]->clear(); + bitVoltsArray[i]->clear(); } } -void HDF5Recording::writeData(AudioSampleBuffer& buffer, int nSamples) +void HDF5Recording::writeData(AudioSampleBuffer& buffer) { int index; for (int i = 0; i < buffer.getNumChannels(); i++) { if (getChannel(i)->getRecordState()) { + + int sourceNodeId = getChannel(i)->sourceNodeId; + int nSamples = (*numSamples)[sourceNodeId]; + double multFactor = 1/(float(0x7fff) * getChannel(i)->bitVolts); int index = processorMap[getChannel(i)->recordIndex]; FloatVectorOperations::copyWithMultiply(scaledBuffer,buffer.getReadPointer(i,0),multFactor,nSamples); @@ -156,10 +170,10 @@ void HDF5Recording::writeData(AudioSampleBuffer& buffer, int nSamples) void HDF5Recording::writeEvent(int eventType, MidiMessage& event, int samplePosition) { const uint8* dataptr = event.getRawData(); - if (eventType == GenericProcessor::TTL) - mainFile->writeEvent(0,*(dataptr+2),*(dataptr+1),(void*)(dataptr+3),timestamp+samplePosition); - else if (eventType == GenericProcessor::MESSAGE) - mainFile->writeEvent(1,*(dataptr+2),*(dataptr+1),(void*)(dataptr+4),timestamp+samplePosition); + if (eventType == GenericProcessor::TTL) + mainFile->writeEvent(0,*(dataptr+2),*(dataptr+1),(void*)(dataptr+3),timestamp+samplePosition); + else if (eventType == GenericProcessor::MESSAGE) + mainFile->writeEvent(1,*(dataptr+2),*(dataptr+1),(void*)(dataptr+4),timestamp+samplePosition); } void HDF5Recording::addSpikeElectrode(int index, SpikeRecordInfo* elec) @@ -174,13 +188,13 @@ void HDF5Recording::writeSpike(const SpikeObject& spike, int electrodeIndex) void HDF5Recording::startAcquisition() { mainFile = new KWIKFile(); - mainFile->addEventType("TTL",HDF5FileBase::U8,"event_channels"); - mainFile->addEventType("Messages",HDF5FileBase::STR,"Text"); + mainFile->addEventType("TTL",HDF5FileBase::U8,"event_channels"); + mainFile->addEventType("Messages",HDF5FileBase::STR,"Text"); spikesFile = new KWXFile(); } RecordEngineManager* HDF5Recording::getEngineManager() { - RecordEngineManager* man = new RecordEngineManager("KWIK","Kwik",nullptr); - return man; + RecordEngineManager* man = new RecordEngineManager("KWIK","Kwik",nullptr); + return man; } \ No newline at end of file diff --git a/Source/Processors/RecordNode/HDF5Recording.h b/Source/Processors/RecordNode/HDF5Recording.h index 9be5e3942929b93014826b0f7b6f1a474075e5d7..9b9466dd7ac63230866fa8c3f5af2091df40ca2b 100644 --- a/Source/Processors/RecordNode/HDF5Recording.h +++ b/Source/Processors/RecordNode/HDF5Recording.h @@ -32,26 +32,27 @@ class HDF5Recording : public RecordEngine public: HDF5Recording(); ~HDF5Recording(); - String getEngineID(); + String getEngineID(); void openFiles(File rootFolder, int experimentNumber, int recordingNumber); void closeFiles(); - void writeData(AudioSampleBuffer& buffer, int nSamples); + void writeData(AudioSampleBuffer& buffer); void writeEvent(int eventType, MidiMessage& event, int samplePosition); void addChannel(int index, Channel* chan); void addSpikeElectrode(int index, SpikeRecordInfo* elec); void writeSpike(const SpikeObject& spike, int electrodeIndex); void registerProcessor(GenericProcessor* processor); void resetChannels(); - void updateTimeStamp(int64 timestamp); + //oid updateTimeStamp(int64 timestamp); void startAcquisition(); - static RecordEngineManager* getEngineManager(); + static RecordEngineManager* getEngineManager(); private: int processorIndex; Array<int> processorMap; OwnedArray<Array<float>> bitVoltsArray; + OwnedArray<Array<float>> sampleRatesArray; OwnedArray<KWDFile> fileArray; OwnedArray<HDF5RecordingInfo> infoArray; ScopedPointer<KWIKFile> mainFile; @@ -60,7 +61,7 @@ private: int16* intBuffer; int64 timestamp; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HDF5Recording); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HDF5Recording); }; diff --git a/Source/Processors/RecordNode/OriginalRecording.cpp b/Source/Processors/RecordNode/OriginalRecording.cpp index c03b27491e1d451d0249ea9ced5ac20e30a8c360..d0d3eb0a945dad1f1333405eb4c3b2f0111015f6 100644 --- a/Source/Processors/RecordNode/OriginalRecording.cpp +++ b/Source/Processors/RecordNode/OriginalRecording.cpp @@ -25,8 +25,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../../Audio/AudioComponent.h" OriginalRecording::OriginalRecording() : separateFiles(false), - blockIndex(0), recordingNumber(0), experimentNumber(0), zeroBuffer(1, 50000), - eventFile(nullptr), messageFile(nullptr), lastProcId(0) + recordingNumber(0), experimentNumber(0), zeroBuffer(1, 50000), + eventFile(nullptr), messageFile(nullptr), lastProcId(0) { continuousDataIntegerBuffer = new int16[10000]; continuousDataFloatBuffer = new float[10000]; @@ -66,6 +66,8 @@ void OriginalRecording::addChannel(int index, Channel* chan) { //Just populate the file array with null so we can address it by index afterwards fileArray.add(nullptr); + blockIndex.add(0); + samplesSinceLastTimestamp.add(0); } void OriginalRecording::addSpikeElectrode(int index, SpikeRecordInfo* elec) @@ -77,7 +79,9 @@ void OriginalRecording::resetChannels() { fileArray.clear(); spikeFileArray.clear(); - processorArray.clear(); + blockIndex.clear(); + processorArray.clear(); + samplesSinceLastTimestamp.clear(); } void OriginalRecording::openFiles(File rootFolder, int experimentNumber, int recordingNumber) @@ -85,24 +89,26 @@ void OriginalRecording::openFiles(File rootFolder, int experimentNumber, int rec this->recordingNumber = recordingNumber; this->experimentNumber = experimentNumber; - processorArray.clear(); - lastProcId = 0; + processorArray.clear(); + lastProcId = 0; openFile(rootFolder,nullptr); openMessageFile(rootFolder); + for (int i = 0; i < fileArray.size(); i++) { if (getChannel(i)->getRecordState()) { openFile(rootFolder,getChannel(i)); + blockIndex.set(i,0); + samplesSinceLastTimestamp.set(i,0); } + } for (int i = 0; i < spikeFileArray.size(); i++) { openSpikeFile(rootFolder,getSpikeElectrode(i)); } - blockIndex = 0; - startTimestamp = timestamp; } void OriginalRecording::openFile(File rootFolder, Channel* ch) @@ -110,9 +116,9 @@ void OriginalRecording::openFile(File rootFolder, Channel* ch) FILE* chFile; bool isEvent; String fullPath(rootFolder.getFullPathName() + rootFolder.separatorString); - String fileName; + String fileName; - recordPath = fullPath; + recordPath = fullPath; isEvent = (ch == nullptr) ? true : false; if (isEvent) @@ -127,8 +133,8 @@ void OriginalRecording::openFile(File rootFolder, Channel* ch) fileName += getFileName(ch); } - fullPath += fileName; - std::cout << "OPENING FILE: " << fullPath << std::endl; + fullPath += fileName; + std::cout << "OPENING FILE: " << fullPath << std::endl; File f = File(fullPath); @@ -151,36 +157,36 @@ void OriginalRecording::openFile(File rootFolder, Channel* ch) std::cout << "Wrote header." << std::endl; - std::cout << "Block index: " << blockIndex << std::endl; + // std::cout << "Block index: " << blockIndex << std::endl; } else { std::cout << "File already exists, just opening." << std::endl; - fseek(chFile, 0, SEEK_END ); + fseek(chFile, 0, SEEK_END); } if (isEvent) eventFile = chFile; else - { + { fileArray.set(ch->recordIndex,chFile); - if (ch->nodeId != lastProcId) - { - lastProcId = ch->nodeId; - ProcInfo* p = new ProcInfo(); - p->id = ch->nodeId; - p->sampleRate = ch->sampleRate; - processorArray.add(p); - } - ChannelInfo* c = new ChannelInfo(); - c->filename = fileName; - c->name = ch->name; - c->startPos = ftell(chFile); - c->bitVolts = ch->bitVolts; - processorArray.getLast()->channels.add(c); - } - diskWriteLock.exit(); + if (ch->nodeId != lastProcId) + { + lastProcId = ch->nodeId; + ProcInfo* p = new ProcInfo(); + p->id = ch->nodeId; + p->sampleRate = ch->sampleRate; + processorArray.add(p); + } + ChannelInfo* c = new ChannelInfo(); + c->filename = fileName; + c->name = ch->name; + c->startPos = ftell(chFile); + c->bitVolts = ch->bitVolts; + processorArray.getLast()->channels.add(c); + } + diskWriteLock.exit(); } @@ -269,7 +275,7 @@ String OriginalRecording::generateHeader(Channel* ch) String header = "header.format = 'Open Ephys Data Format'; \n"; - header += "header.version = "+ String(VERSION_STRING) +"; \n"; + header += "header.version = "+ String(VERSION_STRING) +"; \n"; header += "header.header_bytes = "; header += String(HEADER_SIZE); header += ";\n"; @@ -333,7 +339,7 @@ String OriginalRecording::generateSpikeHeader(SpikeRecordInfo* elec) header += String(HEADER_SIZE); header += ";\n"; - header += "header.description = 'Each record contains 1 uint8 eventType, 1 uint64 timestamp, 1 uint16 electrodeID, 1 uint16 numChannels (n), 1 uint16 numSamples (m), n*m uint16 samples, n uint16 channelGains, n uint16 thresholds, and 1 uint16 recordingNumber'; \n"; + header += "header.description = 'Each record contains 1 uint8 eventType, 1 int64 timestamp, 1 uint16 electrodeID, 1 uint16 numChannels (n), 1 uint16 numSamples (m), n*m uint16 samples, n uint16 channelGains, n uint16 thresholds, and 1 uint16 recordingNumber'; \n"; header += "header.date_created = '"; header += generateDateString(); @@ -371,8 +377,9 @@ void OriginalRecording::writeMessage(MidiMessage& event, int samplePosition) if (messageFile == nullptr) return; uint64 samplePos = (uint64) samplePosition; + uint8 sourceNodeId = event.getNoteNumber(); - int64 eventTimestamp = timestamp + samplePos; + int64 eventTimestamp = (*timestamps)[sourceNodeId] + samplePos; int msgLength = event.getRawDataSize() - 5; const char* dataptr = (const char*)event.getRawData() + 4; @@ -400,7 +407,9 @@ void OriginalRecording::writeTTLEvent(MidiMessage& event, int samplePosition) uint64 samplePos = (uint64) samplePosition; - int64 eventTimestamp = timestamp + samplePos; // add the sample position to the buffer timestamp + uint8 sourceNodeId = event.getNoteNumber(); + + int64 eventTimestamp = (*timestamps)[sourceNodeId] + samplePos; // add the sample position to the buffer timestamp diskWriteLock.enter(); @@ -426,63 +435,60 @@ void OriginalRecording::writeTTLEvent(MidiMessage& event, int samplePosition) diskWriteLock.exit(); } -void OriginalRecording::writeData(AudioSampleBuffer& buffer, int nSamples) +void OriginalRecording::writeData(AudioSampleBuffer& buffer) { - int samplesWritten = 0; - while (samplesWritten < nSamples) // there are still unwritten samples in the buffer + for (int i = 0; i < buffer.getNumChannels(); i++) { + if (getChannel(i)->getRecordState()) + { + int samplesWritten = 0; - int numSamplesToWrite = nSamples - samplesWritten; // samples remaining in the buffer + int sourceNodeId = getChannel(i)->sourceNodeId; - if (blockIndex + numSamplesToWrite < BLOCK_LENGTH) // we still have space in this block - { - for (int i = 0; i < buffer.getNumChannels(); i++) + samplesSinceLastTimestamp.set(i,0); + + int nSamples = (*numSamples)[sourceNodeId]; + + while (samplesWritten < nSamples) // there are still unwritten samples in this buffer { + int numSamplesToWrite = nSamples - samplesWritten; - if (getChannel(i)->getRecordState()) + if (blockIndex[i] + numSamplesToWrite < BLOCK_LENGTH) // we still have space in this block { + // write buffer to disk! writeContinuousBuffer(buffer.getReadPointer(i,samplesWritten), numSamplesToWrite, i); + //timestamp += numSamplesToWrite; + samplesSinceLastTimestamp.set(i, samplesSinceLastTimestamp[i] + numSamplesToWrite); + blockIndex.set(i, blockIndex[i] + numSamplesToWrite); + samplesWritten += numSamplesToWrite; } - } - - // update our variables - samplesWritten += numSamplesToWrite; - timestamp += numSamplesToWrite; - blockIndex += numSamplesToWrite; - - } - else // there's not enough space left in this block for all remaining samples - { - - numSamplesToWrite = BLOCK_LENGTH - blockIndex; + else // there's not enough space left in this block for all remaining samples + { - for (int i = 0; i < buffer.getNumChannels(); i++) - { + numSamplesToWrite = BLOCK_LENGTH - blockIndex[i]; - if (getChannel(i)->getRecordState()) - { // write buffer to disk! writeContinuousBuffer(buffer.getReadPointer(i,samplesWritten), numSamplesToWrite, i); - //std::cout << "Record channel " << i << std::endl; + // update our variables + samplesWritten += numSamplesToWrite; + //timestamp += numSamplesToWrite; + samplesSinceLastTimestamp.set(i, samplesSinceLastTimestamp[i] + numSamplesToWrite); + blockIndex.set(i,0); // back to the beginning of the block } } - // update our variables - samplesWritten += numSamplesToWrite; - timestamp += numSamplesToWrite; - blockIndex = 0; // back to the beginning of the block - } } + } void OriginalRecording::writeContinuousBuffer(const float* data, int nSamples, int channel) @@ -493,15 +499,16 @@ void OriginalRecording::writeContinuousBuffer(const float* data, int nSamples, i // scale the data back into the range of int16 float scaleFactor = float(0x7fff) * getChannel(channel)->bitVolts; + for (int n = 0; n < nSamples; n++) { *(continuousDataFloatBuffer+n) = *(data+n) / scaleFactor; } AudioDataConverters::convertFloatToInt16BE(continuousDataFloatBuffer, continuousDataIntegerBuffer, nSamples); - if (blockIndex == 0) + if (blockIndex[channel] == 0) { - writeTimestampAndSampleCount(fileArray[channel]); + writeTimestampAndSampleCount(fileArray[channel], channel); } diskWriteLock.enter(); @@ -511,23 +518,29 @@ void OriginalRecording::writeContinuousBuffer(const float* data, int nSamples, i nSamples, // count fileArray[channel]); // ptr to FILE object + //std::cout << channel << " : " << nSamples << " : " << count << std::endl; + jassert(count == nSamples); // make sure all the data was written diskWriteLock.exit(); - if (blockIndex + nSamples == BLOCK_LENGTH) + if (blockIndex[channel] + nSamples == BLOCK_LENGTH) { writeRecordMarker(fileArray[channel]); } } -void OriginalRecording::writeTimestampAndSampleCount(FILE* file) +void OriginalRecording::writeTimestampAndSampleCount(FILE* file, int channel) { diskWriteLock.enter(); uint16 samps = BLOCK_LENGTH; - fwrite(×tamp, // ptr + int sourceNodeId = getChannel(channel)->sourceNodeId; + + int64 ts = (*timestamps)[sourceNodeId] + samplesSinceLastTimestamp[channel]; + + fwrite(&ts, // ptr 8, // size of each element 1, // count file); // ptr to FILE object @@ -564,16 +577,18 @@ void OriginalRecording::closeFiles() { if (fileArray[i] != nullptr) { - if (blockIndex < BLOCK_LENGTH) + if (blockIndex[i] < BLOCK_LENGTH) { // fill out the rest of the current buffer - writeContinuousBuffer(zeroBuffer.getReadPointer(0), BLOCK_LENGTH - blockIndex, i); + writeContinuousBuffer(zeroBuffer.getReadPointer(0), BLOCK_LENGTH - blockIndex[i], i); diskWriteLock.enter(); fclose(fileArray[i]); fileArray.set(i,nullptr); diskWriteLock.exit(); } } + + blockIndex.set(i,0); } for (int i = 0; i < spikeFileArray.size(); i++) { @@ -599,15 +614,16 @@ void OriginalRecording::closeFiles() messageFile = nullptr; diskWriteLock.exit(); } - writeXml(); - blockIndex = 0; -} -void OriginalRecording::updateTimeStamp(int64 timestamp) -{ - this->timestamp = timestamp; + writeXml(); + } +// void OriginalRecording::updateTimeStamp(int64 timestamp) +// { +// this->timestamp = timestamp; +// } + void OriginalRecording::writeSpike(const SpikeObject& spike, int electrodeIndex) { uint8_t spikeBuffer[MAX_SPIKE_BUFFER_LEN]; @@ -649,46 +665,46 @@ void OriginalRecording::writeSpike(const SpikeObject& spike, int electrodeIndex) void OriginalRecording::writeXml() { - String name = recordPath + "Continuous_Data"; - if (experimentNumber > 1) - { - name += "_"; - name += String(experimentNumber); - } - name += ".openephys"; - - File file(name); - XmlDocument doc(file); - ScopedPointer<XmlElement> xml = doc.getDocumentElement(); - if ( !xml || ! xml->hasTagName("EXPERIMENT")) - { - xml = new XmlElement("EXPERIMENT"); - xml->setAttribute("version",VERSION); - xml->setAttribute("number",experimentNumber); - xml->setAttribute("separatefiles",separateFiles); - } - XmlElement* rec = new XmlElement("RECORDING"); - rec->setAttribute("number",recordingNumber); - rec->setAttribute("length",(double)(timestamp-startTimestamp)); - for (int i = 0; i < processorArray.size(); i++) - { - XmlElement* proc = new XmlElement("PROCESSOR"); - proc->setAttribute("id",processorArray[i]->id); - rec->setAttribute("samplerate",processorArray[i]->sampleRate); - for (int j = 0; j < processorArray[i]->channels.size(); j++) - { - ChannelInfo* c = processorArray[i]->channels[j]; - XmlElement* chan = new XmlElement("CHANNEL"); - chan->setAttribute("name",c->name); - chan->setAttribute("bitVolts",c->bitVolts); - chan->setAttribute("filename",c->filename); - chan->setAttribute("position",(double)(c->startPos)); //As long as the file doesnt exceed 2^53 bytes, this will have integer precission. Better than limiting to 32bits. - proc->addChildElement(chan); - } - rec->addChildElement(proc); - } - xml->addChildElement(rec); - xml->writeToFile(file,String::empty); + String name = recordPath + "Continuous_Data"; + if (experimentNumber > 1) + { + name += "_"; + name += String(experimentNumber); + } + name += ".openephys"; + + File file(name); + XmlDocument doc(file); + ScopedPointer<XmlElement> xml = doc.getDocumentElement(); + if (!xml || ! xml->hasTagName("EXPERIMENT")) + { + xml = new XmlElement("EXPERIMENT"); + xml->setAttribute("version",VERSION); + xml->setAttribute("number",experimentNumber); + xml->setAttribute("separatefiles",separateFiles); + } + XmlElement* rec = new XmlElement("RECORDING"); + rec->setAttribute("number",recordingNumber); + //rec->setAttribute("length",(double)(timestamp-startTimestamp)); + for (int i = 0; i < processorArray.size(); i++) + { + XmlElement* proc = new XmlElement("PROCESSOR"); + proc->setAttribute("id",processorArray[i]->id); + rec->setAttribute("samplerate",processorArray[i]->sampleRate); + for (int j = 0; j < processorArray[i]->channels.size(); j++) + { + ChannelInfo* c = processorArray[i]->channels[j]; + XmlElement* chan = new XmlElement("CHANNEL"); + chan->setAttribute("name",c->name); + chan->setAttribute("bitVolts",c->bitVolts); + chan->setAttribute("filename",c->filename); + chan->setAttribute("position",(double)(c->startPos)); //As long as the file doesnt exceed 2^53 bytes, this will have integer precission. Better than limiting to 32bits. + proc->addChildElement(chan); + } + rec->addChildElement(proc); + } + xml->addChildElement(rec); + xml->writeToFile(file,String::empty); } void OriginalRecording::setParameter(EngineParameter& parameter) diff --git a/Source/Processors/RecordNode/OriginalRecording.h b/Source/Processors/RecordNode/OriginalRecording.h index f269d06634ea174a9b21da166bfcfae28de19a9c..5a1447167d4f763e3c84f46c46120ff30607e49c 100644 --- a/Source/Processors/RecordNode/OriginalRecording.h +++ b/Source/Processors/RecordNode/OriginalRecording.h @@ -28,6 +28,7 @@ #include "RecordEngine.h" #include <stdio.h> +#include <map> #define HEADER_SIZE 1024 #define BLOCK_LENGTH 1024 @@ -48,11 +49,11 @@ public: String getEngineID(); void openFiles(File rootFolder, int experimentNumber, int recordingNumber); void closeFiles(); - void writeData(AudioSampleBuffer& buffer, int nSamples); + void writeData(AudioSampleBuffer& buffer); void writeEvent(int eventType, MidiMessage& event, int samplePosition); void addChannel(int index, Channel* chan); void resetChannels(); - void updateTimeStamp(int64 timestamp); + //void updateTimeStamp(int64 timestamp); void addSpikeElectrode(int index, SpikeRecordInfo* elec); void writeSpike(const SpikeObject& spike, int electrodeIndex); @@ -63,7 +64,7 @@ private: void openFile(File rootFolder, Channel* ch); String generateHeader(Channel* ch); void writeContinuousBuffer(const float* data, int nSamples, int channel); - void writeTimestampAndSampleCount(FILE* file); + void writeTimestampAndSampleCount(FILE* file, int channel); void writeRecordMarker(FILE* file); void openSpikeFile(File rootFolder, SpikeRecordInfo* elec); @@ -73,10 +74,11 @@ private: void writeTTLEvent(MidiMessage& event, int samplePosition); void writeMessage(MidiMessage& event, int samplePosition); - void writeXml(); + void writeXml(); bool separateFiles; - int blockIndex; + Array<int> blockIndex; + Array<int> samplesSinceLastTimestamp; int recordingNumber; int experimentNumber; @@ -94,31 +96,32 @@ private: char* recordMarker; AudioSampleBuffer zeroBuffer; - int64 timestamp; FILE* eventFile; FILE* messageFile; Array<FILE*> fileArray; Array<FILE*> spikeFileArray; - + CriticalSection diskWriteLock; - struct ChannelInfo { - String name; - String filename; - float bitVolts; - long int startPos; - }; - struct ProcInfo { - int id; - float sampleRate; - OwnedArray<ChannelInfo> channels; - }; - - OwnedArray<ProcInfo> processorArray; - int lastProcId; - String recordPath; - int64 startTimestamp; + struct ChannelInfo + { + String name; + String filename; + float bitVolts; + long int startPos; + }; + struct ProcInfo + { + int id; + float sampleRate; + OwnedArray<ChannelInfo> channels; + }; + + OwnedArray<ProcInfo> processorArray; + int lastProcId; + String recordPath; + int64 startTimestamp; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OriginalRecording); }; diff --git a/Source/Processors/RecordNode/RecordEngine.cpp b/Source/Processors/RecordNode/RecordEngine.cpp index 3d187092502ecfb2dc987d5ff8c55b1147424de1..d6cc769e26e5ef3a0a3501bfa7bac3ef37ceddf3 100644 --- a/Source/Processors/RecordNode/RecordEngine.cpp +++ b/Source/Processors/RecordNode/RecordEngine.cpp @@ -57,7 +57,16 @@ SpikeRecordInfo* RecordEngine::getSpikeElectrode(int index) return getProcessorGraph()->getRecordNode()->getSpikeElectrode(index); } -void RecordEngine::updateTimeStamp(int64 timestamp) {} +void RecordEngine::updateTimestamps(std::map<uint8, int64>* ts) +{ + timestamps = ts; +} + +void RecordEngine::updateNumSamples(std::map<uint8, int>* ns) +{ + numSamples = ns; +} + void RecordEngine::registerSpikeSource(GenericProcessor* processor) {} diff --git a/Source/Processors/RecordNode/RecordEngine.h b/Source/Processors/RecordNode/RecordEngine.h index 09ff73ceefa34f9805d0354d7d890cbc6752ed92..44d48163b229eeb3c2531db7125d1261347a23b3 100644 --- a/Source/Processors/RecordNode/RecordEngine.h +++ b/Source/Processors/RecordNode/RecordEngine.h @@ -29,6 +29,8 @@ #include "../GenericProcessor/GenericProcessor.h" #include "../Visualization/SpikeObject.h" +#include <map> + //Handy macros for setParameter #define boolParameter(i,v) if ((parameter.id == i) && (parameter.type == EngineParameter::BOOL)) \ v = parameter.boolParam.value @@ -65,8 +67,8 @@ public: 2-registerProcessor, addChannel, registerSpikeSource, addspikeelectrode 3-configureEngine (which calls setParameter) 3-startAcquisition - During acquisition: - updateTimeStamps + During acquisition: + updateTimeStamps When recording starts (in the specified order): 1-directoryChanged (if needed) 2-openFiles @@ -91,9 +93,10 @@ public: /** Write continuous data. This method gets the full data buffer, it must query getRecordState for - each registered channel to determine which channels to actually write to disk + each registered channel to determine which channels to actually write to disk. + The number of samples to write will be found in the numSamples object. */ - virtual void writeData(AudioSampleBuffer& buffer, int nSamples) = 0; + virtual void writeData(AudioSampleBuffer& buffer) = 0; /** Write a single event to disk. */ @@ -127,7 +130,10 @@ public: /** Called every time a new timestamp event is received */ - virtual void updateTimeStamp(int64 timestamp); + void updateTimestamps(std::map<uint8, int64>* timestamps); + + /** Called every time a new numSamples event is received */ + void updateNumSamples(std::map<uint8, int>* numSamples); /** Called after all channels and spike groups have been registered, just before acquisition starts @@ -158,6 +164,9 @@ protected: */ String generateDateString(); + std::map<uint8, int>* numSamples; + std::map<uint8, int64>* timestamps; + private: RecordEngineManager* manager; diff --git a/Source/Processors/RecordNode/RecordNode.cpp b/Source/Processors/RecordNode/RecordNode.cpp index 1bc936469c6d91ba457a8bcf2953894ba9a542f9..48b283eee7c446071bb6ee376814e92e34c51551 100755 --- a/Source/Processors/RecordNode/RecordNode.cpp +++ b/Source/Processors/RecordNode/RecordNode.cpp @@ -48,11 +48,9 @@ RecordNode::RecordNode() settings.numInputs = 2048; settings.numOutputs = 0; - eventChannel = new Channel(this, 0); - eventChannel->setType(EVENT_CHANNEL); + eventChannel = new Channel(this, 0, EVENT_CHANNEL); recordingNumber = 0; - spikeElectrodeIndex = 0; experimentNumber = 0; @@ -412,53 +410,34 @@ float RecordNode::getFreeSpace() void RecordNode::handleEvent(int eventType, MidiMessage& event, int samplePosition) { - if (eventType == TIMESTAMP) - { - const uint8* dataptr = event.getRawData(); - - // // double-check buffer contents: - // std::cout << (int) *(dataptr + 11) << " " << - // (int) *(dataptr + 10) << " " << - // (int) *(dataptr + 9) << " " << - // (int) *(dataptr + 8) << " " << - // (int) *(dataptr + 7) << " " << - // (int) *(dataptr + 6) << " " << - // (int) *(dataptr + 5) << " " << - // (int) *(dataptr + 4) << std::endl; - - memcpy(×tamp, dataptr + 4, 8); // remember to skip first four bytes - EVERY_ENGINE->updateTimeStamp(timestamp); - } if (isRecording && allFilesOpened) { if ((eventType == TTL) || (eventType == MESSAGE)) { - if (event.getNoteNumber() > 0) // processor ID > 0 + if (event.getRawData()+4 > 0) // saving flag > 0 (i.e., event has not already been processed) { EVERY_ENGINE->writeEvent(eventType, event, samplePosition); } } - else if (eventType == MESSAGE) - { - std::cout << "Received event!" << std::endl; - } } - } void RecordNode::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { - // FIRST: cycle through events -- extract the TTLs and the timestamps + // FIRST: cycle through events -- extract the TTLs and the timestamps checkForEvents(events); + + //update timstamp data even if we're not recording yet + EVERY_ENGINE->updateTimestamps(×tamps); + EVERY_ENGINE->updateNumSamples(&numSamples); + if (isRecording && allFilesOpened) { - // SECOND: write channel data if (channelPointers.size() > 0) { - EVERY_ENGINE->writeData(buffer,nSamples); + EVERY_ENGINE->writeData(buffer); } // std::cout << nSamples << " " << samplesWritten << " " << blockIndex << std::endl; diff --git a/Source/Processors/RecordNode/RecordNode.h b/Source/Processors/RecordNode/RecordNode.h index 032db2f73c295c78b5bf9750d8cc88f8a48b7285..2ef65fb021b73fb2a00453ee6aca728498eb7665 100755 --- a/Source/Processors/RecordNode/RecordNode.h +++ b/Source/Processors/RecordNode/RecordNode.h @@ -60,7 +60,7 @@ public: /** Handle incoming data and decide which files and events to write to disk. */ - void process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer); /** Overrides implementation in GenericProcessor; used to change recording parameters @@ -74,24 +74,24 @@ public: */ void setParameter(int parameterIndex, float newValue); - /** Called by the processor graph for each processor that could record data - */ + /** Called by the processor graph for each processor that could record data + */ void registerProcessor(GenericProcessor* sourceNode); - /** Called by the processor graph for each recordable channel - */ + /** Called by the processor graph for each recordable channel + */ void addInputChannel(GenericProcessor* sourceNode, int chan); bool enable(); bool disable(); /** returns channel names and whether we record them */ - void getChannelNamesAndRecordingStatus(StringArray &names, Array<bool> &recording); + void getChannelNamesAndRecordingStatus(StringArray& names, Array<bool>& recording); /** update channel name */ void updateChannelName(int channelIndex, String newname); - /** Get channel stored in channelPointers array - */ + /** Get channel stored in channelPointers array + */ Channel* getDataChannel(int index); /** Called by the ControlPanel to determine the amount of space @@ -128,29 +128,29 @@ public: } void appendTrialNumber(bool); - + void updateTrialNumber(); - /** Adds a Record Engine to use - */ + /** Adds a Record Engine to use + */ void registerRecordEngine(RecordEngine* engine); - /** Clears the list of active Record Engines - */ - void clearRecordEngines(); + /** Clears the list of active Record Engines + */ + void clearRecordEngines(); - /** Must be called by a spike recording source on the "enable" method - */ + /** Must be called by a spike recording source on the "enable" method + */ void registerSpikeSource(GenericProcessor* processor); - /** Registers an electrode group for spike recording - Must be called by a spike recording source on the "enable" method - after the call to registerSpikeSource - */ + /** Registers an electrode group for spike recording + Must be called by a spike recording source on the "enable" method + after the call to registerSpikeSource + */ int addSpikeElectrode(SpikeRecordInfo* elec); - /** Called by a spike recording source to write a spike to file - */ + /** Called by a spike recording source to write a spike to file + */ void writeSpike(SpikeObject& spike, int electrodeIndex); SpikeRecordInfo* getSpikeElectrode(int index); diff --git a/Source/Processors/ReferenceNode/ReferenceNode.cpp b/Source/Processors/ReferenceNode/ReferenceNode.cpp deleted file mode 100644 index b162d8b42d619a820491c8be70e5c6f9b4871da6..0000000000000000000000000000000000000000 --- a/Source/Processors/ReferenceNode/ReferenceNode.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - ------------------------------------------------------------------ - - This file is part of the Open Ephys GUI - Copyright (C) 2014 Open Ephys - - ------------------------------------------------------------------ - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -*/ - -#include <stdio.h> -#include "ReferenceNode.h" -#include "ReferenceNodeEditor.h" - - - -ReferenceNode::ReferenceNode() - : GenericProcessor("Digital Ref"), referenceChannel(-1), referenceBuffer(1,10000) -{ - -} - -ReferenceNode::~ReferenceNode() -{ - -} - -AudioProcessorEditor* ReferenceNode::createEditor() -{ - editor = new ReferenceNodeEditor(this, true); - - std::cout << "Creating editor." << std::endl; - - return editor; -} - - - -void ReferenceNode::updateSettings() -{ - - - -} - -void ReferenceNode::setParameter(int parameterIndex, float newValue) -{ - editor->updateParameterButtons(parameterIndex); - - referenceChannel = (int) newValue; - - std::cout << "Reference set to " << referenceChannel << std::endl; - -} - -void ReferenceNode::process(AudioSampleBuffer& buffer, - MidiBuffer& midiMessages, - int& nSamples) -{ - - if (referenceChannel > -1) - { - referenceBuffer.clear(0, 0, nSamples); - - referenceBuffer.addFrom(0, // destChannel - 0, // destStartSample - buffer, // source - referenceChannel, // sourceChannel - 0, // sourceStartSample - nSamples, // numSamples - -1.0f // gain to apply to source - ); - - for (int i = 0; i < buffer.getNumChannels(); i++) - { - - buffer.addFrom(i, // destChannel - 0, // destStartSample - referenceBuffer, // source - 0, // sourceChannel - 0, // sourceStartSample - nSamples, // numSamples - 1.0f // gain to apply to source - ); - } - - } - -} - diff --git a/Source/Processors/ReferenceNode/ReferenceNode.h b/Source/Processors/ReferenceNode/ReferenceNode.h deleted file mode 100644 index 15038e72a5d824c7c2a9af0ccbbdb4c31d14f599..0000000000000000000000000000000000000000 --- a/Source/Processors/ReferenceNode/ReferenceNode.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - ------------------------------------------------------------------ - - This file is part of the Open Ephys GUI - Copyright (C) 2014 Open Ephys - - ------------------------------------------------------------------ - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -*/ - -#ifndef __REFERENCENODE_H_786EA929__ -#define __REFERENCENODE_H_786EA929__ - - -#include "../../../JuceLibraryCode/JuceHeader.h" - -#include "../GenericProcessor/GenericProcessor.h" - - -/** - - Digital reference node - - @see GenericProcessor - -*/ - -class ReferenceNode : public GenericProcessor - -{ -public: - - ReferenceNode(); - ~ReferenceNode(); - - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); - void setParameter(int parameterIndex, float newValue); - - AudioProcessorEditor* createEditor(); - - bool hasEditor() const - { - return true; - } - - void updateSettings(); - -private: - - int referenceChannel; - - AudioSampleBuffer referenceBuffer; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ReferenceNode); - -}; - -#endif // __REFERENCENODE_H_786EA929__ diff --git a/Source/Processors/ReferenceNode/ReferenceNodeEditor.cpp b/Source/Processors/ReferenceNode/ReferenceNodeEditor.cpp deleted file mode 100644 index 25054001c1b7bb6746648e3911703623663aa857..0000000000000000000000000000000000000000 --- a/Source/Processors/ReferenceNode/ReferenceNodeEditor.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - ------------------------------------------------------------------ - - This file is part of the Open Ephys GUI - Copyright (C) 2014 Open Ephys - - ------------------------------------------------------------------ - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -*/ - - -#include "ReferenceNodeEditor.h" -#include "ReferenceNode.h" -#include <stdio.h> - - -ReferenceNodeEditor::ReferenceNodeEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors=true) - : GenericEditor(parentNode, useDefaultParameterEditors), previousChannelCount(0) - -{ - desiredWidth = 180; - - referenceSelector = new ComboBox(); - referenceSelector->setBounds(15,50,150,25); - referenceSelector->addListener(this); - referenceSelector->addItem("None", 1); - referenceSelector->setSelectedId(1, dontSendNotification); - addAndMakeVisible(referenceSelector); - -} - -ReferenceNodeEditor::~ReferenceNodeEditor() -{ - -} - -void ReferenceNodeEditor::updateSettings() -{ - - if (getProcessor()->getNumInputs() != previousChannelCount) - { - referenceSelector->clear(); - - referenceSelector->addItem("None", 1); - - for (int i = 0; i < getProcessor()->getNumInputs(); i++) - { - referenceSelector->addItem("Channel " + String(i+1), i+2); - - } - - previousChannelCount = getProcessor()->getNumInputs(); - - } - - referenceSelector->setSelectedId(1, dontSendNotification); - - getProcessor()->setParameter(1,-1.0f); -} - -void ReferenceNodeEditor::comboBoxChanged(ComboBox* c) -{ - float channel; - - int id = c->getSelectedId(); - - if (id == 1) - { - channel = -1.0f; - } - else - { - channel = float(id) - 2.0f; - } - - getProcessor()->setParameter(1,channel); - -} - -void ReferenceNodeEditor::buttonEvent(Button* button) -{ - - -} - -void ReferenceNodeEditor::saveEditorParameters(XmlElement* xml) -{ - - xml->setAttribute("Type", "ReferenceNodeEditor"); - - XmlElement* selectedChannel = xml->createNewChildElement("SELECTEDID"); - - selectedChannel->setAttribute("ID",referenceSelector->getSelectedId()); - -} - -void ReferenceNodeEditor::loadEditorParameters(XmlElement* xml) -{ - - forEachXmlChildElement(*xml, xmlNode) - { - if (xmlNode->hasTagName("SELECTEDID")) - { - - int id = xmlNode->getIntAttribute("ID"); - - referenceSelector->setSelectedId(id); - - } - } -} \ No newline at end of file diff --git a/Source/Processors/ReferenceNode/ReferenceNodeEditor.h b/Source/Processors/ReferenceNode/ReferenceNodeEditor.h deleted file mode 100644 index efce3f1a014f384e3fab2a6a805c88d8b7571f6c..0000000000000000000000000000000000000000 --- a/Source/Processors/ReferenceNode/ReferenceNodeEditor.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - ------------------------------------------------------------------ - - This file is part of the Open Ephys GUI - Copyright (C) 2014 Open Ephys - - ------------------------------------------------------------------ - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -*/ - -#ifndef __REFERENCENODEEDITOR_H_370C056D__ -#define __REFERENCENODEEDITOR_H_370C056D__ - -#include "../../../JuceLibraryCode/JuceHeader.h" -#include "../Editors/GenericEditor.h" - -/** - - User interface for the ReferenceNode processor. - - @see ReferenceNode - -*/ - -class ReferenceNodeEditor : public GenericEditor, - public ComboBox::Listener -{ -public: - ReferenceNodeEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors); - virtual ~ReferenceNodeEditor(); - void buttonEvent(Button* button); - - void comboBoxChanged(ComboBox* c); - - void updateSettings(); - - void saveEditorParameters(XmlElement* xml); - void loadEditorParameters(XmlElement* xml); - - -private: - - ScopedPointer<ComboBox> referenceSelector; - - int previousChannelCount; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ReferenceNodeEditor); - -}; - - - - - -#endif // __REFERENCENODEEDITOR_H_370C056D__ diff --git a/Source/Processors/ResamplingNode/ResamplingNode.cpp b/Source/Processors/ResamplingNode/ResamplingNode.cpp index af68d740f32b795fe7d12dc0fc20536766e1e4ea..123a946b72133c3d030565e724b8d9c3ac1857be 100755 --- a/Source/Processors/ResamplingNode/ResamplingNode.cpp +++ b/Source/Processors/ResamplingNode/ResamplingNode.cpp @@ -140,8 +140,7 @@ void ResamplingNode::updateFilter() // } void ResamplingNode::process(AudioSampleBuffer& buffer, - MidiBuffer& midiMessages, - int& nSamples) + MidiBuffer& midiMessages) { //std::cout << "Resampling node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl; @@ -149,6 +148,7 @@ void ResamplingNode::process(AudioSampleBuffer& buffer, // save data at the beginning of each round of processing //writeContinuousBuffer(buffer.getSampleData(0), nSamples, 0); + int nSamples = 100; // SOME NUMBER int nSamps = float(nSamples); int valuesNeeded = int(nSamps / ratio); diff --git a/Source/Processors/ResamplingNode/ResamplingNode.h b/Source/Processors/ResamplingNode/ResamplingNode.h index 0b864eade577f5f8fcf20df097be62e1d84db291..cd20ce62ae503dcd6fce5025cea1c3f4acef6735 100755 --- a/Source/Processors/ResamplingNode/ResamplingNode.h +++ b/Source/Processors/ResamplingNode/ResamplingNode.h @@ -50,7 +50,7 @@ public: ResamplingNode(); ~ResamplingNode(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); void updateSettings(); diff --git a/Source/Processors/SerialInput/SerialInput.cpp b/Source/Processors/SerialInput/SerialInput.cpp index 3664068bd1e8dd7d479c9d913fdc65c3b7add50a..58b6955d31d609ef329160a6af918b17dde2a426 100644 --- a/Source/Processors/SerialInput/SerialInput.cpp +++ b/Source/Processors/SerialInput/SerialInput.cpp @@ -90,7 +90,7 @@ bool SerialInput::disable() } -void SerialInput::process(AudioSampleBuffer&, MidiBuffer& events, int&) +void SerialInput::process(AudioSampleBuffer&, MidiBuffer& events) { int bytesAvailable = serial.available(); diff --git a/Source/Processors/SerialInput/SerialInput.h b/Source/Processors/SerialInput/SerialInput.h index 96f8292d47409ec5f64595db38db4813f6e2bca2..36ceda52e70544577596973e11d9ba67f252009e 100644 --- a/Source/Processors/SerialInput/SerialInput.h +++ b/Source/Processors/SerialInput/SerialInput.h @@ -103,7 +103,7 @@ public: Adds all the new serial data that is available to the event data buffer. */ - void process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& events); /** Returns the Juce GUI component that should be used with this processor. diff --git a/Source/Processors/SignalGenerator/SignalGenerator.cpp b/Source/Processors/SignalGenerator/SignalGenerator.cpp index 43c320fbe062b94ce743ac608f46bfbb5a567ef3..c06ef91a4d218328ceff592ab709a5132975cb01 100755 --- a/Source/Processors/SignalGenerator/SignalGenerator.cpp +++ b/Source/Processors/SignalGenerator/SignalGenerator.cpp @@ -184,11 +184,10 @@ bool SignalGenerator::disable() void SignalGenerator::process(AudioSampleBuffer& buffer, - MidiBuffer& midiMessages, - int& nSamps) + MidiBuffer& midiMessages) { - nSamps = int((float) buffer.getNumSamples() * sampleRateRatio); + int nSamps = int((float) buffer.getNumSamples() * sampleRateRatio); for (int i = 0; i < nSamps; ++i) { diff --git a/Source/Processors/SignalGenerator/SignalGenerator.h b/Source/Processors/SignalGenerator/SignalGenerator.h index eef1de4ee0e9202ab9a493196d0737a048b33fd3..97f9809185e52e9714d15ab86d5ce54cae19f722 100755 --- a/Source/Processors/SignalGenerator/SignalGenerator.h +++ b/Source/Processors/SignalGenerator/SignalGenerator.h @@ -45,7 +45,7 @@ public: SignalGenerator(); ~SignalGenerator(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); diff --git a/Source/Processors/SourceNode/SourceNode.cpp b/Source/Processors/SourceNode/SourceNode.cpp index d657cbc041ab9a7ee84bf017625a3fb72cd7df7f..79964dc0e52bd54a28f64fbf00b772d56b4f3316 100755 --- a/Source/Processors/SourceNode/SourceNode.cpp +++ b/Source/Processors/SourceNode/SourceNode.cpp @@ -23,13 +23,9 @@ #include "SourceNode.h" #include "../DataThreads/DataBuffer.h" -//#include "DataThreads/IntanThread.h" -#include "../DataThreads/FPGAThread.h" -//#include "../DataThreads/FileReaderThread.h" #include "../DataThreads/RHD2000Thread.h" #include "../DataThreads/EcubeThread.h" // Added by Michael Borisov #include "../SourceNode/SourceNodeEditor.h" -//#include "../FileReader/FileReaderEditor.h" #include "../DataThreads/RHD2000Editor.h" #include "../DataThreads/EcubeEditor.h" // Added by Michael Borisov #include "../Channel/Channel.h" @@ -45,15 +41,11 @@ SourceNode::SourceNode(const String& name_) if (getName().equalsIgnoreCase("RHA2000-EVAL")) { - // dataThread = new IntanThread(this);o + // dataThread = new IntanThread(this); // this thread has not been updated recently } - else if (getName().equalsIgnoreCase("Custom FPGA")) - { - dataThread = new FPGAThread(this); - } - //else if (getName().equalsIgnoreCase("File Reader")) + // else if (getName().equalsIgnoreCase("Custom FPGA")) // { - // dataThread = new FileReaderThread(this); + // dataThread = new FPGAThread(this); // } else if (getName().equalsIgnoreCase("Rhythm FPGA")) { @@ -116,13 +108,13 @@ DataThread* SourceNode::getThread() return dataThread; } -int SourceNode::modifyChannelName(channelType t, int str, int ch, String newName, bool updateSignalChain) +int SourceNode::modifyChannelName(ChannelType t, int str, int ch, String newName, bool updateSignalChain) { if (dataThread != 0) { int channel_index = dataThread->modifyChannelName(t, str, ch, newName); if (channel_index >= 0 && channel_index < channels.size()) { - if (channels[channel_index]->getChannelName() != newName) + if (channels[channel_index]->getName() != newName) { channels[channel_index]->setName(newName); // propagate this information... @@ -137,7 +129,7 @@ int SourceNode::modifyChannelName(channelType t, int str, int ch, String newName return -1; } -int SourceNode::modifyChannelGain(int stream, int channel,channelType type, float gain, bool updateSignalChain) +int SourceNode::modifyChannelGain(int stream, int channel, ChannelType type, float gain, bool updateSignalChain) { if (dataThread != 0) { @@ -147,9 +139,9 @@ int SourceNode::modifyChannelGain(int stream, int channel,channelType type, floa if (channel_index >= 0 && channel_index < channels.size()) { // we now need to update the signal chain to propagate this change..... - if (channels[channel_index]->getChannelGain() != gain) + if (channels[channel_index]->bitVolts != gain) { - channels[channel_index]->setGain(gain); + channels[channel_index]->bitVolts = gain; if (updateSignalChain) getEditorViewport()->makeEditorVisible(getEditor(), false, true); @@ -162,7 +154,7 @@ int SourceNode::modifyChannelGain(int stream, int channel,channelType type, floa return -1; } -void SourceNode::getChannelsInfo(StringArray &names, Array<channelType> &types, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains) +void SourceNode::getChannelsInfo(StringArray &names, Array<ChannelType> &types, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains) { if (dataThread != 0) dataThread->getChannelsInfo(names, types,stream,originalChannelNumber,gains); @@ -175,7 +167,7 @@ void SourceNode::setDefaultNamingScheme(int scheme) dataThread->setDefaultNamingScheme(scheme); StringArray names; - Array<channelType> types; + Array<ChannelType> types; Array<int> stream; Array<int> originalChannelNumber; Array<float> gains; @@ -204,21 +196,7 @@ void SourceNode::updateSettings() std::cout << "Input buffer address is " << inputBuffer << std::endl; } - dataThread->updateChannelNames(); - - for (int i = 0; i < dataThread->getNumEventChannels(); i++) - { - Channel* ch = new Channel(this, i); - ch->eventType = TTL; - ch->getType() == EVENT_CHANNEL; - eventChannels.add(ch); - } - - //for (int i = 0; i < channels.size(); i++) - // { - std::cout << "Channel: " << channels[channels.size()-1]->bitVolts << std::endl; - //} - + //dataThread->updateChannelNames(); } @@ -263,15 +241,39 @@ float SourceNode::getDefaultSampleRate() return 44100.0; } -int SourceNode::getDefaultNumOutputs() +int SourceNode::getNumHeadstageOutputs() { if (dataThread != 0) - return dataThread->getNumChannels(); + return dataThread->getNumHeadstageOutputs(); + else + return 2; +} + +int SourceNode::getNumAuxOutputs() +{ + if (dataThread != 0) + return dataThread->getNumAuxOutputs(); else return 0; } -float SourceNode::getBitVolts(int chan) +int SourceNode::getNumAdcOutputs() +{ + if (dataThread != 0) + return dataThread->getNumAdcOutputs(); + else + return 0; +} + +int SourceNode::getNumEventChannels() +{ + if (dataThread != 0) + return dataThread->getNumEventChannels(); + else + return 0; +} + +float SourceNode::getBitVolts(Channel* chan) { if (dataThread != 0) return dataThread->getBitVolts(chan); @@ -365,6 +367,8 @@ bool SourceNode::enable() wasDisabled = false; + stopTimer(); + if (dataThread != 0) { dataThread->startAcquisition(); @@ -375,8 +379,6 @@ bool SourceNode::enable() return false; } - stopTimer(); // WARN compiler warning: unreachable code (spotted by Michael Borisov). Probably needs to be removed - } bool SourceNode::disable() @@ -387,7 +389,7 @@ bool SourceNode::disable() if (dataThread != 0) dataThread->stopAcquisition(); - startTimer(2000); + startTimer(2000); // timer to check for connected source wasDisabled = true; @@ -413,8 +415,7 @@ void SourceNode::acquisitionStopped() void SourceNode::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { //std::cout << "SOURCE NODE" << std::endl; @@ -423,7 +424,10 @@ void SourceNode::process(AudioSampleBuffer& buffer, events.clear(); buffer.clear(); - nSamples = inputBuffer->readAllFromBuffer(buffer, ×tamp, eventCodeBuffer, buffer.getNumSamples()); + int nSamples = inputBuffer->readAllFromBuffer(buffer, ×tamp, eventCodeBuffer, buffer.getNumSamples()); + + setNumSamples(events, nSamples); + setTimestamp(events, timestamp); //std::cout << *buffer.getReadPointer(0) << std::endl; @@ -431,18 +435,8 @@ void SourceNode::process(AudioSampleBuffer& buffer, //std::cout << "Samples per buffer: " << nSamples << std::endl; - uint8 data[8]; - memcpy(data, ×tamp, 8); - // generate timestamp - addEvent(events, // MidiBuffer - TIMESTAMP, // eventType - 0, // sampleNum - nodeId, // eventID - 0, // eventChannel - 8, // numBytes - data // data - ); + // std::cout << (int) *(data + 7) << " " << // (int) *(data + 6) << " " << @@ -506,7 +500,7 @@ void SourceNode::saveCustomParametersToXml(XmlElement* parentElement) { StringArray names; - Array<channelType> types; + Array<ChannelType> types; Array<int> stream; Array<int> originalChannelNumber; Array<float> gains; @@ -540,7 +534,7 @@ void SourceNode::loadCustomParametersFromXml() String name = chan->getStringAttribute("name"); int stream = chan->getIntAttribute("stream"); int number = chan->getIntAttribute("number"); - channelType type = static_cast<channelType>(chan->getIntAttribute("type")); + ChannelType type = static_cast<ChannelType>(chan->getIntAttribute("type")); float gain = chan->getDoubleAttribute("gain"); modifyChannelName(type,stream,number,name,false); modifyChannelGain(stream,number,type,gain,false); diff --git a/Source/Processors/SourceNode/SourceNode.h b/Source/Processors/SourceNode/SourceNode.h index 494481fb282cd88320020662319fbd722e00b612..1b2f1f18a3cf4a8622ed894fe37517019f0747e3 100755 --- a/Source/Processors/SourceNode/SourceNode.h +++ b/Source/Processors/SourceNode/SourceNode.h @@ -51,19 +51,24 @@ public: void enabledState(bool t); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int parameterIndex, float newValue); float getSampleRate(); float getDefaultSampleRate(); - int getDefaultNumOutputs(); - float getBitVolts(int chan); + int getNumHeadstageOutputs(); - int modifyChannelGain(int stream, int channel,channelType type, float gain, bool updateSignalChain); - int modifyChannelName(channelType t, int str, int ch, String newName, bool updateSignalChain); + int getNumAuxOutputs(); + int getNumAdcOutputs(); - void getChannelsInfo(StringArray &Names, Array<channelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains); + int getNumEventChannels(); + float getBitVolts(Channel* chan); + + int modifyChannelGain(int stream, int channel,ChannelType type, float gain, bool updateSignalChain); + int modifyChannelName(ChannelType t, int str, int ch, String newName, bool updateSignalChain); + + void getChannelsInfo(StringArray &Names, Array<ChannelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains); void setDefaultNamingScheme(int scheme); void getEventChannelNames(StringArray &names); @@ -113,12 +118,10 @@ private: uint64* eventCodeBuffer; int* eventChannelState; - int ttlState; void updateSettings(); - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SourceNode); }; diff --git a/Source/Processors/SpikeDetector/SpikeDetector.cpp b/Source/Processors/SpikeDetector/SpikeDetector.cpp index 3a6456dad22fe0d477caf4312ff518193547e326..f181a44eb6c6ec33f073b668b4b8f07ccaada2f6 100755 --- a/Source/Processors/SpikeDetector/SpikeDetector.cpp +++ b/Source/Processors/SpikeDetector/SpikeDetector.cpp @@ -88,10 +88,20 @@ void SpikeDetector::updateSettings() for (int i = 0; i < electrodes.size(); i++) { - Channel* ch = new Channel(this, i); - //ch->isEventChannel = true; - ch->eventType = SPIKE_BASE_CODE + electrodes[i]->numChannels; - ch->name = electrodes[i]->name; + Channel* ch; + + switch (electrodes[i]->numChannels) + { + case 1: + ch = new Channel(this, i, SINGLE_ELECTRODE); + break; + case 2: + ch = new Channel(this, i, STEREOTRODE); + break; + case 4: + ch = new Channel(this, i, TETRODE); + break; + } eventChannels.add(ch); } @@ -156,6 +166,8 @@ bool SpikeDetector::addElectrode(int nChans) *(newElectrode->isActive+i) = true; } + newElectrode->sourceNodeId = channels[*newElectrode->channels]->sourceNodeId; + resetElectrode(newElectrode); electrodes.add(newElectrode); @@ -305,7 +317,13 @@ bool SpikeDetector::enable() { sampleRateForElectrode = (uint16_t) getSampleRate(); - useOverflowBuffer = false; + + + useOverflowBuffer.clear(); + + for (int i = 0; i < electrodes.size(); i++) + useOverflowBuffer.add(false); + return true; } @@ -424,8 +442,7 @@ void SpikeDetector::handleEvent(int eventType, MidiMessage& event, int sampleNum } void SpikeDetector::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { // cycle through electrodes @@ -447,9 +464,12 @@ void SpikeDetector::process(AudioSampleBuffer& buffer, sampleIndex = electrode->lastBufferIndex - 1; // subtract 1 to account for // increment at start of getNextSample() + int nSamples = getNumSamples(*electrode->channels); + // cycle through samples while (samplesAvailable(nSamples)) { + sampleIndex++; // cycle through channels for (int chan = 0; chan < electrode->numChannels; chan++) @@ -543,6 +563,27 @@ void SpikeDetector::process(AudioSampleBuffer& buffer, //jassert(electrode->lastBufferIndex < 0); + if (nSamples > overflowBufferSize) + { + + for (int j = 0; j < electrode->numChannels; j++) + { + + overflowBuffer.copyFrom(*electrode->channels+i, 0, + buffer, *electrode->channels+i, + nSamples-overflowBufferSize, + overflowBufferSize); + + } + + useOverflowBuffer.set(i, true); + + } + else + { + useOverflowBuffer.set(i, false); + } + } // end cycle through electrodes // copy end of this buffer into the overflow buffer @@ -555,26 +596,7 @@ void SpikeDetector::process(AudioSampleBuffer& buffer, // std::cout << "numSamples = " << overflowBufferSize << std::endl; // std::cout << "buffer size = " << buffer.getNumSamples() << std::endl; - if (nSamples > overflowBufferSize) - { - - for (int i = 0; i < overflowBuffer.getNumChannels(); i++) - { - - overflowBuffer.copyFrom(i, 0, - buffer, i, - nSamples-overflowBufferSize, - overflowBufferSize); - - useOverflowBuffer = true; - } - - } - else - { - - useOverflowBuffer = false; - } + @@ -641,7 +663,7 @@ float SpikeDetector::getCurrentSample(int& chan) } -bool SpikeDetector::samplesAvailable(int& nSamples) +bool SpikeDetector::samplesAvailable(int nSamples) { if (sampleIndex > nSamples - overflowBufferSize/2) diff --git a/Source/Processors/SpikeDetector/SpikeDetector.h b/Source/Processors/SpikeDetector/SpikeDetector.h index 8c5292c999f0a475ef3ac5e9b001a866aa0e34bf..829ad60302c9766f74ae6bf5414ad31e5e2d1571 100755 --- a/Source/Processors/SpikeDetector/SpikeDetector.h +++ b/Source/Processors/SpikeDetector/SpikeDetector.h @@ -40,6 +40,7 @@ struct SimpleElectrode int prePeakSamples, postPeakSamples; int lastBufferIndex; bool isMonitored; + int sourceNodeId; int* channels; double* thresholds; @@ -75,7 +76,7 @@ public: /** Processes an incoming continuous buffer and places new spikes into the event buffer. */ - void process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& events); /** Used to alter parameters of data acquisition. */ void setParameter(int parameterIndex, float newValue); @@ -168,9 +169,9 @@ private: float getNextSample(int& chan); float getCurrentSample(int& chan); - bool samplesAvailable(int& nSamples); + bool samplesAvailable(int nSamples); - bool useOverflowBuffer; + Array<bool> useOverflowBuffer; int currentElectrode; int currentChannelIndex; diff --git a/Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.cpp b/Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.cpp index 14233600abafe3c209f0251f9be80a82d809cc3f..6b254dcc5875da4809af8991719bb12b4c5562f6 100755 --- a/Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.cpp +++ b/Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.cpp @@ -934,7 +934,7 @@ void WaveAxes::paint(Graphics& g) } - g.setColour(Colours::white); + plotSpike(spikeBuffer[spikeIndex], g); @@ -950,6 +950,11 @@ void WaveAxes::plotSpike(const SpikeObject& s, Graphics& g) //compute the spatial width for each waveform sample float dx = getWidth()/float(spikeBuffer[0].nSamples); + if (s.sortedId > 0) + g.setColour(Colour(s.color[0],s.color[1],s.color[2])); + else + g.setColour(Colours::white); + // type corresponds to channel so we need to calculate the starting // sample based upon which channel is getting plotted int sampIdx = 40*type; //spikeBuffer[0].nSamples * type; // @@ -1273,13 +1278,19 @@ bool ProjectionAxes::updateSpikeData(const SpikeObject& s) calcWaveformPeakIdx(s, ampDim1, ampDim2, &idx1, &idx2); // add peaks to image + Colour col; + + if (s.sortedId > 0) + col = Colour(s.color[0], s.color[1], s.color[2]); + else + col = Colours::white; - updateProjectionImage(s.data[idx1], s.data[idx2], *s.gain); + updateProjectionImage(s.data[idx1], s.data[idx2], *s.gain, col); return true; } -void ProjectionAxes::updateProjectionImage(uint16_t x, uint16_t y, uint16_t gain) +void ProjectionAxes::updateProjectionImage(uint16_t x, uint16_t y, uint16_t gain, Colour col) { Graphics g(projectionImage); @@ -1290,7 +1301,7 @@ void ProjectionAxes::updateProjectionImage(uint16_t x, uint16_t y, uint16_t gain float xf = float(x-32768)/float(gain)*1000.0f; // in microvolts float yf = float(imageDim) - float(y-32768)/float(gain)*1000.0f; // in microvolts - g.setColour(Colours::white); + g.setColour(col); g.fillEllipse(xf,yf,2.0f,2.0f); } diff --git a/Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.h b/Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.h index 78bfc189978b29bf065db5f74f53b020da0af19a..bacf46e08c8b9c60911b0aeacbc1060cc511eb64 100755 --- a/Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.h +++ b/Source/Processors/SpikeDisplayNode/SpikeDisplayCanvas.h @@ -425,7 +425,7 @@ public: private: - void updateProjectionImage(uint16_t, uint16_t, uint16_t); + void updateProjectionImage(uint16_t, uint16_t, uint16_t, Colour); void calcWaveformPeakIdx(const SpikeObject&, int, int, int*, int*); diff --git a/Source/Processors/SpikeDisplayNode/SpikeDisplayNode.cpp b/Source/Processors/SpikeDisplayNode/SpikeDisplayNode.cpp index 4502ea5fae2bdfe396d75662833e774c2c69f895..fa1c2f702f5173f36be76fe578f0b6290e78d9c1 100755 --- a/Source/Processors/SpikeDisplayNode/SpikeDisplayNode.cpp +++ b/Source/Processors/SpikeDisplayNode/SpikeDisplayNode.cpp @@ -58,12 +58,27 @@ void SpikeDisplayNode::updateSettings() electrodes.clear(); for (int i = 0; i < eventChannels.size(); i++) { - if ((eventChannels[i]->eventType < 999) && (eventChannels[i]->eventType > SPIKE_BASE_CODE)) + ChannelType type = eventChannels[i]->getType(); + + if (type == SINGLE_ELECTRODE || type == STEREOTRODE || type == TETRODE) { Electrode elec; - elec.numChannels = eventChannels[i]->eventType - 100; - elec.name = eventChannels[i]->name; + + switch (type) + { + case SINGLE_ELECTRODE: + elec.numChannels = 1; + break; + case STEREOTRODE: + elec.numChannels = 2; + break; + case TETRODE: + elec.numChannels = 4; + break; + } + + elec.name = eventChannels[i]->getName(); elec.currentSpikeIndex = 0; elec.mostRecentSpikes.ensureStorageAllocated(displayBufferSize); @@ -197,7 +212,7 @@ void SpikeDisplayNode::setParameter(int param, float val) -void SpikeDisplayNode::process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples) +void SpikeDisplayNode::process(AudioSampleBuffer& buffer, MidiBuffer& events) { checkForEvents(events); // automatically calls 'handleEvent diff --git a/Source/Processors/SpikeDisplayNode/SpikeDisplayNode.h b/Source/Processors/SpikeDisplayNode/SpikeDisplayNode.h index 2b630f7cd528e69656aa4eda757d92423435ef66..56f776aafb1ef0c97ea1a27893566286e1cc3e81 100755 --- a/Source/Processors/SpikeDisplayNode/SpikeDisplayNode.h +++ b/Source/Processors/SpikeDisplayNode/SpikeDisplayNode.h @@ -56,7 +56,7 @@ public: return true; } - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); void setParameter(int, float); diff --git a/Source/Processors/SpikeSorter/SpikeSorter.cpp b/Source/Processors/SpikeSorter/SpikeSorter.cpp index 6ca986f06f2d9d030cd31766d5f28518ae83230f..7e5205efb05a636635c0bbe1904141e3382739a5 100644 --- a/Source/Processors/SpikeSorter/SpikeSorter.cpp +++ b/Source/Processors/SpikeSorter/SpikeSorter.cpp @@ -188,20 +188,27 @@ void SpikeSorter::updateSettings() double ContinuousBufferLengthSec = 5; channelBuffers = new ContinuousCircularBuffer(numChannels,SamplingRate,1, ContinuousBufferLengthSec); - for (int i = 0; i < electrodes.size(); i++) - { + + for (int i = 0; i < electrodes.size(); i++) + { - Channel* ch = new Channel(this, i); - //ch->isEventChannel = true; - ch->eventType = SPIKE_BASE_CODE + electrodes[i]->numChannels; - ch->name = electrodes[i]->name; + Channel* ch; + + switch (electrodes[i]->numChannels) + { + case 1: + ch = new Channel(this, i, SINGLE_ELECTRODE); + break; + case 2: + ch = new Channel(this, i, STEREOTRODE); + break; + case 4: + ch = new Channel(this, i, TETRODE); + break; + } eventChannels.add(ch); - // String eventlog = "NewElectrode "+String(electrodes[k]->electrodeID) + " "+String(electrodes[k]->numChannels)+" "; - // for (int j=0;j<electrodes[k]->numChannels;j++) - // eventlog += String(electrodes[k]->channels[j])+ " "+electrodes[k]->name; - // //addNetworkEventToQueue(StringTS(eventlog)); - } + } mut.exit(); } @@ -216,7 +223,7 @@ Electrode::~Electrode() delete spikeSort; } -Electrode::Electrode(int ID, UniqueIDgenerator *uniqueIDgenerator_, PCAcomputingThread *pth, String _name, int _numChannels, int *_channels, float default_threshold, int pre, int post, float samplingRate ) +Electrode::Electrode(int ID, UniqueIDgenerator *uniqueIDgenerator_, PCAcomputingThread *pth, String _name, int _numChannels, int *_channels, float default_threshold, int pre, int post, float samplingRate , int sourceNodeId) { electrodeID = ID; computingThread = pth; @@ -400,7 +407,7 @@ void SpikeSorter::assignDACtoChannel(int dacOutput, int channel) RHD2000Thread* th = getRhythmAccess(); if (th != nullptr) { - th->setDACchannel(dacOutput, channels[channel]->originalStream, channels[channel]->originalChannel); + th->setDACchannel(dacOutput, channels[channel]->sourceNodeId, channels[channel]->index); // this is probably wrong (JHS) } } @@ -436,19 +443,19 @@ bool SpikeSorter::addElectrode(int nChans, String name, double Depth) return false; } - int *channels = new int[nChans]; + int *chans = new int[nChans]; for (int k = 0; k < nChans; k++) - channels[k] = firstChan + k; + chans[k] = firstChan + k; - Electrode* newElectrode = new Electrode(++uniqueID, &uniqueIDgenerator, &computingThread, name, nChans, channels, getDefaultThreshold(), - numPreSamples, numPostSamples, getSampleRate()); + Electrode* newElectrode = new Electrode(++uniqueID, &uniqueIDgenerator, &computingThread, name, nChans, chans, getDefaultThreshold(), + numPreSamples, numPostSamples, getSampleRate(), channels[chans[0]]->sourceNodeId); newElectrode->depthOffsetMM = Depth; String log = "Added electrode (ID "+ String(uniqueID)+") with " + String(nChans) + " channels." ; std::cout << log << std::endl; String eventlog = "NewElectrode "+ String(uniqueID) + " " + String(nChans) + " "; for (int k = 0; k < nChans; k++) - eventlog += String(channels[k])+ " " + name; + eventlog += String(chans[k])+ " " + name; //addNetworkEventToQueue(StringTS(eventlog)); @@ -635,7 +642,12 @@ void SpikeSorter::setParameter(int parameterIndex, float newValue) bool SpikeSorter::enable() { - useOverflowBuffer = false; + useOverflowBuffer.clear(); + + for (int i = 0; i < electrodes.size(); i++) + useOverflowBuffer.add(false); + + SpikeSorterEditor* editor = (SpikeSorterEditor*) getEditor(); editor->enable(); @@ -705,7 +717,7 @@ void SpikeSorter::addWaveformToSpikeObject(SpikeObject* s, int chan = *(electrodes[electrodeNumber]->channels+currentChannel); - s->gain[currentChannel] = (1.0f / channels[chan]->getChannelGain())*1000; + s->gain[currentChannel] = (1.0f / channels[chan]->bitVolts)*1000; s->threshold[currentChannel] = (int) electrodes[electrodeNumber]->thresholds[currentChannel]; // cycle through buffer @@ -719,7 +731,7 @@ void SpikeSorter::addWaveformToSpikeObject(SpikeObject* s, // warning -- be careful of bitvolts conversion // do not flip signal (!). float value = getNextSample(electrodes[electrodeNumber]->channels[currentChannel]); - s->data[currentIndex] = uint16(jmin(65535,jmax(0, int(value / channels[chan]->getChannelGain()) + 32768))); + s->data[currentIndex] = uint16(jmin(65535,jmax(0, int(value / channels[chan]->bitVolts) + 32768))); // recovered data //float value2 = (s->data[currentIndex]-32768) /float(s->gain[currentChannel])*1000.0f; @@ -845,8 +857,7 @@ void SpikeSorter::handleEvent(int eventType, MidiMessage& event, int sampleNum) // } void SpikeSorter::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { //printf("Entering Spike Detector::process\n"); @@ -858,9 +869,7 @@ void SpikeSorter::process(AudioSampleBuffer& buffer, checkForEvents(events); // find latest's packet timestamps - //postEventsInQueue(events); - - channelBuffers->update(buffer, hardware_timestamp,software_timestamp,nSamples); + //channelBuffers->update(buffer, hardware_timestamp,software_timestamp, nSamples); for (int i = 0; i < electrodes.size(); i++) { @@ -873,6 +882,8 @@ void SpikeSorter::process(AudioSampleBuffer& buffer, sampleIndex = electrode->lastBufferIndex - 1; // subtract 1 to account for // increment at start of getNextSample() + int nSamples = getNumSamples(*electrode->channels); // get the number of samples for this buffer + // cycle through samples while (samplesAvailable(nSamples)) { @@ -1003,39 +1014,28 @@ void SpikeSorter::process(AudioSampleBuffer& buffer, //jassert(electrode->lastBufferIndex < 0); - } // end cycle through electrodes - - // copy end of this buffer into the overflow buffer + if (nSamples > overflowBufferSize) + { - //std::cout << "Copying buffer" << std::endl; - // std::cout << "nSamples: " << nSamples; - //std::cout << "overflowBufferSize:" << overflowBufferSize; + for (int j = 0; j < electrode->numChannels; j++) + { - //std::cout << "sourceStartSample = " << nSamples-overflowBufferSize << std::endl; - // std::cout << "numSamples = " << overflowBufferSize << std::endl; - // std::cout << "buffer size = " << buffer.getNumSamples() << std::endl; + overflowBuffer.copyFrom(*electrode->channels+i, 0, + buffer, *electrode->channels+i, + nSamples-overflowBufferSize, + overflowBufferSize); + + } - if (nSamples > overflowBufferSize) - { + useOverflowBuffer.set(i, true); - for (int i = 0; i < overflowBuffer.getNumChannels(); i++) + } + else { - - overflowBuffer.copyFrom(i, 0, - buffer, i, - nSamples-overflowBufferSize, - overflowBufferSize); - - - useOverflowBuffer = true; + useOverflowBuffer.set(i, false); } - } - else - { - - useOverflowBuffer = false; - } + } // end cycle through electrodes mut.exit(); @@ -1103,7 +1103,7 @@ float SpikeSorter::getCurrentSample(int& chan) } -bool SpikeSorter::samplesAvailable(int& nSamples) +bool SpikeSorter::samplesAvailable(int nSamples) { if (sampleIndex > nSamples - overflowBufferSize/2) @@ -1328,8 +1328,11 @@ void SpikeSorter::loadCustomParametersFromXml() isActive[channelIndex] = channelNode->getBoolAttribute("isActive"); } } + + int sourceNodeId = 102010; // some number + Electrode* newElectrode = new Electrode(electrodeID, &uniqueIDgenerator,&computingThread, electrodeName, channelsPerElectrode, channels,getDefaultThreshold(), - numPreSamples,numPostSamples, getSampleRate()); + numPreSamples,numPostSamples, getSampleRate(), sourceNodeId); for (int k=0;k<channelsPerElectrode;k++) { newElectrode->thresholds[k] = thres[k]; diff --git a/Source/Processors/SpikeSorter/SpikeSorter.h b/Source/Processors/SpikeSorter/SpikeSorter.h index d5dff6e048d433b4644164982534f4650e5d08b4..bb520b868bc464251a657df3025aa9c8c03f8af9 100644 --- a/Source/Processors/SpikeSorter/SpikeSorter.h +++ b/Source/Processors/SpikeSorter/SpikeSorter.h @@ -84,7 +84,7 @@ private: class Electrode { public: - Electrode(int electrodeID, UniqueIDgenerator *uniqueIDgenerator_, PCAcomputingThread *pth,String _name, int _numChannels, int *_channels, float default_threshold, int pre, int post, float samplingRate ); + Electrode(int electrodeID, UniqueIDgenerator *uniqueIDgenerator_, PCAcomputingThread *pth,String _name, int _numChannels, int *_channels, float default_threshold, int pre, int post, float samplingRate , int sourceNodeId); ~Electrode(); void resizeWaveform(int numPre, int numPost); @@ -99,6 +99,7 @@ class Electrode float depthOffsetMM; int electrodeID; + int sourceNodeId; int* channels; double* thresholds; bool* isActive; @@ -161,7 +162,7 @@ public: /** Processes an incoming continuous buffer and places new spikes into the event buffer. */ - void process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& events); /** Used to alter parameters of data acquisition. */ void setParameter(int parameterIndex, float newValue); @@ -338,9 +339,9 @@ private: std::vector<int> electrodeCounter; float getNextSample(int& chan); float getCurrentSample(int& chan); - bool samplesAvailable(int& nSamples); + bool samplesAvailable(int nSamples); - bool useOverflowBuffer; + Array<bool> useOverflowBuffer; int currentElectrode; int currentChannelIndex; diff --git a/Source/Processors/Splitter/Splitter.h b/Source/Processors/Splitter/Splitter.h index 12a6f80bbd87a62a9678b8d2f80c97cd9e8e62b2..76a18a6dff84607ccf7062cad19f421cff080fc1 100755 --- a/Source/Processors/Splitter/Splitter.h +++ b/Source/Processors/Splitter/Splitter.h @@ -53,7 +53,7 @@ public: AudioProcessorEditor* createEditor(); /** Nothing happens here, because Splitters are not part of the ProcessorGraph. */ - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples) {} + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages) {} bool isSplitter() { diff --git a/Source/Processors/WiFiOutput/WiFiOutput.cpp b/Source/Processors/WiFiOutput/WiFiOutput.cpp index cf52d9091b5601fa19203942704b571b474ff1d0..9e56b84293e795d8ef57766ec61051b6991a6cae 100755 --- a/Source/Processors/WiFiOutput/WiFiOutput.cpp +++ b/Source/Processors/WiFiOutput/WiFiOutput.cpp @@ -56,8 +56,7 @@ void WiFiOutput::setParameter(int parameterIndex, float newValue) } void WiFiOutput::process(AudioSampleBuffer& buffer, - MidiBuffer& events, - int& nSamples) + MidiBuffer& events) { diff --git a/Source/Processors/WiFiOutput/WiFiOutput.h b/Source/Processors/WiFiOutput/WiFiOutput.h index b2d35d436249bd967b18406c9c58341c6cf52cfe..bf6a7dbc3660f86a79a25cd0d306a52c66e7b742 100755 --- a/Source/Processors/WiFiOutput/WiFiOutput.h +++ b/Source/Processors/WiFiOutput/WiFiOutput.h @@ -51,7 +51,7 @@ public: WiFiOutput(); ~WiFiOutput(); - void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages, int& nSamples); + void process(AudioSampleBuffer& buffer, MidiBuffer& events); void setParameter(int parameterIndex, float newValue); void handleEvent(int eventType, MidiMessage& event, int sampleNum); diff --git a/Source/UI/EditorViewport.cpp b/Source/UI/EditorViewport.cpp index cae581e6d70475cd50832179937a61863d7a1795..ff2724befd9b58c892eb3005f6ca54d0fa05f1e7 100755 --- a/Source/UI/EditorViewport.cpp +++ b/Source/UI/EditorViewport.cpp @@ -1379,6 +1379,7 @@ const String EditorViewport::saveState(File fileToUse) getControlPanel()->saveStateToXml(xml); // save the control panel settings getProcessorList()->saveStateToXml(xml); + getMessageCenter()->saveStateToXml(xml); getUIComponent()->saveStateToXml(xml); // save the UI settings if (! xml->writeToFile(currentFile, String::empty)) @@ -1586,6 +1587,7 @@ const String EditorViewport::loadState(File fileToLoad) getControlPanel()->loadStateFromXml(xml); // save the control panel settings getProcessorList()->loadStateFromXml(xml); + getMessageCenter()->loadStateFromXml(xml); getUIComponent()->loadStateFromXml(xml); // save the UI settings if (editorArray.size() > 0) diff --git a/open-ephys.jucer b/open-ephys.jucer index 448f83415e12b6bd01c0afc4d883b30593b3821f..b432a75a756fb9126161eb3948a24a5a656c643e 100644 --- a/open-ephys.jucer +++ b/open-ephys.jucer @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<JUCERPROJECT id="ynSYIrr" name="open-ephys" projectType="guiapp" version="0.3.3" +<JUCERPROJECT id="ynSYIrr" name="open-ephys" projectType="guiapp" version="0.3.4" juceLinkage="amalg_multi" buildVST="1" buildRTAS="0" buildAU="1" pluginName="Juce Project" pluginDesc="Juce Project" pluginManufacturer="yourcompany" pluginManufacturerCode="Manu" pluginCode="Plug" pluginChannelConfigs="{1, 1}, {2, 2}" @@ -296,12 +296,6 @@ <FILE id="jClaJf" name="AudioNode.cpp" compile="1" resource="0" file="Source/Processors/AudioNode/AudioNode.cpp"/> <FILE id="LHkdoG" name="AudioNode.h" compile="0" resource="0" file="Source/Processors/AudioNode/AudioNode.h"/> </GROUP> - <GROUP id="{ED1C2AFE-2ED9-D835-532A-4D6C558C73E7}" name="AudioResamplingNode"> - <FILE id="YStaN1" name="AudioResamplingNode.cpp" compile="1" resource="0" - file="Source/Processors/AudioResamplingNode/AudioResamplingNode.cpp"/> - <FILE id="pnFZDY" name="AudioResamplingNode.h" compile="0" resource="0" - file="Source/Processors/AudioResamplingNode/AudioResamplingNode.h"/> - </GROUP> <GROUP id="{46016F19-8F25-F540-AA1C-D6E87E8D7D31}" name="Channel"> <FILE id="X3I3e9" name="Channel.cpp" compile="1" resource="0" file="Source/Processors/Channel/Channel.cpp"/> <FILE id="IEZGF3" name="Channel.h" compile="0" resource="0" file="Source/Processors/Channel/Channel.h"/> @@ -346,12 +340,6 @@ file="Source/Processors/DataThreads/RHD2000Thread.cpp"/> <FILE id="BbYdtBN" name="RHD2000Thread.h" compile="0" resource="0" file="Source/Processors/DataThreads/RHD2000Thread.h"/> - <FILE id="xWMgZ8D" name="FileReaderThread.cpp" compile="1" resource="0" - file="Source/Processors/DataThreads/FileReaderThread.cpp"/> - <FILE id="muolub6" name="FileReaderThread.h" compile="0" resource="0" - file="Source/Processors/DataThreads/FileReaderThread.h"/> - <FILE id="KEzbFux" name="FPGAThread.cpp" compile="1" resource="0" file="Source/Processors/DataThreads/FPGAThread.cpp"/> - <FILE id="6iEndcT" name="FPGAThread.h" compile="0" resource="0" file="Source/Processors/DataThreads/FPGAThread.h"/> <FILE id="Qfe0ygk" name="DataBuffer.cpp" compile="1" resource="0" file="Source/Processors/DataThreads/DataBuffer.cpp"/> <FILE id="VCRMcQP" name="DataBuffer.h" compile="0" resource="0" file="Source/Processors/DataThreads/DataBuffer.h"/> <FILE id="9JbVKlA" name="DataThread.cpp" compile="1" resource="0" file="Source/Processors/DataThreads/DataThread.cpp"/> @@ -463,14 +451,6 @@ <FILE id="usXu7Q" name="FilterNode.cpp" compile="1" resource="0" file="Source/Processors/FilterNode/FilterNode.cpp"/> <FILE id="qnkW8d" name="FilterNode.h" compile="0" resource="0" file="Source/Processors/FilterNode/FilterNode.h"/> </GROUP> - <GROUP id="{C47ABFBD-BC30-F6F2-B445-67B11DC5594F}" name="FPGAOutput"> - <FILE id="DY6GL1" name="FPGAOutput.cpp" compile="1" resource="0" file="Source/Processors/FPGAOutput/FPGAOutput.cpp"/> - <FILE id="CdbTqf" name="FPGAOutput.h" compile="0" resource="0" file="Source/Processors/FPGAOutput/FPGAOutput.h"/> - <FILE id="tH5H69" name="FPGAOutputEditor.cpp" compile="1" resource="0" - file="Source/Processors/FPGAOutput/FPGAOutputEditor.cpp"/> - <FILE id="e1ivPs" name="FPGAOutputEditor.h" compile="0" resource="0" - file="Source/Processors/FPGAOutput/FPGAOutputEditor.h"/> - </GROUP> <GROUP id="{95FA3CAF-7BFA-AFF7-4480-EADCCA5FBA66}" name="GenericProcessor"> <FILE id="l24v5k" name="GenericProcessor.cpp" compile="1" resource="0" file="Source/Processors/GenericProcessor/GenericProcessor.cpp"/> @@ -491,20 +471,6 @@ <FILE id="rKu45v" name="LfpDisplayNode.h" compile="0" resource="0" file="Source/Processors/LfpDisplayNode/LfpDisplayNode.h"/> </GROUP> - <GROUP id="{D20DFFFD-08E8-5CC6-479A-07CECDE9BC86}" name="LfpTriggeredAverageNode"> - <FILE id="dxKyFx" name="LfpTriggeredAverageCanvas.cpp" compile="1" - resource="0" file="Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageCanvas.cpp"/> - <FILE id="CMxAvm" name="LfpTriggeredAverageCanvas.h" compile="0" resource="0" - file="Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageCanvas.h"/> - <FILE id="VhsonN" name="LfpTriggeredAverageEditor.cpp" compile="1" - resource="0" file="Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageEditor.cpp"/> - <FILE id="jVc0dD" name="LfpTriggeredAverageEditor.h" compile="0" resource="0" - file="Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageEditor.h"/> - <FILE id="ADrDsi" name="LfpTriggeredAverageNode.cpp" compile="1" resource="0" - file="Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.cpp"/> - <FILE id="wEt96B" name="LfpTriggeredAverageNode.h" compile="0" resource="0" - file="Source/Processors/LfpTriggeredAverageNode/LfpTriggeredAverageNode.h"/> - </GROUP> <GROUP id="{4B40CAAE-49C7-509A-B7E7-0C7EF011FBA1}" name="Merger"> <FILE id="gZxAmt" name="Merger.cpp" compile="1" resource="0" file="Source/Processors/Merger/Merger.cpp"/> <FILE id="w8qwHK" name="Merger.h" compile="0" resource="0" file="Source/Processors/Merger/Merger.h"/> @@ -602,15 +568,6 @@ <FILE id="fDpocU" name="TrialCircularBuffer.h" compile="0" resource="0" file="Source/Processors/PSTH/TrialCircularBuffer.h"/> </GROUP> - <GROUP id="{B0C14DBE-8CC1-F242-3534-1DFBEAC5E43B}" name="ReferenceNode"> - <FILE id="F7WTBV" name="ReferenceNode.cpp" compile="1" resource="0" - file="Source/Processors/ReferenceNode/ReferenceNode.cpp"/> - <FILE id="XyYPUn" name="ReferenceNode.h" compile="0" resource="0" file="Source/Processors/ReferenceNode/ReferenceNode.h"/> - <FILE id="tsfK4e" name="ReferenceNodeEditor.cpp" compile="1" resource="0" - file="Source/Processors/ReferenceNode/ReferenceNodeEditor.cpp"/> - <FILE id="virGvM" name="ReferenceNodeEditor.h" compile="0" resource="0" - file="Source/Processors/ReferenceNode/ReferenceNodeEditor.h"/> - </GROUP> <GROUP id="{C6F1F354-C97E-128E-9C4E-2376E039F233}" name="ResamplingNode"> <FILE id="yIwQ4b" name="ResamplingNode.cpp" compile="1" resource="0" file="Source/Processors/ResamplingNode/ResamplingNode.cpp"/> @@ -714,14 +671,6 @@ <FILE id="EH2pAq" name="MatlabLikePlot.h" compile="0" resource="0" file="Source/Processors/Visualization/MatlabLikePlot.h"/> </GROUP> - <GROUP id="{3FCFBFDA-848D-6B59-5F37-E3D1F43D54DF}" name="WiFiOutput"> - <FILE id="OmOeLf" name="WiFiOutput.cpp" compile="1" resource="0" file="Source/Processors/WiFiOutput/WiFiOutput.cpp"/> - <FILE id="o3arNv" name="WiFiOutput.h" compile="0" resource="0" file="Source/Processors/WiFiOutput/WiFiOutput.h"/> - <FILE id="XSiAk6" name="WiFiOutputEditor.cpp" compile="1" resource="0" - file="Source/Processors/WiFiOutput/WiFiOutputEditor.cpp"/> - <FILE id="QdKqgJ" name="WiFiOutputEditor.h" compile="0" resource="0" - file="Source/Processors/WiFiOutput/WiFiOutputEditor.h"/> - </GROUP> </GROUP> <GROUP id="RNGb1yR" name="UI"> <FILE id="PBkkUW" name="EcubeDialogComponent.cpp" compile="1" resource="0"