Jamoma API  0.6.0.a19
MIDIInput.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup modularMIDI
4  *
5  * @brief bind to an external device source
6  *
7  * @details MidiInput receives messages from one external device. @n
8  * It is a wrapper around the PortMidi library. @n
9  *
10  * @author Theo Delahogue
11  *
12  * @copyright © 2014, GMEA (http://www.gmea.net) @n
13  * This code is licensed under the terms of the "New BSD License" @n
14  * http://creativecommons.org/licenses/BSD/
15  */
16 
17 #include "MIDIInput.h"
18 
19 MIDIInput::MIDIInput(MIDIPtr protocol, TTSymbol& application) :
20 mProtocol(protocol),
21 mStream(NULL),
22 mPollingThread(NULL),
23 mRunning(NO),
24 mApplication(application)
25 {
26  ;
27 }
28 
29 MIDIInput::~MIDIInput()
30 {
31  mRunning = NO;
32 
33  if (mStream) {
34  Pm_Close(mStream);
35  mStream = NULL;
36  }
37 
38  if (mPollingThread)
39  mPollingThread->wait();
40  delete mPollingThread;
41 }
42 
43 TTErr MIDIInput::setName(TTSymbol& newName)
44 {
45  const PmDeviceInfo* deviceInfo;
46  int i, deviceCount;
47  PmError err = pmNoError;
48 
49  if (newName != mName) {
50 
51  // check there is an input with this name
52  deviceCount = Pm_CountDevices();
53  for (i = 0; i < deviceCount; i++) {
54 
55  deviceInfo = Pm_GetDeviceInfo(i);
56 
57  if (deviceInfo->input && newName == TTSymbol(deviceInfo->name))
58  break;
59  }
60 
61  if (i == deviceCount)
62  return kTTErrGeneric;
63 
64  mName = newName;
65 
66  setRunning(NO);
67 
68  if (mStream) {
69  Pm_Close(mStream);
70  mStream = NULL;
71  }
72 
73  err = Pm_OpenInput(&mStream, i, NULL, kMidiBufferSize, NULL, NULL);
74  if (err) {
75 
76  TTLogError("MIDIInput::setName : can't open the %s device\n", mName.c_str());
77  return kTTErrGeneric;
78  }
79  }
80 
81  return kTTErrNone;
82 }
83 
84 TTErr MIDIInput::setRunning(TTBoolean running)
85 {
86  if (running != mRunning) {
87 
88  mRunning = running;
89 
90  if (mRunning) {
91 
92  mPollingThread = new TTThread(TTThreadCallbackType(MIDIInputPoll), this);
93  }
94  else {
95 
96  if (mPollingThread)
97  mPollingThread->wait();
98  delete mPollingThread;
99  }
100  }
101 
102  return kTTErrNone;
103 }
104 
105 void* MIDIInputPoll(MIDIInput* self)
106 {
107  PmEvent buffer[64];
108  int result;
109 
110  while (self->mRunning) {
111 
112  if (Pm_Poll(self->mStream)) {
113 
114  result = Pm_Read(self->mStream, buffer, 64);
115 
116  // result is an error number
117  if (result < 0) {
118 
119  TTLogError("MidiPoll error\n");
120  }
121  // result is the number of midi events
122  else {
123 
124  MIDIParserFrom parser;
125 
126  for (TTInt32 i = 0; i < result; i++) {
127 
128  // if the parsing is done : pass address and value
129  if (parser.parse(Pm_MessageStatus(buffer[i].message), Pm_MessageData1(buffer[i].message), Pm_MessageData2(buffer[i].message)))
130  self->mProtocol->receivedMessage(self->mApplication, parser.address, parser.value);
131  }
132  }
133  }
134 
135  self->mPollingThread->sleep(1);
136  }
137 
138  return NULL;
139 }
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
void * MIDIInputPoll(MIDIInput *self)
the function call by the polling thread
Definition: MIDIInput.cpp:105
bind to an external device source
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
void TTFOUNDATION_EXPORT TTLogError(TTImmutableCString message,...)
Platform and host independent method for posting errors.
Definition: TTBase.cpp:572
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
Definition: TTBase.h:344
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
No Error.
Definition: TTBase.h:343