From 3f4aa3c4e9a0f5a5d36393225bc9920efa4f75f5 Mon Sep 17 00:00:00 2001
From: Aaron Cuevas Lopez <aacuelo@teleco.upv.es>
Date: Thu, 14 Apr 2016 23:39:35 +0200
Subject: [PATCH] Fix crashes

---
 .../RecordEngine/HDF5FileFormat.cpp           |  5 ++--
 .../KWIKFormat/RecordEngine/HDF5FileFormat.h  |  3 +-
 .../KWIKFormat/RecordEngine/HDF5Recording.cpp | 29 ++++++++++++-------
 .../KWIKFormat/RecordEngine/HDF5Recording.h   |  7 +++--
 .../DataThreads/RhythmNode/RHD2000Thread.cpp  | 12 ++++----
 .../GenericProcessor/GenericProcessor.cpp     |  2 +-
 .../MessageCenter/MessageCenter.cpp           |  4 +--
 Source/Processors/RecordNode/RecordNode.cpp   |  4 +--
 Source/Processors/RecordNode/RecordThread.cpp |  2 ++
 9 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp
index e2c449ba0..ef5c5e1bc 100644
--- a/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp
+++ b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp
@@ -893,18 +893,17 @@ KWXFile::KWXFile(String basename) : HDF5FileBase()
 {
     initFile(basename);
     numElectrodes=0;
-    transformVector = new int16[MAX_TRANSFORM_SIZE];
+    transformVector.malloc(MAX_TRANSFORM_SIZE);
 }
 
 KWXFile::KWXFile() : HDF5FileBase()
 {
     numElectrodes=0;
-    transformVector = new int16[MAX_TRANSFORM_SIZE];
+    transformVector.malloc(MAX_TRANSFORM_SIZE);
 }
 
 KWXFile::~KWXFile()
 {
-    delete transformVector;
 }
 
 String KWXFile::getFileName()
diff --git a/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h
index f98748373..a9ab171d8 100644
--- a/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h
+++ b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h
@@ -205,7 +205,8 @@ private:
     OwnedArray<HDF5RecordingData> timeStamps;
     Array<int> channelArray;
     int numElectrodes;
-    int16* transformVector;
+	HeapBlock<int16> transformVector;
+    //int16* transformVector;
 
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWXFile);
 };
diff --git a/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp
index b337df0c9..3de43b2ab 100644
--- a/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp
+++ b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp
@@ -22,21 +22,19 @@
  */
 
 #include "HDF5Recording.h"
-#define MAX_BUFFER_SIZE 10000
+#define MAX_BUFFER_SIZE 40960
 #define CHANNEL_TIMESTAMP_PREALLOC_SIZE 16
 #define TIMESTAMP_EACH_NSAMPLES 1024
 
-HDF5Recording::HDF5Recording() : processorIndex(-1), hasAcquired(false)
+HDF5Recording::HDF5Recording() : processorIndex(-1), hasAcquired(false), bufferSize(MAX_BUFFER_SIZE)
 {
     //timestamp = 0;
-    scaledBuffer = new float[MAX_BUFFER_SIZE];
-    intBuffer = new int16[MAX_BUFFER_SIZE];
+    scaledBuffer.malloc(MAX_BUFFER_SIZE);
+    intBuffer.malloc(MAX_BUFFER_SIZE);
 }
 
 HDF5Recording::~HDF5Recording()
