/* ------------------------------------------------------------------ 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/>. */ #include "FileReader.h" #include "Editors/FileReaderEditor.h" #include <stdio.h> FileReader::FileReader() : GenericProcessor("File Reader") { input = 0; timestamp = 0; enabledState(false); } FileReader::~FileReader() { if (input) fclose(input); } AudioProcessorEditor* FileReader::createEditor() { editor = new FileReaderEditor(this, true); return editor; } bool FileReader::isReady() { if (input == 0) { sendActionMessage("No file selected in File Reader."); return false; } else { return true; } } float FileReader::getDefaultSampleRate() { return 40000.0f; } int FileReader::getDefaultNumOutputs() { return 16; } float FileReader::getDefaultBitVolts() { return 0.05f; } void FileReader::enabledState(bool t) { isEnabled = t; } void FileReader::setFile(String fullpath) { filePath = fullpath; const char* path = filePath.getCharPointer(); if (input) fclose(input); input = fopen(path, "rb"); // Avoid a segfault if file isn't found if (!input) { std::cout << "Can't find data file " << '"' << path << "\"" << std::endl; return; } fseek(input, 0, SEEK_END); lengthOfInputFile = ftell(input); rewind(input); } String FileReader::getFile() { return filePath; } void FileReader::updateSettings() { } void FileReader::process(AudioSampleBuffer& buffer, MidiBuffer& events, int& nSamples) { uint8 data[8]; memcpy(data, ×tamp, 8); // generate timestamp addEvent(events, // MidiBuffer TIMESTAMP, // eventType 0, // sampleNum nodeId, // eventID 0, // eventChannel 8, // numBytes data // data ); // FIXME: needs to account for the fact that the ratio might not be an exact // integer value int samplesNeeded = (int) float(buffer.getNumSamples()) * (getDefaultSampleRate()/44100.0f); if (ftell(input) >= lengthOfInputFile - samplesNeeded) { rewind(input); } size_t numRead = fread(readBuffer, 2, samplesNeeded*buffer.getNumChannels(), input); int chan = 0; int samp = 0; for (size_t n = 0; n < numRead; n++) { if (chan == buffer.getNumChannels()) { samp++; timestamp++; chan = 0; } int16 sample = readBuffer[n]; #ifdef JUCE_WINDOWS //-- big-endian format // reverse the byte order // float sample_f; // AudioDataConverters::convertInt16BEToFloat(&readBuffer[n], &sample_f, 1); #endif *buffer.getSampleData(chan++, samp) = -sample * getDefaultBitVolts(); } nSamples = samplesNeeded; } void FileReader::setParameter(int parameterIndex, float newValue) { } void FileReader::saveCustomParametersToXml(XmlElement* parentElement) { XmlElement* childNode = parentElement->createNewChildElement("FILENAME"); childNode->setAttribute("path", getFile()); } void FileReader::loadCustomParametersFromXml() { if (parametersAsXml != nullptr) { // use parametersAsXml to restore state forEachXmlChildElement(*parametersAsXml, xmlNode) { if (xmlNode->hasTagName("FILENAME")) { String filepath = xmlNode->getStringAttribute("path"); FileReaderEditor* fre = (FileReaderEditor*) getEditor(); fre->setFile(filepath); } } } }