@@ -34,13 +34,14 @@ SpikeSorter::SpikeSorter()
3434 overflowBufferSize(100 ), currentElectrode(-1 ),
3535 numPreSamples(8 ),numPostSamples(32 )
3636{
37+ setProcessorType (PROCESSOR_TYPE_FILTER);
38+
3739 uniqueID = 0 ; // for electrode count
3840 uniqueSpikeID = 0 ;
3941 juce::Time timer;
4042 ticksPerSec = (float ) timer.getHighResolutionTicksPerSecond ();
4143 electrodeTypes.clear ();
4244 electrodeCounter.clear ();
43- spikeBuffer = new uint8_t [MAX_SPIKE_BUFFER_LEN]; // MAX_SPIKE_BUFFER_LEN defined in SpikeObject.h
4445 channelBuffers=nullptr ;
4546 PCAbeforeBoxes = true ;
4647 autoDACassignment = false ;
@@ -137,6 +138,13 @@ int SpikeSorter::getUniqueProbeID(String type)
137138 return 1 ;
138139}
139140
141+ void SpikeSorter::setEditAllState (bool val){
142+ editAll = val;
143+ }
144+
145+ bool SpikeSorter::getEditAllState (){
146+ return editAll;
147+ }
140148
141149void SpikeSorter::increaseUniqueProbeID (String type)
142150{
@@ -153,9 +161,6 @@ void SpikeSorter::increaseUniqueProbeID(String type)
153161
154162SpikeSorter::~SpikeSorter ()
155163{
156- delete spikeBuffer;
157- spikeBuffer = nullptr ;
158-
159164 if (channelBuffers != nullptr )
160165 delete channelBuffers;
161166
@@ -188,13 +193,19 @@ void SpikeSorter::updateSettings()
188193
189194 for (int i = 0 ; i < electrodes.size (); i++)
190195 {
196+ Electrode* elec = electrodes[i];
197+ unsigned int nChans = elec->numChannels ;
198+ Array<const DataChannel*> chans;
199+ for (int c = 0 ; c < nChans; c++)
200+ {
201+ chans.add (getDataChannel (elec->channels [c]));
202+ }
191203
192- Channel* ch = new Channel (this ,i,ELECTRODE_CHANNEL);
193- ch->name = generateSpikeElectrodeName (electrodes[i]->numChannels , ch->index );
194- SpikeChannel* spk = new SpikeChannel (SpikeChannel::Sorted, electrodes[i]->numChannels , electrodes[i], sizeof (Electrode));
195- ch->extraData = spk;
204+ SpikeChannel* spk = new SpikeChannel (SpikeChannel::typeFromNumChannels (nChans), this , chans);
205+ spk->setNumSamples (elec->prePeakSamples , elec->postPeakSamples );
206+ spk->addEventMetaData (new MetaDataDescriptor (MetaDataDescriptor::UINT8, 3 , " Color" , " Color of the spike" , " graphics.color" ));
196207
197- eventChannels .add (ch );
208+ spikeChannelArray .add (spk );
198209 }
199210
200211 mut.exit ();
@@ -212,12 +223,14 @@ Electrode::~Electrode()
212223
213224}
214225
215- Electrode::Electrode (int ID, UniqueIDgenerator* uniqueIDgenerator_, PCAcomputingThread* pth, String _name, int _numChannels, int * _channels, float default_threshold, int pre , int post , float samplingRate , int sourceNodeId )
226+ Electrode::Electrode (int ID, UniqueIDgenerator* uniqueIDgenerator_, PCAcomputingThread* pth, String _name, int _numChannels, int * _channels, float default_threshold, int pre , int post , float samplingRate , int sourceId, int subIdx )
216227{
217228 electrodeID = ID;
218229 computingThread = pth;
219230 uniqueIDgenerator = uniqueIDgenerator_;
220231 name = _name;
232+ sourceNodeId_ = sourceId;
233+ sourceSubIdx = subIdx;
221234
222235 numChannels = _numChannels;
223236 prePeakSamples = pre ;
@@ -438,7 +451,7 @@ bool SpikeSorter::addElectrode(int nChans, String name, double Depth)
438451 chans[k] = firstChan + k;
439452
440453 Electrode* newElectrode = new Electrode (++uniqueID, &uniqueIDgenerator, &computingThread, name, nChans, chans, getDefaultThreshold (),
441- numPreSamples, numPostSamples, getSampleRate (), channels [chans[0 ]]->sourceNodeId );
454+ numPreSamples, numPostSamples, getSampleRate (), dataChannelArray [chans[0 ]]->getSourceNodeID (), dataChannelArray[chans[ 0 ]]-> getSubProcessorIdx () );
442455
443456 newElectrode->depthOffsetMM = Depth;
444457 String log = " Added electrode (ID " + String (uniqueID)+" ) with " + String (nChans) + " channels." ;
@@ -679,83 +692,41 @@ Electrode* SpikeSorter::getActiveElectrode()
679692}
680693
681694
682- void SpikeSorter::addSpikeEvent (SpikeObject* s, MidiBuffer& eventBuffer, int peakIndex)
683- {
684-
685- // std::cout << "Adding spike event for index " << peakIndex << std::endl;
686-
687- s->eventType = SPIKE_EVENT_CODE;
688-
689- int numBytes = packSpike (s, // SpikeObject
690- spikeBuffer, // uint8_t*
691- MAX_SPIKE_BUFFER_LEN); // int
692-
693- if (numBytes > 0 )
694- eventBuffer.addEvent (spikeBuffer, numBytes, peakIndex);
695-
696- // std::cout << "Adding spike" << std::endl;
697- }
698-
699- void SpikeSorter::addWaveformToSpikeObject (SpikeObject* s,
695+ void SpikeSorter::addWaveformToSpikeObject (SpikeEvent::SpikeBuffer& s,
700696 int & peakIndex,
701697 int & electrodeNumber,
702698 int & currentChannel)
703699{
704700 mut.enter ();
705- int spikeLength = electrodes[electrodeNumber]->prePeakSamples +
706- + electrodes[electrodeNumber]->postPeakSamples ;
707-
708- s->timestamp = getTimestamp (currentChannel) + peakIndex;
709-
710- // convert sample offset to software ticks
711- float samplesPerSec = getSampleRate ();
712- s->timestamp_software = software_timestamp + int64 (ticksPerSec*float (peakIndex)/samplesPerSec);
713- s->nSamples = spikeLength;
714-
715- int chan = *(electrodes[electrodeNumber]->channels +currentChannel);
716-
717- s->gain [currentChannel] = (1 .0f / channels[chan]->bitVolts )*1000 ;
718- s->threshold [currentChannel] = (int ) electrodes[electrodeNumber]->thresholds [currentChannel];
719-
720- // cycle through buffer
721-
722- if (isChannelActive (electrodeNumber, currentChannel))
723- {
724-
725- for (int sample = 0 ; sample < spikeLength; sample++)
726- {
727-
728- // warning -- be careful of bitvolts conversion
729- // do not flip signal (!).
730- float value = getNextSample (electrodes[electrodeNumber]->channels [currentChannel]);
731- s->data [currentIndex] = uint16 (jmin (65535 ,jmax (0 , int (value / channels[chan]->bitVolts ) + 32768 )));
732- // recovered data
733- // float value2 = (s->data[currentIndex]-32768) /float(s->gain[currentChannel])*1000.0f;
734-
735- currentIndex++;
736- sampleIndex++;
737-
738- // std::cout << currentIndex << std::endl;
701+ int spikeLength = electrodes[electrodeNumber]->prePeakSamples
702+ + electrodes[electrodeNumber]->postPeakSamples ;
739703
740- }
741- }
742- else
743- {
744- for (int sample = 0 ; sample < spikeLength; sample++)
745- {
746704
747- // insert a blank spike if the
748- s->data [currentIndex] = 0 ;
749- currentIndex++;
750- sampleIndex++;
705+ const int chan = *(electrodes[electrodeNumber]->channels + currentChannel);
751706
752- // std::cout << currentIndex << std::endl;
707+ if (isChannelActive (electrodeNumber, currentChannel))
708+ {
753709
754- }
755- }
710+ for (int sample = 0 ; sample < spikeLength; ++sample)
711+ {
712+ s.set (currentChannel, sample, getNextSample (*(electrodes[electrodeNumber]->channels + currentChannel)));
713+ ++sampleIndex;
756714
715+ // std::cout << currentIndex << std::endl;
716+ }
717+ }
718+ else
719+ {
720+ for (int sample = 0 ; sample < spikeLength; ++sample)
721+ {
722+ // insert a blank spike if the
723+ s.set (currentChannel, sample, 0 );
724+ ++sampleIndex;
725+ // std::cout << currentIndex << std::endl;
726+ }
727+ }
757728
758- sampleIndex -= spikeLength; // reset sample index
729+ sampleIndex -= spikeLength; // reset sample index
759730 mut.exit ();
760731
761732}
@@ -825,16 +796,6 @@ void SpikeSorter::startRecording()
825796// delete msg_with_ts;
826797// }
827798
828- void SpikeSorter::handleEvent (int eventType, MidiMessage& event, int sampleNum)
829- {
830- if (eventType == TIMESTAMP)
831- {
832- const uint8* dataptr = event.getRawData ();
833- memcpy (&hardware_timestamp, dataptr + 4 , 8 ); // remember to skip first four bytes
834- software_timestamp = timer.getHighResolutionTicks (); // software timestamp for start of buffer
835- }
836- }
837-
838799// void SpikeSorter::addNetworkEventToQueue(StringTS S)
839800// {
840801// StringTS copy(S);
@@ -872,8 +833,7 @@ void SpikeSorter::clearRunningStatForSelectedElectrode()
872833 electrodes[currentElectrode]->runningStats [0 ].Clear ();
873834}
874835
875- void SpikeSorter::process (AudioSampleBuffer& buffer,
876- MidiBuffer& events)
836+ void SpikeSorter::process (AudioSampleBuffer& buffer)
877837{
878838
879839 // printf("Entering Spike Detector::process\n");
@@ -882,8 +842,7 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
882842 // cycle through electrodes
883843 Electrode* electrode;
884844 dataBuffer = &buffer;
885-
886- checkForEvents (events); // find latest's packet timestamps
845+ const SpikeChannel* spikeChan;
887846
888847 // channelBuffers->update(buffer, hardware_timestamp,software_timestamp, nSamples);
889848
@@ -893,6 +852,7 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
893852 // std::cout << "ELECTRODE " << i << std::endl;
894853
895854 electrode = electrodes[i];
855+ spikeChan = spikeChannelArray[i];
896856
897857 // refresh buffer index for this electrode
898858 sampleIndex = electrode->lastBufferIndex - 1 ; // subtract 1 to account for
@@ -958,28 +918,20 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
958918 peakIndex = sampleIndex;
959919 sampleIndex -= (electrode->prePeakSamples +1 );
960920
961- SpikeObject newSpike;
962- newSpike.sortedId = 0 ; // unsorted.
963- newSpike.timestamp = getTimestamp (currentChannel) + peakIndex;
964- newSpike.electrodeID = electrode->electrodeID ;
965- newSpike.channel = chan;
966- newSpike.source = i;
967- newSpike.nChannels = electrode->numChannels ;
968- newSpike.samplingFrequencyHz = samplingFrequencyHz;
969- newSpike.color [0 ] = newSpike.color [1 ] = newSpike.color [2 ] = 127 ;
970- currentIndex = 0 ;
971-
972- // package spikes;
973- for (int channel = 0 ; channel < electrode->numChannels ; channel++)
974- {
975-
976- addWaveformToSpikeObject (&newSpike,
977- peakIndex,
978- i,
979- channel);
980-
981- // std::cout << "adding waveform" << std::endl;
982- }
921+ const SpikeChannel* spikeChan = getSpikeChannel (i);
922+ SpikeEvent::SpikeBuffer spikeData (spikeChan);
923+ Array<float > thresholds;
924+ for (int channel = 0 ; channel < electrode->numChannels ; ++channel)
925+ {
926+ addWaveformToSpikeObject (spikeData,
927+ peakIndex,
928+ i,
929+ channel);
930+ thresholds.add ((int )*(electrode->thresholds + channel));
931+ }
932+ int64 timestamp = getTimestamp (electrode->channels [0 ]) + peakIndex;
933+
934+ SorterSpikePtr sorterSpike = new SorterSpikeContainer (spikeChan, spikeData, timestamp);
983935
984936 /*
985937 bool perfectMatch = true;
@@ -994,10 +946,10 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
994946 */
995947
996948 // for (int xxx = 0; xxx < 1000; xxx++) // overload with spikes for testing purposes
997- electrode->spikeSort ->projectOnPrincipalComponents (&newSpike );
949+ electrode->spikeSort ->projectOnPrincipalComponents (sorterSpike );
998950
999951 // Add spike to drawing buffer....
1000- electrode->spikeSort ->sortSpike (&newSpike , PCAbeforeBoxes);
952+ electrode->spikeSort ->sortSpike (sorterSpike , PCAbeforeBoxes);
1001953
1002954
1003955 // transfer buffered spikes to spike plot
@@ -1012,11 +964,14 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
1012964 }
1013965
1014966
1015- electrode->spikePlot ->processSpikeObject (newSpike );
967+ electrode->spikePlot ->processSpikeObject (sorterSpike );
1016968 }
1017969
970+ MetaDataValueArray md;
971+ md.add (new MetaDataValue (MetaDataDescriptor::UINT8, 3 , sorterSpike->color ));
972+ SpikeEventPtr newSpike = SpikeEvent::createSpikeEvent (spikeChan, timestamp, thresholds, spikeData, sorterSpike->sortedId , md);
1018973
1019- addSpikeEvent (&newSpike, events , peakIndex);
974+ addSpike (spikeChan, newSpike , peakIndex);
1020975 // prevSpike = newSpike;
1021976 // advance the sample index
1022977 sampleIndex = peakIndex + electrode->postPeakSamples ;
@@ -1337,7 +1292,7 @@ void SpikeSorter::loadCustomParametersFromXml()
13371292 int sourceNodeId = 102010 ; // some number
13381293
13391294 Electrode* newElectrode = new Electrode (electrodeID, &uniqueIDgenerator,&computingThread, electrodeName, channelsPerElectrode, channels,getDefaultThreshold (),
1340- numPreSamples,numPostSamples, getSampleRate (), sourceNodeId);
1295+ numPreSamples,numPostSamples, getSampleRate (), sourceNodeId, 0 );
13411296 for (int k=0 ; k<channelsPerElectrode; k++)
13421297 {
13431298 newElectrode->thresholds [k] = thres[k];
@@ -1963,5 +1918,3 @@ int ContinuousCircularBuffer::GetPtr()
19631918
19641919/* ***********************************************************/
19651920
1966-
1967-
0 commit comments