Skip to content
Snippets Groups Projects
RecordNode.h 4.73 KiB
/*
    ------------------------------------------------------------------

    This file is part of the Open Ephys GUI
    Copyright (C) 2012 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__


#ifdef WIN32
#include <Windows.h>
#endif
#include "../../JuceLibraryCode/JuceHeader.h"
#include <stdio.h>
#include <map>

#include "GenericProcessor.h"

/**

  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);
  void addInputChannel(GenericProcessor* sourceNode, int chan);

	bool enable();
	bool disable();

  /** 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(int id, int chan);

  /** Turns recording on and off for a particular channel.

      Channel numbers are absolute (based on RecordNode channel mapping).
  */
  void setChannelStatus(int chan, bool status);

  /** Used to clear all connections prior to the start of acquisition.
  */
  void resetConnections();

  /** Overrides implementation by GenericProcessor.
  */
 // bool isAudioOrRecordNode() {return true;}

  /** 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();
	
private:

  /** Keep the RecordNode informed of acquisition and record states. 
  */
	bool isRecording, 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;

  /** Holds data that has been converted from float to int16 before
      saving. 
  */
  int16* continuousDataIntegerBuffer;

  /** Holds data that has been converted from float to int16 before
      saving. 
  */
  float* continuousDataFloatBuffer;

  /** Integer timestamp saved for each buffer. 
  */ 
  int64 timestamp;

  /** Used to generate timestamps if none are given. 
  */ 
  Time timer;

  /** Holds information for a given channel to be recorded to 
      its own file.
  */ 
  struct Channel
  {
    int nodeId;
    int chan;
    String name;
    bool isRecording;
    String filename;
    FILE* file;
  };

  /** Closes all open files after recording has finished.
  */ 
  void closeAllFiles();

  /** Map of continuous channels. 
  */ 
  std::map<int, Channel> continuousChannels;

  /** Map of event channels. 
  */ 
  std::map<int, std::map<int,Channel> > eventChannels;

  /** Method for writing continuous buffers to disk. 
  */ 
  void writeContinuousBuffer(float* data, int nSamples, int channel);
  
  /** Method for writing event buffers to disk. 
  */ 
  void writeEventBuffer(MidiMessage& event, int node, int channel);

	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RecordNode);

};



#endif  // __RECORDNODE_H_FB9B1CA7__