Bela
Real-time, ultra-low-latency audio and sensor processing system for BeagleBone Black
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
DigitalChannelManager.h
1 /*
2  * DigitalStream.h
3  *
4  * Created on: 7 Jun 2016
5  * Author: giulio
6  */
7 
8 #ifndef DIGITALCHANNELMANAGER_H_
9 #define DIGITALCHANNELMANAGER_H_
10 #include <Bela.h>
11 
35 public:
37 
50  void setCallback(void (*newCallback)(bool, unsigned int, void*)){
51  stateChangedCallback = newCallback;
52  if(newCallback != NULL){
53  callbackEnabled = true;
54  } else {
55  callbackEnabled = false;
56  }
57  };
58 
68  void setCallbackArgument(unsigned int channel, void* arg){
69  callbackArguments[channel] = arg;
70  }
71 
82  void processInput(uint32_t* array, unsigned int length){
83  if(callbackEnabled == false){
84  return;
85  }
86  // DIGITAL_FORMAT_ASSUMPTION
87  static uint16_t lastDigitalInputValues = 0;
88  for (unsigned int frame = 0; frame < length; ++frame) {
89  uint32_t inWord = array[frame];
90  uint16_t direction = inWord & 0Xffff;
91  uint16_t inputValues = (inWord >> 16);
92  // note: even though INPUT == 0 and OUTPUT == 0, this is actually reversed in the binary word,
93  // so it actually is 1 for input and 0 for output
94 
95  // mask out outputValues from the half-word by setting them to zero
96  // if a bit of direction is 1, then it is an input.
97  // ANDing this with the inputValues gets rid of the output values
98  inputValues &= direction;
99  uint16_t changed = inputValues ^ lastDigitalInputValues;
100  //mask out channels that are not set at message rate
101  changed &= messageRate;
102  if(changed){
103 // rt_printf("changed: 0x%x, messageRate: 0x%x, ANDed: 0x%x\n", changed, messageRate, changed&messageRate);
104  for(int n = 0; n < 16; ++n){
105  if(changed & (1 << n)){ //if state for this channel has changed, invoke the callback
106  stateChangedCallback(inputValues & (1 << n), frame, callbackArguments[n]);
107  }
108  }
109  }
110  lastDigitalInputValues = inputValues;
111  }
112  }
113 
126  void processOutput(uint32_t* array, unsigned int length){
127  uint32_t orWord = ((setDataOut << 16) | modeInput);
128  uint32_t andWord = ~((clearDataOut << 16) | modeOutput);
129  uint32_t outWord;
130  for (unsigned int frame = 0; frame < length; ++frame) {
131  outWord = array[frame];
132  outWord = outWord | orWord;
133  outWord = outWord & andWord;
134  array[frame] = outWord;
135  }
136  }
137 
143  bool isSignalRate(unsigned int channel){
144  return (bool)((1 << channel) & signalRate);
145  }
146 
153  bool isMessageRate(unsigned int channel){
154  return (bool)((1 << channel) & messageRate);
155  }
156 
163  bool isInput(unsigned int channel){
164  return (bool)((1 << channel) & modeInput);
165  }
166 
173  bool isOutput(unsigned int channel){
174  return (bool)((1 << channel) & modeOutput);
175  }
176 
183  void setValue(unsigned int channel, bool value){
184  if(value == 0){
185  clearDataOut = Bela_setBit(clearDataOut, channel);
186  setDataOut = Bela_clearBit(setDataOut, channel);
187  } else {
188  setDataOut = Bela_setBit(setDataOut, channel);
189  clearDataOut = Bela_clearBit(clearDataOut, channel);
190  }
191  }
192 
198  void unmanage(unsigned int channel){
199  messageRate = Bela_clearBit(messageRate, channel);
200  signalRate = Bela_clearBit(signalRate, channel);
201  modeInput = Bela_clearBit(modeInput, channel);
202  modeOutput = Bela_clearBit(modeOutput, channel);
203  clearDataOut = Bela_clearBit(clearDataOut, channel);
204  setDataOut = Bela_clearBit(setDataOut, channel);
205  }
206 
218  void manage(unsigned int channel, bool direction, bool isMessageRate){
219  // direction is expected to be one of INPUT or OUTPUT
220  messageRate = Bela_changeBit(messageRate, channel, isMessageRate);
221  signalRate = Bela_changeBit(signalRate, channel, !isMessageRate);
222  if(direction == OUTPUT){
223  modeOutput = Bela_setBit(modeOutput, channel);
224  modeInput = Bela_clearBit(modeInput, channel);
225  } else { // direction == INPUT
226  modeInput = Bela_setBit(modeInput, channel);
227  modeOutput = Bela_clearBit(modeOutput, channel);
228  }
229  if(verbose)
230  rt_printf("Bela digital: channel %d is set as %s at %s rate\n", channel,
231  isInput(channel) ? "input" : "output", isSignalRate(channel) ? "signal" : "message");
232  }
233 
234  void setVerbose(bool isVerbose);
235  virtual ~DigitalChannelManager();
236 private:
237  bool callbackEnabled;
238  void* callbackArguments[16];
239  void (*stateChangedCallback)(bool value, unsigned int delay, void* arg);
240  uint32_t clearDataOut;
241  uint32_t setDataOut;
242  uint16_t modeOutput;
243  uint16_t modeInput;
244  uint16_t messageRate;
245  uint16_t signalRate;
246  bool verbose;
247 };
248 
249 #endif /* DIGITALCHANNELMANAGER_H_ */
void processOutput(uint32_t *array, unsigned int length)
Definition: DigitalChannelManager.h:126
Definition: DigitalChannelManager.h:34
bool isMessageRate(unsigned int channel)
Definition: DigitalChannelManager.h:153
bool isOutput(unsigned int channel)
Definition: DigitalChannelManager.h:173
bool isSignalRate(unsigned int channel)
Definition: DigitalChannelManager.h:143
bool isInput(unsigned int channel)
Definition: DigitalChannelManager.h:163
void setValue(unsigned int channel, bool value)
Definition: DigitalChannelManager.h:183
void manage(unsigned int channel, bool direction, bool isMessageRate)
Definition: DigitalChannelManager.h:218
void unmanage(unsigned int channel)
Definition: DigitalChannelManager.h:198
void processInput(uint32_t *array, unsigned int length)
Definition: DigitalChannelManager.h:82
Main Bela public API.
void setCallbackArgument(unsigned int channel, void *arg)
Definition: DigitalChannelManager.h:68
void setCallback(void(*newCallback)(bool, unsigned int, void *))
Definition: DigitalChannelManager.h:50