From cc102e71d56570bbb42074965075214c42fd4dd0 Mon Sep 17 00:00:00 2001
From: kmichaelfox <kmichaelfox.contact@gmail.com>
Date: Fri, 1 Sep 2017 14:52:56 -0700
Subject: [PATCH] add simple FileReader pre-buffer cache

---
 Source/Processors/Events/Events.cpp         |  3 +-
 Source/Processors/FileReader/FileReader.cpp | 63 ++++++++++++---------
 Source/Processors/FileReader/FileReader.h   |  4 +-
 3 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/Source/Processors/Events/Events.cpp b/Source/Processors/Events/Events.cpp
index dbf122acb..a701b00d6 100644
--- a/Source/Processors/Events/Events.cpp
+++ b/Source/Processors/Events/Events.cpp
@@ -219,7 +219,8 @@ String SystemEvent::getSyncText(const MidiMessage& msg)
 
 //Event
 Event::Event(const Event& other)
-	: Event(other)
+	//: Event(other)
+    : Event(other.m_channelInfo, other.m_timestamp, other.m_channel)
 {
 	size_t size = other.m_channelInfo->getDataSize();
 	m_data.malloc(size);
diff --git a/Source/Processors/FileReader/FileReader.cpp b/Source/Processors/FileReader/FileReader.cpp
index 42cbb38d7..63d79c852 100644
--- a/Source/Processors/FileReader/FileReader.cpp
+++ b/Source/Processors/FileReader/FileReader.cpp
@@ -38,6 +38,7 @@ FileReader::FileReader()
     , startSample           (0)
     , stopSample            (0)
     , counter               (0)
+    , bufferCacheWindow     (0)
 {
     setProcessorType (PROCESSOR_TYPE_SOURCE);
 
@@ -231,45 +232,55 @@ void FileReader::updateSettings()
 
 void FileReader::process (AudioSampleBuffer& buffer)
 {
-    
-
     const int samplesNeededPerBuffer = int (float (buffer.getNumSamples()) * (getDefaultSampleRate() / 44100.0f));
-//    const int samplesNeeded = int (float (buffer.getNumSamples()) * (getDefaultSampleRate() / 44100.0f));
     const int samplesNeeded = samplesNeededPerBuffer * BUFFER_WINDOW_CACHE_SIZE;
     // FIXME: needs to account for the fact that the ratio might not be an exact
     //        integer value
-
+    
     int samplesRead = 0;
-
-    while (bufferCacheWindow == 0 && samplesRead < samplesNeeded) // only read every 5th window
+    
+    // if window id == 0, we need to read and cache BUFFER_WINDOW_CACHE_SIZE more buffer windows
+    if (bufferCacheWindow == 0)
     {
-        int samplesToRead = samplesNeeded - samplesRead;
-        if ( (currentSample + samplesToRead) > stopSample) // if there are enough samples for full buffer
+        
+        // should only loop if reached end of file and resuming from start
+        while (samplesRead < samplesNeeded)
         {
-            samplesToRead = stopSample - currentSample;
-            if (samplesToRead > 0)
+            int samplesToRead = samplesNeeded - samplesRead;
+            
+            // if reached end of file stream
+            if ( (currentSample + samplesToRead) > stopSample)
+            {
+                samplesToRead = stopSample - currentSample;
+                if (samplesToRead > 0)
+                    input->readData (readBuffer + samplesRead * currentNumChannels, samplesToRead);
+                
+                // reset stream to beginning
+                input->seekTo (startSample);
+                currentSample = startSample;
+            }
+            else // else read the block needed
+            {
                 input->readData (readBuffer + samplesRead * currentNumChannels, samplesToRead);
-
-            input->seekTo (startSample);
-            currentSample = startSample;
+                
+                currentSample += samplesToRead;
+            }
+            
+            samplesRead += samplesToRead;
         }
-        else // if there aren't enough samples for full buffer
-        {
-            input->readData (readBuffer + samplesRead * currentNumChannels, samplesToRead);
-
-            currentSample += samplesToRead;
-        }
-
-        samplesRead += samplesToRead;
     }
-
+    
     for (int i = 0; i < currentNumChannels; ++i)
     {
-        input->processChannelData (readBuffer + samplesRead * currentNumChannels * bufferCacheWindow, buffer.getWritePointer (i, 0), i, samplesNeededPerBuffer);
+        // offset readBuffer index by current cache window count * buffer window size * num channels
+        input->processChannelData (readBuffer + (samplesNeededPerBuffer * currentNumChannels * bufferCacheWindow),
+                                   buffer.getWritePointer (i, 0),
+                                   i,
+                                   samplesNeededPerBuffer);
     }
-
-    timestamp += samplesNeeded;
-	setTimestampAndSamples(timestamp, samplesNeededPerBuffer);
+    
+    timestamp += samplesNeededPerBuffer;
+    setTimestampAndSamples(timestamp, samplesNeededPerBuffer);
     
     bufferCacheWindow += 1;
     bufferCacheWindow %= BUFFER_WINDOW_CACHE_SIZE;
diff --git a/Source/Processors/FileReader/FileReader.h b/Source/Processors/FileReader/FileReader.h
index e3aede0df..91ee3fe77 100644
--- a/Source/Processors/FileReader/FileReader.h
+++ b/Source/Processors/FileReader/FileReader.h
@@ -32,7 +32,7 @@
 #include "FileSource.h"
 
 #define BUFFER_SIZE 1024
-#define BUFFER_WINDOW_CACHE_SIZE 5
+#define BUFFER_WINDOW_CACHE_SIZE 3
 
 
 /**
@@ -84,7 +84,7 @@ private:
     int64 currentNumSamples;
     int64 startSample;
     int64 stopSample;
-    int64 bufferCacheWindow;
+    int64 bufferCacheWindow; // the current buffer window to read from readBuffer
     Array<RecordedChannelInfo> channelInfo;
 
     // for testing purposes only
-- 
GitLab