-{
-    delete scaledBuffer;
-    delete intBuffer;
+{	
 }
 
 String HDF5Recording::getEngineID() const
@@ -67,6 +65,9 @@ void HDF5Recording::registerProcessor(const GenericProcessor* proc)
 
 void HDF5Recording::resetChannels()
 {
+	scaledBuffer.malloc(MAX_BUFFER_SIZE);
+	intBuffer.malloc(MAX_BUFFER_SIZE);
+	bufferSize = MAX_BUFFER_SIZE;
     processorIndex = -1;
     fileArray.clear();
 	channelsPerProcessor.clear();
@@ -173,6 +174,7 @@ void HDF5Recording::closeFiles()
     {
         if (fileArray[i]->isOpen())
         {
+			std::cout << "Closed file " << i << std::endl;
             fileArray[i]->stopRecording();
             fileArray[i]->close();
             bitVoltsArray[i]->clear();
@@ -196,11 +198,18 @@ void HDF5Recording::startChannelBlock()
 
 void HDF5Recording::writeData(int writeChannel, int realChannel, const float* buffer, int size)
 {
+	if (size > bufferSize) //Shouldn't happen, and if it happens it'll be slow, but better this than crashing. Will be reset on reset.
+	{
+		std::cerr << "Write buffer overrun, resizing to" << size << std::endl;
+		bufferSize = size;
+		scaledBuffer.malloc(size);
+		intBuffer.malloc(size);
+	}
 	double multFactor = 1 / (float(0x7fff) * getChannel(realChannel)->bitVolts);
 	int index = processorMap[getChannel(realChannel)->recordIndex];
-	FloatVectorOperations::copyWithMultiply(scaledBuffer, buffer, multFactor, size);
-	AudioDataConverters::convertFloatToInt16LE(scaledBuffer, intBuffer, size);
-	fileArray[index]->writeRowData(intBuffer, size, recordedChanToKWDChan[writeChannel]);
+	FloatVectorOperations::copyWithMultiply(scaledBuffer.getData(), buffer, multFactor, size);
+	AudioDataConverters::convertFloatToInt16LE(scaledBuffer.getData(), intBuffer.getData(), size);
+	fileArray[index]->writeRowData(intBuffer.getData(), size, recordedChanToKWDChan[writeChannel]);
 
 	int sampleOffset = channelLeftOverSamples[writeChannel];
 	int blockStart = sampleOffset;
diff --git a/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h
index cc0ac27b9..7364746c3 100644
--- a/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h
+++ b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h
@@ -62,8 +62,11 @@ private:
     OwnedArray<HDF5RecordingInfo> infoArray;
     ScopedPointer<KWEFile> eventFile;
     ScopedPointer<KWXFile> spikesFile;
-    float* scaledBuffer;
-    int16* intBuffer;
+	HeapBlock<float> scaledBuffer;
+	HeapBlock<int16> intBuffer;
+	int bufferSize;
+    //float* scaledBuffer;
+    //int16* intBuffer;
 
     bool hasAcquired;
 
diff --git a/Source/Processors/DataThreads/RhythmNode/RHD2000Thread.cpp b/Source/Processors/DataThreads/RhythmNode/RHD2000Thread.cpp
index c76639c60..b73e8a067 100644
--- a/Source/Processors/DataThreads/RhythmNode/RHD2000Thread.cpp
+++ b/Source/Processors/DataThreads/RhythmNode/RHD2000Thread.cpp
@@ -44,8 +44,8 @@
 #define REGISTER_59_MISO_B  58
 #define RHD2132_16CH_OFFSET 8
 
-//#define DEBUG_EMULATE_HEADSTAGES 8
-//#define DEBUG_EMULATE_64CH
+#define DEBUG_EMULATE_HEADSTAGES 8
+#define DEBUG_EMULATE_64CH
 
 #define INIT_STEP ( evalBoard->isUSB3() ? 256 : 60)
 
@@ -188,10 +188,10 @@ RHD2000Thread::~RHD2000Thread()
 
     //deleteAndZero(dataBlock);
 
-    delete dacStream;
-    delete dacChannels;
-    delete dacThresholds;
-    delete dacChannelsToUpdate;
+    delete[] dacStream;
+    delete[] dacChannels;
+    delete[] dacThresholds;
+    delete[] dacChannelsToUpdate;
 
 }
 
diff --git a/Source/Processors/GenericProcessor/GenericProcessor.cpp b/Source/Processors/GenericProcessor/GenericProcessor.cpp
index ffc990e41..90e34c315 100755
--- a/Source/Processors/GenericProcessor/GenericProcessor.cpp
+++ b/Source/Processors/GenericProcessor/GenericProcessor.cpp
@@ -632,7 +632,7 @@ void GenericProcessor::setTimestamp(MidiBuffer& events, int64 timestamp)
                  0,
                  0,
                  0,
-                 data.length() + 1, //It doesn't hurt to send the end-string null and can help avoid issues
+                 data.sizeInBytes(), //It doesn't hurt to send the end-string null and can help avoid issues
                  (uint8*)data.getAddress(),
                  true);
 
diff --git a/Source/Processors/MessageCenter/MessageCenter.cpp b/Source/Processors/MessageCenter/MessageCenter.cpp
index 2f4540c72..ba17df9bb 100644
--- a/Source/Processors/MessageCenter/MessageCenter.cpp
+++ b/Source/Processors/MessageCenter/MessageCenter.cpp
@@ -134,7 +134,7 @@ void MessageCenter::process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer)
                  0,
                  0,
                  0,
-                 data.length() + 1, //It doesn't hurt to send the end-string null and can help avoid issues
+                 data.sizeInBytes(), //It doesn't hurt to send the end-string null and can help avoid issues
                  (uint8*)data.getAddress());
 
         needsToSendTimestampMessage = false;
@@ -153,7 +153,7 @@ void MessageCenter::process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer)
                  0,
                  0,
                  0,
