Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
plugin-GUI
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
yehaojie
plugin-GUI
Commits
e9dd581d
Commit
e9dd581d
authored
8 years ago
by
Aaron Cuevas Lopez
Browse files
Options
Downloads
Patches
Plain Diff
Update Binary Recording plugin
parent
6d195da5
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
Source/Plugins/BinaryWriter/BinaryRecording.cpp
+91
-53
91 additions, 53 deletions
Source/Plugins/BinaryWriter/BinaryRecording.cpp
Source/Plugins/BinaryWriter/BinaryRecording.h
+8
-7
8 additions, 7 deletions
Source/Plugins/BinaryWriter/BinaryRecording.h
with
99 additions
and
60 deletions
Source/Plugins/BinaryWriter/BinaryRecording.cpp
+
91
−
53
View file @
e9dd581d
...
...
@@ -69,7 +69,7 @@ void BinaryRecording::openFiles(File rootFolder, int experimentNumber, int recor
openMessageFile
(
basepath
,
recordingNumber
);
for
(
int
i
=
0
;
i
<
spikeFileArray
.
size
();
i
++
)
{
openSpikeFile
(
basepath
,
getSpikeElectrode
(
i
)
,
recordingNumber
);
openSpikeFile
(
basepath
,
i
,
recordingNumber
);
}
m_recordingNum
=
recordingNumber
;
}
...
...
@@ -126,7 +126,7 @@ void BinaryRecording::writeData(int writeChannel, int realChannel, const float*
m_scaledBuffer
.
malloc
(
size
);
m_intBuffer
.
malloc
(
size
);
}
double
multFactor
=
1
/
(
float
(
0x7fff
)
*
getChannel
(
realChannel
)
->
b
itVolts
);
double
multFactor
=
1
/
(
float
(
0x7fff
)
*
get
Data
Channel
(
realChannel
)
->
getB
itVolts
()
);
FloatVectorOperations
::
copyWithMultiply
(
m_scaledBuffer
.
getData
(),
buffer
,
multFactor
,
size
);
AudioDataConverters
::
convertFloatToInt16LE
(
m_scaledBuffer
.
getData
(),
m_intBuffer
.
getData
(),
size
);
...
...
@@ -135,7 +135,7 @@ void BinaryRecording::writeData(int writeChannel, int realChannel, const float*
//Code below is copied from OriginalRecording, so it's not as clean as newer one
void
BinaryRecording
::
addSpikeElectrode
(
int
index
,
const
Spike
RecordInfo
*
elec
)
void
BinaryRecording
::
addSpikeElectrode
(
int
index
,
const
Spike
Channel
*
elec
)
{
spikeFileArray
.
add
(
nullptr
);
}
...
...
@@ -185,11 +185,11 @@ void BinaryRecording::openEventFile(String basepath, int recordingNumber)
}
void
BinaryRecording
::
openSpikeFile
(
String
basePath
,
SpikeRecordInfo
*
elec
,
int
recordingNumber
)
void
BinaryRecording
::
openSpikeFile
(
String
basePath
,
int
spikeIndex
,
int
recordingNumber
)
{
const
SpikeChannel
*
elec
=
getSpikeChannel
(
spikeIndex
);
FILE
*
spFile
;
String
fullPath
=
basePath
+
"_"
+
elec
->
n
ame
.
removeCharacters
(
" "
)
+
"_"
+
String
(
recordingNumber
)
+
".spikes"
;
String
fullPath
=
basePath
+
"_"
+
elec
->
getN
ame
()
.
removeCharacters
(
" "
)
+
"_"
+
String
(
recordingNumber
)
+
".spikes"
;
std
::
cout
<<
"OPENING FILE: "
<<
fullPath
<<
std
::
endl
;
...
...
@@ -207,7 +207,7 @@ void BinaryRecording::openSpikeFile(String basePath, SpikeRecordInfo* elec, int
fwrite
(
header
.
toUTF8
(),
1
,
header
.
getNumBytesAsUTF8
(),
spFile
);
}
diskWriteLock
.
exit
();
spikeFileArray
.
set
(
elec
->
record
Index
,
spFile
);
spikeFileArray
.
set
(
spike
Index
,
spFile
);
}
...
...
@@ -263,7 +263,7 @@ String BinaryRecording::generateEventHeader()
header
+=
"header.sampleRate = "
;
// all channels need to have the same sample rate under the current scheme
header
+=
String
(
getChannel
(
0
)
->
s
ampleRate
);
header
+=
String
(
get
Event
Channel
(
0
)
->
getS
ampleRate
()
);
header
+=
";
\n
"
;
header
+=
"header.blockLength = "
;
header
+=
BLOCK_LENGTH
;
...
...
@@ -283,7 +283,7 @@ String BinaryRecording::generateEventHeader()
}
String
BinaryRecording
::
generateSpikeHeader
(
SpikeRecordInfo
*
elec
)
String
BinaryRecording
::
generateSpikeHeader
(
const
SpikeChannel
*
elec
)
{
String
header
=
"header.format = 'Open Ephys Data Format';
\n
"
;
header
+=
"header.version = "
+
String
(
VERSION_STRING
)
+
";
\n
"
;
...
...
@@ -300,15 +300,15 @@ String BinaryRecording::generateSpikeHeader(SpikeRecordInfo* elec)
header
+=
"';
\n
"
;
header
+=
"header.electrode = '"
;
header
+=
elec
->
n
ame
;
header
+=
elec
->
getN
ame
()
;
header
+=
"';
\n
"
;
header
+=
"header.num_channels = "
;
header
+=
elec
->
n
umChannels
;
header
+=
elec
->
getN
umChannels
()
;
header
+=
";
\n
"
;
header
+=
"header.sampleRate = "
;
header
+=
String
(
elec
->
s
ampleRate
);
header
+=
String
(
elec
->
getS
ampleRate
()
);
header
+=
";
\n
"
;
header
=
header
.
paddedRight
(
' '
,
HEADER_SIZE
);
...
...
@@ -318,34 +318,41 @@ String BinaryRecording::generateSpikeHeader(SpikeRecordInfo* elec)
return
header
;
}
void
BinaryRecording
::
writeEvent
(
int
eventType
,
const
MidiMessage
&
event
,
int64
timestamp
)
void
BinaryRecording
::
writeEvent
(
int
eventIndex
,
const
MidiMessage
&
event
)
{
writeTTLEvent
(
eventIndex
,
event
);
if
(
Event
::
getEventType
(
event
)
==
EventChannel
::
TEXT
)
{
TextEventPtr
ev
=
TextEvent
::
deserializeFromMessage
(
event
,
getEventChannel
(
eventIndex
));
if
(
ev
==
nullptr
)
return
;
writeMessage
(
ev
->
getText
(),
ev
->
getSourceID
(),
ev
->
getChannel
(),
ev
->
getTimestamp
());
}
}
void
BinaryRecording
::
writeTimestampSyncText
(
uint16
sourceID
,
uint16
sourceIdx
,
uint64
timestamp
,
String
text
)
{
if
(
isWritableEvent
(
eventType
))
writeTTLEvent
(
event
,
timestamp
);
if
(
eventType
==
GenericProcessor
::
MESSAGE
)
writeMessage
(
event
,
timestamp
);
writeMessage
(
text
,
sourceID
,
255
,
timestamp
);
}
void
BinaryRecording
::
writeMessage
(
const
MidiMessage
&
event
,
int64
timestamp
)
void
BinaryRecording
::
writeMessage
(
String
message
,
uint16
processorID
,
uint16
channel
,
u
int64
timestamp
)
{
if
(
messageFile
==
nullptr
)
return
;
int
msgLength
=
event
.
getRawDataSize
()
-
6
;
const
char
*
dataptr
=
(
const
char
*
)
event
.
getRawData
()
+
6
;
int
msgLength
=
message
.
getNumBytesAsUTF8
();
String
timestampText
(
timestamp
);
diskWriteLock
.
enter
();
fwrite
(
timestampText
.
toUTF8
(),
1
,
timestampText
.
length
(),
messageFile
);
fwrite
(
" "
,
1
,
1
,
messageFile
);
fwrite
(
dataptr
,
1
,
msgLength
,
messageFile
);
fwrite
(
message
.
toUTF8
()
,
1
,
msgLength
,
messageFile
);
fwrite
(
"
\n
"
,
1
,
1
,
messageFile
);
diskWriteLock
.
exit
();
}
void
BinaryRecording
::
writeTTLEvent
(
const
MidiMessage
&
event
,
int64
timestamp
)
void
BinaryRecording
::
writeTTLEvent
(
int
eventIndex
,
const
MidiMessage
&
event
)
{
// find file and write samples to disk
// std::cout << "Received event!" << std::endl;
...
...
@@ -353,56 +360,87 @@ void BinaryRecording::writeTTLEvent(const MidiMessage& event, int64 timestamp)
if
(
eventFile
==
nullptr
)
return
;
const
uint8
*
dataptr
=
event
.
getRawData
();
uint8
data
[
16
];
//With the new external recording thread, this field has no sense.
int16
samplePos
=
0
;
diskWriteLock
.
enter
();
EventPtr
ev
=
Event
::
deserializeFromMessage
(
event
,
getEventChannel
(
eventIndex
));
if
(
!
ev
)
return
;
*
reinterpret_cast
<
uint64
*>
(
data
)
=
ev
->
getTimestamp
();
*
reinterpret_cast
<
int16
*>
(
data
+
8
)
=
samplePos
;
*
(
data
+
10
)
=
static_cast
<
uint8
>
(
ev
->
getEventType
());
*
(
data
+
11
)
=
static_cast
<
uint8
>
(
ev
->
getSourceID
());
*
(
data
+
12
)
=
(
ev
->
getEventType
()
==
EventChannel
::
TTL
)
?
(
dynamic_cast
<
TTLEvent
*>
(
ev
.
get
())
->
getState
()
?
1
:
0
)
:
0
;
*
(
data
+
13
)
=
static_cast
<
uint8
>
(
ev
->
getChannel
());
*
reinterpret_cast
<
uint16
*>
(
data
+
14
)
=
static_cast
<
uint16
>
(
m_recordingNum
);
fwrite
(
&
timestamp
,
// ptr
8
,
// size of each element
1
,
// count
eventFile
);
// ptr to FILE object
fwrite
(
&
samplePos
,
// ptr
2
,
// size of each element
1
,
// count
eventFile
);
// ptr to FILE object
diskWriteLock
.
enter
();
// write 1st four bytes of event (type, nodeId, eventId, eventChannel)
fwrite
(
dataptr
,
1
,
4
,
eventFile
);
int16
recordingNumber
=
m_recordingNum
;
// write recording number
fwrite
(
&
recordingNumber
,
// ptr
2
,
// size of each element
1
,
// count
eventFile
);
// ptr to FILE object
fwrite
(
&
data
,
// ptr
sizeof
(
uint8
),
// size of each element
16
,
// count
eventFile
);
// ptr to FILE object
diskWriteLock
.
exit
();
}
void
BinaryRecording
::
writeSpike
(
int
electrodeIndex
,
const
SpikeObject
&
spike
,
int64
timestamp
)
{
uint8_t
spikeBuffer
[
MAX_SPIKE_BUFFER_LEN
];
void
BinaryRecording
::
writeSpike
(
int
electrodeIndex
,
const
SpikeEvent
*
spike
)
{
if
(
spikeFileArray
[
electrodeIndex
]
==
nullptr
)
return
;
packSpike
(
&
spike
,
spikeBuffer
,
MAX_SPIKE_BUFFER_LEN
);
int
totalBytes
=
spike
.
nSamples
*
spike
.
nChannels
*
2
+
// account for samples
spike
.
nChannels
*
4
+
// acount for gain
spike
.
nChannels
*
2
+
// account for thresholds
SPIKE_METADATA_SIZE
;
// 42, from SpikeObject.h
HeapBlock
<
char
>
spikeBuffer
;
const
SpikeChannel
*
channel
=
getSpikeChannel
(
electrodeIndex
);
int
totalSamples
=
channel
->
getTotalSamples
()
*
channel
->
getNumChannels
();
int
numChannels
=
channel
->
getNumChannels
();
int
chanSamples
=
channel
->
getTotalSamples
();
int
totalBytes
=
totalSamples
*
2
+
// account for samples
numChannels
*
4
+
// acount for gain
numChannels
*
2
+
// account for thresholds
42
;
// 42, from SpikeObject.h
spikeBuffer
.
malloc
(
totalBytes
);
*
(
spikeBuffer
.
getData
())
=
static_cast
<
char
>
(
channel
->
getChannelType
());
*
reinterpret_cast
<
uint64
*>
(
spikeBuffer
.
getData
()
+
1
)
=
spike
->
getTimestamp
();
*
reinterpret_cast
<
uint64
*>
(
spikeBuffer
.
getData
()
+
9
)
=
0
;
//Legacy unused value
*
reinterpret_cast
<
uint16
*>
(
spikeBuffer
.
getData
()
+
17
)
=
spike
->
getSourceID
();
*
reinterpret_cast
<
uint16
*>
(
spikeBuffer
.
getData
()
+
19
)
=
numChannels
;
*
reinterpret_cast
<
uint16
*>
(
spikeBuffer
.
getData
()
+
21
)
=
chanSamples
;
*
reinterpret_cast
<
uint16
*>
(
spikeBuffer
.
getData
()
+
23
)
=
spike
->
getSortedID
();
*
reinterpret_cast
<
uint16
*>
(
spikeBuffer
.
getData
()
+
25
)
=
electrodeIndex
;
//Legacy value
*
reinterpret_cast
<
uint16
*>
(
spikeBuffer
.
getData
()
+
27
)
=
0
;
//Legacy unused value
zeromem
(
spikeBuffer
.
getData
()
+
29
,
3
*
sizeof
(
uint8
));
zeromem
(
spikeBuffer
.
getData
()
+
32
,
2
*
sizeof
(
float
));
*
reinterpret_cast
<
uint16
*>
(
spikeBuffer
.
getData
()
+
40
)
=
channel
->
getSampleRate
();
int
ptrIdx
=
0
;
for
(
int
i
=
0
;
i
<
numChannels
;
i
++
)
{
float
scaleFactor
=
1
/
(
float
(
0x7fff
)
*
channel
->
getChannelBitVolts
(
i
));
FloatVectorOperations
::
copyWithMultiply
(
m_scaledBuffer
+
ptrIdx
,
spike
->
getDataPointer
(
i
),
scaleFactor
,
chanSamples
);
ptrIdx
+=
chanSamples
;
}
AudioDataConverters
::
convertFloatToInt16LE
(
m_scaledBuffer
,
(
spikeBuffer
.
getData
()
+
42
),
totalSamples
);
ptrIdx
=
totalSamples
*
2
+
42
;
for
(
int
i
=
0
;
i
<
numChannels
;
i
++
)
{
*
reinterpret_cast
<
float
*>
(
spikeBuffer
.
getData
()
+
ptrIdx
)
=
channel
->
getGain
();
ptrIdx
+=
sizeof
(
float
);
}
for
(
int
i
=
0
;
i
<
numChannels
;
i
++
)
{
*
reinterpret_cast
<
int16
*>
(
spikeBuffer
.
getData
()
+
ptrIdx
)
=
spike
->
getThreshold
(
i
);
ptrIdx
+=
sizeof
(
int16
);
}
diskWriteLock
.
enter
();
fwrite
(
spikeBuffer
,
1
,
totalBytes
,
spikeFileArray
[
electrodeIndex
]);
int16
recordingNumber
=
m_recordingNum
;
fwrite
(
&
recordingNumber
,
// ptr
fwrite
(
&
m_recordingNum
,
// ptr
2
,
// size of each element
1
,
// count
spikeFileArray
[
electrodeIndex
]);
// ptr to FILE object
...
...
This diff is collapsed.
Click to expand it.
Source/Plugins/BinaryWriter/BinaryRecording.h
+
8
−
7
View file @
e9dd581d
...
...
@@ -47,23 +47,24 @@ namespace BinaryRecordingEngine
void
openFiles
(
File
rootFolder
,
int
experimentNumber
,
int
recordingNumber
)
override
;
void
closeFiles
()
override
;
void
writeData
(
int
writeChannel
,
int
realChannel
,
const
float
*
buffer
,
int
size
)
override
;
void
writeEvent
(
int
eventType
,
const
MidiMessage
&
event
,
int64
timestamp
)
override
;
void
writeEvent
(
int
eventType
,
const
MidiMessage
&
event
)
override
;
void
resetChannels
()
override
;
void
addSpikeElectrode
(
int
index
,
const
SpikeRecordInfo
*
elec
)
override
;
void
writeSpike
(
int
electrodeIndex
,
const
SpikeObject
&
spike
,
int64
timestamp
)
override
;
void
addSpikeElectrode
(
int
index
,
const
SpikeChannel
*
elec
)
override
;
void
writeSpike
(
int
electrodeIndex
,
const
SpikeEvent
*
spike
)
override
;
void
writeTimestampSyncText
(
uint16
sourceID
,
uint16
sourceIdx
,
uint64
timestamp
,
String
text
);
static
RecordEngineManager
*
getEngineManager
();
private:
void
openSpikeFile
(
String
basepath
,
SpikeRecordInfo
*
elec
,
int
recordingNumber
);
String
generateSpikeHeader
(
SpikeRecordInfo
*
elec
);
void
openSpikeFile
(
String
basepath
,
int
spikeIndex
,
int
recordingNumber
);
String
generateSpikeHeader
(
const
SpikeChannel
*
elec
);
String
generateEventHeader
();
void
openMessageFile
(
String
basepath
,
int
recordingNumber
);
void
openEventFile
(
String
basepath
,
int
recordingNumber
);
void
writeTTLEvent
(
const
MidiMessage
&
event
,
int64
timestamp
);
void
writeMessage
(
const
MidiMessage
&
event
,
int64
timestamp
);
void
writeTTLEvent
(
int
eventIndex
,
const
MidiMessage
&
event
);
void
writeMessage
(
String
message
,
uint16
processorID
,
uint16
channel
,
u
int64
timestamp
);
HeapBlock
<
float
>
m_scaledBuffer
;
HeapBlock
<
int16
>
m_intBuffer
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment