2626using namespace OnixSourcePlugin ;
2727
2828DigitalIO::DigitalIO (std::string name, std::string hubName, const oni_dev_idx_t deviceIdx_, std::shared_ptr<Onix1> oni_ctx)
29- : OnixDevice(name, hubName, DigitalIO::getDeviceType(), deviceIdx_, oni_ctx), eventWords( 64 )
29+ : OnixDevice(name, hubName, DigitalIO::getDeviceType(), deviceIdx_, oni_ctx)
3030{
31+ StreamInfo digitalInputStream = StreamInfo (
32+ OnixDevice::createStreamName ({ getHubName (), name, " DigitalInputs" }),
33+ " Digital Inputs data" ,
34+ getStreamIdentifier (),
35+ NumDigitalInputs,
36+ AnalogIO::getSampleRate (),
37+ " CH" ,
38+ ContinuousChannel::Type::AUX,
39+ 1.0 ,
40+ " u" , // NB: Digital data is unitless by definition
41+ {},
42+ { " input" });
43+ streamInfos.add (digitalInputStream);
44+
45+ StreamInfo digitalButtonStream = StreamInfo (
46+ OnixDevice::createStreamName ({ getHubName (), name, " DigitalButtons" }),
47+ " Digital Buttons data" ,
48+ getStreamIdentifier (),
49+ NumButtons,
50+ AnalogIO::getSampleRate (),
51+ " " ,
52+ ContinuousChannel::Type::AUX,
53+ 1.0 ,
54+ " u" , // NB: Digital data is unitless by definition
55+ { " Moon" , " Triangle" , " X" , " Check" , " Circle" , " Square" },
56+ { " input" });
57+ streamInfos.add (digitalButtonStream);
58+
59+ eventCodes.fill (0 );
3160}
3261
3362OnixDeviceType DigitalIO::getDeviceType ()
@@ -49,7 +78,9 @@ int DigitalIO::configureDevice()
4978 if (rc != ONI_ESUCCESS)
5079 throw error_str (" Could not read the base frequency register on the DigitalIO device." );
5180
52- uint32_t periodTicks = baseFreqHz / (uint32_t )AnalogIO::getSampleRate ();
81+ // NB: Two states are not accounted for when comparing clock ticks on the hardware,
82+ // therefore the periodTicks variable must be decreased by 2 to get the correct sample rate.
83+ uint32_t periodTicks = (baseFreqHz / (uint32_t )AnalogIO::getSampleRate ()) - 2u ;
5384 rc = deviceContext->writeRegister (deviceIdx, (uint32_t )DigitalIORegisters::SAMPLE_PERIOD, periodTicks);
5485 if (rc != ONI_ESUCCESS)
5586 throw error_str (" Could not write the sample rate for polling to the DigitalIO device." );
@@ -64,10 +95,16 @@ bool DigitalIO::updateSettings()
6495
6596void DigitalIO::startAcquisition ()
6697{
98+ currentFrame = 0 ;
99+ sampleNumber = 0 ;
100+
101+ digitalSamples.fill (0 );
67102}
68103
69104void DigitalIO::addSourceBuffers (OwnedArray<DataBuffer>& sourceBuffers)
70105{
106+ sourceBuffers.add (new DataBuffer (NumChannels, (int )streamInfos.getFirst ().getSampleRate () * bufferSizeInSeconds));
107+ digitalBuffer = sourceBuffers.getLast ();
71108}
72109
73110EventChannel::Settings DigitalIO::getEventChannelSettings (DataStream* stream)
@@ -78,48 +115,54 @@ EventChannel::Settings DigitalIO::getEventChannelSettings(DataStream* stream)
78115 " Digital inputs and breakout button states coming from a DigitalIO device" ,
79116 getStreamIdentifier () + " .event.digital" ,
80117 stream,
81- numButtons + numDigitalInputs
118+ NumChannels
82119 };
83120
84121 return settings;
85122}
86123
87- int DigitalIO::getNumberOfWords ( )
124+ float DigitalIO::getChannelState ( uint8_t state, int channel )
88125{
89- return eventWords. size_approx ();
90- }
126+ return (state & ( 1 << channel)) >> channel; // NB: Return the state of the specified channel
127+ };
91128
92129void DigitalIO::processFrames ()
93130{
94131 oni_frame_t * frame;
95132 while (frameQueue.try_dequeue (frame))
96133 {
134+ size_t offset = 0 ;
97135
98136 uint16_t * dataPtr = (uint16_t *)frame->data ;
99- uint64_t timestamp = deviceContext->convertTimestampToSeconds (frame->time );
100137
101- int dataOffset = 4 ;
138+ timestamps[currentFrame] = deviceContext->convertTimestampToSeconds (frame->time );
139+ sampleNumbers[currentFrame] = sampleNumber++;
102140
103- uint64_t portState = *(dataPtr + dataOffset) ;
104- uint64_t buttonState = *(dataPtr + dataOffset + 1 ) ;
141+ constexpr int inputDataOffset = 4 ;
142+ constexpr int buttonDataOffset = inputDataOffset + 1 ;
105143
106- uint64_t ttlEventWord = (buttonState & 0x3F ) << 8 | (portState & 0xFF );
107- eventWords. enqueue (ttlEventWord );
144+ uint64_t inputState = *(dataPtr + inputDataOffset );
145+ uint64_t buttonState = *(dataPtr + buttonDataOffset );
108146
109- oni_destroy_frame (frame);
110- }
111- }
147+ for (int i = 0 ; i < NumDigitalInputs; i++)
148+ {
149+ digitalSamples[currentFrame + offset++ * NumFrames] = getChannelState (inputState, i);
150+ }
112151
113- uint64_t DigitalIO::getEventWord ()
114- {
115- uint64_t eventWord;
116- if (eventWords.try_dequeue (eventWord))
117- return eventWord;
152+ for (int i = 0 ; i < NumButtons; i++)
153+ {
154+ digitalSamples[currentFrame + offset++ * NumFrames] = getChannelState (buttonState, i);
155+ }
118156
119- return 0 ;
120- }
157+ eventCodes[currentFrame] = (buttonState & 0x3F ) << 8 | (inputState & 0xFF );
121158
122- bool DigitalIO::hasEventWord ()
123- {
124- return eventWords.peek () != nullptr ;
159+ oni_destroy_frame (frame);
160+
161+ if (++currentFrame >= NumFrames)
162+ {
163+ digitalBuffer->addToBuffer (digitalSamples.data (), sampleNumbers.data (), timestamps.data (), eventCodes.data (), NumFrames);
164+
165+ currentFrame = 0 ;
166+ }
167+ }
125168}
0 commit comments