RecordNode.h 6.92 KiB
/*
------------------------------------------------------------------
This file is part of the Open Ephys GUI
Copyright (C) 2013 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 __RECORDNODE_H_FB9B1CA7__
#define __RECORDNODE_H_FB9B1CA7__
#include "../../JuceLibraryCode/JuceHeader.h"
#include <stdio.h>
#include <map>
#include "GenericProcessor.h"
#include "Channel.h"
#include "RecordEngine.h"
#define HEADER_SIZE 1024
#define BLOCK_LENGTH 1024
/**
Receives inputs from all processors that want to save their data.
Writes data to disk using fwrite.
Receives a signal from the ControlPanel to begin recording.
@see GenericProcessor, ControlPanel
*/
class RecordNode : public GenericProcessor,
public FilenameComponentListener
{
public:
RecordNode();
~RecordNode();
/** Handle incoming data and decide which files and events to write to disk.
*/
void process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer, int& nSamples);
/** Overrides implementation in GenericProcessor; used to change recording parameters
on the fly.
parameterIndex = 0: stop recording
parameterIndex = 1: start recording
parameterIndex = 2:
newValue = 0: turn off recording for current channel
newValue = 1: turn on recording for current channel
*/
void setParameter(int parameterIndex, float newValue);
/** 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
*/
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);
/** update channel name */
void updateChannelName(int channelIndex, String newname);
/** Get channel stored in channelPointers array
*/
Channel* getDataChannel(int index);
/** Called by the ControlPanel to determine the amount of space
left in the current dataDirectory.
*/
float getFreeSpace();
/** Selects a channel relative to a particular processor with ID = id
*/
void setChannel(Channel* ch);
/** Turns recording on and off for a particular channel.
Channel numbers are absolute (based on RecordNode channel mapping).
*/
void setChannelStatus(Channel* ch, bool status);
/** Used to clear all connections prior to the start of acquisition.
*/
void resetConnections();
/** Callback to indicate when user has chosen a new data directory.
*/
void filenameComponentChanged(FilenameComponent*);
/** Creates a new data directory in the location specified by the fileNameComponent.
*/
void createNewDirectory();
File getDataDirectory()
{
return rootFolder;
}
void appendTrialNumber(bool);
void updateTrialNumber();
/** Adds a Record Engine to use
*/
void registerRecordEngine(RecordEngine* engine);
/** Clears the list of active Record Engines
*/
void clearRecordEngines();
/** 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
*/
int addSpikeElectrode(SpikeRecordInfo* elec);
/** Called by a spike recording source to write a spike to file
*/
void writeSpike(SpikeObject& spike, int electrodeIndex);
SpikeRecordInfo* getSpikeElectrode(int index);
/** Signals when to create a new data directory when recording starts.*/
bool newDirectoryNeeded;
bool isRecording;
bool allFilesOpened;
/** Generate a Matlab-compatible datestring */
String generateDateString();
private:
/** Keep the RecordNode informed of acquisition and record states.
*/
bool isProcessing, signalFilesShouldClose;
/** User-selectable directory for saving data files. Currently
defaults to the user's home directory.
*/
File dataDirectory;
/** Automatically generated folder for each recording session.
*/
File rootFolder;
/** Integer timestamp saved for each buffer.
*/
int64 timestamp;
/** Integer to keep track of number of recording sessions in the same file */
uint16 recordingNumber;
/** Used to generate timestamps if none are given.
*/
Time timer;
/** Closes all open files after recording has finished.
*/
void closeAllFiles();
/** Pointers to all continuous channels */
Array<Channel*> channelPointers;
/** Pointers to all event channels */
Array<Channel*> eventChannelPointers;
OwnedArray<SpikeRecordInfo> spikeElectrodePointers;
int spikeElectrodeIndex;
int experimentNumber;
bool hasRecorded;
/** Generates a default directory name, based on the current date and time */
String generateDirectoryName();
/** Cycle through the event buffer, looking for data to save */
void handleEvent(int eventType, MidiMessage& event, int samplePos);
/** Object for holding information about the events file */
Channel* eventChannel;
/** Method for writing continuous buffers to disk.
*/
void writeContinuousBuffer(const float* data, int nSamples, int channel);
/** Method for writing event buffers to disk.
*/
void writeEventBuffer(MidiMessage& event, int samplePos);
void writeRecordMarker(FILE*);
void writeTimestampAndSampleCount(FILE*);
/** Used to indicate the end of each record */
char* recordMarker;
CriticalSection diskWriteLock;
Array<String> modifiedChannelNames;
Array<int> modifiedChannelInd;
bool appendTrialNum;
int trialNum;
/**RecordEngines loaded**/
OwnedArray<RecordEngine> engineArray;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RecordNode);
};
#endif // __RECORDNODE_H_FB9B1CA7__