-                 data.length()+1, //It doesn't hurt to send the end-string null and can help avoid issues
+                 data.sizeInBytes(), //It doesn't hurt to send the end-string null and can help avoid issues
                  (uint8*) data.getAddress());
 
         newEventAvailable = false;
diff --git a/Source/Processors/RecordNode/RecordNode.cpp b/Source/Processors/RecordNode/RecordNode.cpp
index b41604eab..8e56c9b82 100755
--- a/Source/Processors/RecordNode/RecordNode.cpp
+++ b/Source/Processors/RecordNode/RecordNode.cpp
@@ -334,7 +334,7 @@ void RecordNode::setParameter(int parameterIndex, float newValue)
     {
 
 
-        // std::cout << "STOP RECORDING." << std::endl;
+        std::cout << "STOP RECORDING." << std::endl;
 
         if (isRecording)
         {
@@ -345,7 +345,7 @@ void RecordNode::setParameter(int parameterIndex, float newValue)
 			m_recordThread->waitForThreadToExit(2000);
 			while (m_recordThread->isThreadRunning())
 			{
-				
+				std::cerr << "RecordEngine timeout" << std::endl;
 				if (AlertWindow::showOkCancelBox(AlertWindow::WarningIcon, "Record Thread timeout",
 					"The recording thread is taking too long to close.\nThis could mean there is still data waiting to be written in the buffer, but it normally "
 					"shouldn't take this long.\nYou can either wait a bit more or forcefully close the thread. Note that data might be lost or corrupted"
diff --git a/Source/Processors/RecordNode/RecordThread.cpp b/Source/Processors/RecordNode/RecordThread.cpp
index 431c924c1..b49d86222 100644
--- a/Source/Processors/RecordNode/RecordThread.cpp
+++ b/Source/Processors/RecordNode/RecordThread.cpp
@@ -96,11 +96,13 @@ void RecordThread::run()
 	{
 		writeData(dataBuffer, BLOCK_MAX_WRITE_SAMPLES, BLOCK_MAX_WRITE_EVENTS, BLOCK_MAX_WRITE_SPIKES);
 	}
+	std::cout << "Exiting record thread" << std::endl;
 	//4-Before closing the thread, try to write the remaining samples
 	if (!closeEarly)
 	{
 		writeData(dataBuffer, -1, -1, -1);
 
+		std::cout << "Closing files" << std::endl;
 		//5-Close files
 		EVERY_ENGINE->closeFiles();
 	}
-- 
GitLab