Accessing ActiveTwo skin-conductance/GSR signals through the C++ SDK

As you will see in these posts at the Biosemi forum:

GSR data undergoes additional processing within ActiveView before storage in the BDF file. GSR signals are normally processed within ActiView to derive a meaningful signal from the original excitation / oscillator signal. Note: this discussion assumes your GSR unit is of the most current type, which uses a 16 Hz oscillator (units in ActiveView are nanoSiemens).

The GSR waveform displayed in ActiView cannot be accessed directly through the SDK, so your software will have to perform the necessary arithmetic to derive a GSR waveform from raw signals on these channels:

  • GSR 1: chan 265 vs chan 266
  • GSR 2: chan 267 vs chan 268

The amplitude of the resultant 16 Hz filtered square wave is a measure of the impedance between a pair of GSR electrodes (voltage drop of the 16 Hz, 1 uA excitation current). Scaling of your GSR signal can be validated with a few test resistors between the GSR electrodes (with CMS+DRL connected to one of the GSR electrodes). Admittance (in Siemens) is then the inverse of the calculated impedance (in Ohm).

Here is a summary of the steps you should take to derive a GSR signal from the raw data stream from the SDK:

  1. Differential is calculated between the raw channels: Signal1 = CH266 – CH265
  2. Signal1 is low passed filtered: Chebyshev 4th order, lowpass, 16hz cutoff, 1dB ripple. After the low-pass filter, the data are floating point values.
  3. Signal1 is scaled (gain of 13.3): Signal1 = 13.3 * Signal1.  This is a scaling factor determined by hardware components.
  4. Collect a full 16 Hz wave, and then determine the min/max values in this wave at a rate of 32 Hz (after a new half wave is collected). Consequently, on 2048 Hz, the GSR value is determined in each group of 128 data points, after each new set of 64 samples (proportionally more on higher speedmodes with higher sample rates, and proportionally less on downsampled signals),
  5. The difference in the maximum and minimum values of the buffered Signal1 is calculated: Signal2 = max(Signal1inbuffer)- min(Signal1inbuffer)
  6. Signal2 is scaled: Signal2 = Signal2/8192. Original 24 bit data has LSB = 1/32 uV, extra byte is added in receiver to construct 32-bit integers, conversion to uV by dividing by 32*256. No data is lost by doing this since  there is no information in the 4th byte.
  7. Signal2 is inverted: Signal3 = 1/Signal2. Admittance (Siemens or Mho) is inverse of impedance (Ohm).
  8. Signal3 is scaled to nanoSiemens: Signal3 = 1E+9 * Signal3
  9. Signal3 is then what is stored in the BDF file (after some data type/endian operations).

The resultant GSR data stream is at 32 Hz sample rate. This signal is up-sampled to the original sample rate by copying values. This is only done to keep the eventual BDF file simple with the same sample rate for all channels (although BDF does support different sample rates for different channels).

Leave a Comment