2222 */
2323
2424#include " HDF5Recording.h"
25- #define MAX_BUFFER_SIZE 10000
25+ #define MAX_BUFFER_SIZE 40960
26+ #define CHANNEL_TIMESTAMP_PREALLOC_SIZE 128
27+ #define CHANNEL_TIMESTAMP_MIN_WRITE 32
28+ #define TIMESTAMP_EACH_NSAMPLES 1024
2629
27- HDF5Recording::HDF5Recording () : processorIndex(-1 ), hasAcquired(false )
30+ HDF5Recording::HDF5Recording () : processorIndex(-1 ), hasAcquired(false ), bufferSize(MAX_BUFFER_SIZE)
2831{
2932 // timestamp = 0;
30- scaledBuffer = new float [ MAX_BUFFER_SIZE] ;
31- intBuffer = new int16[ MAX_BUFFER_SIZE] ;
33+ scaledBuffer. malloc ( MAX_BUFFER_SIZE) ;
34+ intBuffer. malloc ( MAX_BUFFER_SIZE) ;
3235}
3336
3437HDF5Recording::~HDF5Recording ()
35- {
36- delete scaledBuffer;
37- delete intBuffer;
38+ {
3839}
3940
40- String HDF5Recording::getEngineID ()
41+ String HDF5Recording::getEngineID () const
4142{
4243 return " KWIK" ;
4344}
@@ -65,6 +66,9 @@ void HDF5Recording::registerProcessor(const GenericProcessor* proc)
6566
6667void HDF5Recording::resetChannels ()
6768{
69+ scaledBuffer.malloc (MAX_BUFFER_SIZE);
70+ intBuffer.malloc (MAX_BUFFER_SIZE);
71+ bufferSize = MAX_BUFFER_SIZE;
6872 processorIndex = -1 ;
6973 fileArray.clear ();
7074 channelsPerProcessor.clear ();
@@ -73,6 +77,8 @@ void HDF5Recording::resetChannels()
7377 processorMap.clear ();
7478 infoArray.clear ();
7579 recordedChanToKWDChan.clear ();
80+ channelLeftOverSamples.clear ();
81+ channelTimestampArray.clear ();
7682 if (spikesFile)
7783 spikesFile->resetChannels ();
7884}
@@ -129,31 +135,11 @@ void HDF5Recording::openFiles(File rootFolder, int experimentNumber, int recordi
129135 int procPos = processorRecPos[index];
130136 recordedChanToKWDChan.add (procPos);
131137 processorRecPos.set (index, procPos+1 );
138+ channelTimestampArray.add (new Array<int64>);
139+ channelTimestampArray.getLast ()->ensureStorageAllocated (CHANNEL_TIMESTAMP_PREALLOC_SIZE);
140+ channelLeftOverSamples.add (0 );
132141 }
133- #if 0
134- for (int i = 0; i < processorMap.size(); i++)
135- {
136- int index = processorMap[i];
137- if (getChannel(i)->getRecordState())
138- {
139- if (!fileArray[index]->isOpen())
140- {
141- fileArray[index]->initFile(getChannel(i)->nodeId,basepath);
142- if (hasAcquired)
143- infoArray[index]->start_time = (*timestamps)[getChannel(i)->sourceNodeId]; //the timestamps of the first channel
144- else
145- infoArray[index]->start_time = 0;
146- }
147- channelsPerProcessor.set(index, channelsPerProcessor[index] + 1);
148- bitVoltsArray[index]->add(getChannel(i)->bitVolts);
149- sampleRatesArray[index]->add(getChannel(i)->sampleRate);
150- if (getChannel(i)->sampleRate != infoArray[index]->sample_rate)
151- {
152- infoArray[index]->multiSample = true;
153- }
154- }
155- }
156- #endif
142+
157143 for (int i = 0 ; i < fileArray.size (); i++)
158144 {
159145 if ((!fileArray[i]->isOpen ()) && (fileArray[i]->isReadyToOpen ()))
@@ -189,25 +175,72 @@ void HDF5Recording::closeFiles()
189175 {
190176 if (fileArray[i]->isOpen ())
191177 {
178+ std::cout << " Closed file " << i << std::endl;
192179 fileArray[i]->stopRecording ();
193180 fileArray[i]->close ();
194181 bitVoltsArray[i]->clear ();
195182 sampleRatesArray[i]->clear ();
196183 }
197184 channelsPerProcessor.set (i, 0 );
198185 }
186+ recordedChanToKWDChan.clear ();
187+ channelTimestampArray.clear ();
188+ channelLeftOverSamples.clear ();
189+ scaledBuffer.malloc (MAX_BUFFER_SIZE);
190+ intBuffer.malloc (MAX_BUFFER_SIZE);
191+ bufferSize = MAX_BUFFER_SIZE;
199192}
200193
201194void HDF5Recording::writeData (int writeChannel, int realChannel, const float * buffer, int size)
202195{
203- // int64 t1 = Time::getHighResolutionTicks();
196+ if (size > bufferSize) // Shouldn't happen, and if it happens it'll be slow, but better this than crashing. Will be reset on flie close and reset.
197+ {
198+ std::cerr << " Write buffer overrun, resizing to" << size << std::endl;
199+ bufferSize = size;
200+ scaledBuffer.malloc (size);
201+ intBuffer.malloc (size);
202+ }
204203 double multFactor = 1 / (float (0x7fff ) * getChannel (realChannel)->bitVolts );
205204 int index = processorMap[getChannel (realChannel)->recordIndex ];
206- FloatVectorOperations::copyWithMultiply (scaledBuffer, buffer, multFactor, size);
207- AudioDataConverters::convertFloatToInt16LE (scaledBuffer, intBuffer, size);
208- fileArray[index]->writeRowData (intBuffer, size, recordedChanToKWDChan[writeChannel]);
209- // int64 t2 = Time::getHighResolutionTicks();
210- // std::cout << "record time: " << float(t2 - t1) / float(Time::getHighResolutionTicksPerSecond()) << std::endl;
205+ FloatVectorOperations::copyWithMultiply (scaledBuffer.getData (), buffer, multFactor, size);
206+ AudioDataConverters::convertFloatToInt16LE (scaledBuffer.getData (), intBuffer.getData (), size);
207+ fileArray[index]->writeRowData (intBuffer.getData (), size, recordedChanToKWDChan[writeChannel]);
208+
209+ int sampleOffset = channelLeftOverSamples[writeChannel];
210+ int blockStart = sampleOffset;
211+ int64 currentTS = getTimestamp (realChannel);
212+
213+ if (sampleOffset > 0 )
214+ {
215+ currentTS += TIMESTAMP_EACH_NSAMPLES - sampleOffset;
216+ blockStart += TIMESTAMP_EACH_NSAMPLES - sampleOffset;
217+ }
218+
219+ for (int i = 0 ; i < size; i += TIMESTAMP_EACH_NSAMPLES)
220+ {
221+ if ((blockStart + i) < (sampleOffset + size))
222+ {
223+ channelTimestampArray[writeChannel]->add (currentTS);
224+ currentTS += TIMESTAMP_EACH_NSAMPLES;
225+ }
226+ }
227+ channelLeftOverSamples.set (writeChannel, (size + sampleOffset) % TIMESTAMP_EACH_NSAMPLES);
228+ }
229+
230+ void HDF5Recording::endChannelBlock (bool lastBlock)
231+ {
232+ int nCh = channelTimestampArray.size ();
233+ for (int ch = 0 ; ch < nCh; ++ch)
234+ {
235+ int tsSize = channelTimestampArray[ch]->size ();
236+ if ((tsSize > 0 ) && ((tsSize > CHANNEL_TIMESTAMP_MIN_WRITE) || lastBlock))
237+ {
238+ int realChan = getRealChannel (ch);
239+ int index = processorMap[getChannel (realChan)->recordIndex ];
240+ fileArray[index]->writeTimestamps (channelTimestampArray[ch]->getRawDataPointer (), tsSize, recordedChanToKWDChan[ch]);
241+ channelTimestampArray[ch]->clearQuick ();
242+ }
243+ }
211244}
212245
213246void HDF5Recording::writeEvent (int eventType, const MidiMessage& event, int64 timestamp)
0 commit comments