Jamoma API  0.6.0.a19
TTMidiOutput.cpp
1 /*
2  * Midi Input Object
3  * Copyright © 2011, Timothy Place
4  *
5  * License: This code is licensed under the terms of the "New BSD License"
6  * http://creativecommons.org/licenses/BSD/
7  */
8 
9 #include "TTGraphObjectBase.h"
10 #include "TTMidiOutput.h"
11 #ifdef TT_PLATFORM_WIN
12 #include <algorithm>
13 #endif
14 
15 #define thisTTClass TTMidiOutput
16 #define thisTTClassName "midi.out"
17 #define thisTTClassTags "midi, output"
18 
19 
20 static const int kMidiBufferSize = 100; // This is arbitrary, is there a more rational value for this?
21 
22 
24  mStream(NULL)
25 {
26  PmError err = Pm_Initialize();
27 
28  if (err) {
29  logError("err %ld from Pm_Initialize()", err);
30  }
31 
33 
34  addMessageWithArguments(dictionary);
35  addMessageWithArguments(getAvailableDeviceNames);
36 
37  setAttributeValue(TT("device"), TT("default"));
38 }
39 
40 
41 TTMidiOutput::~TTMidiOutput()
42 {
43  // TODO: we are supposed to call Pm_Terminate() when we are done using the library
44  // but we don't currently have a "shutdown" method for classes when the system is torn down
45 }
46 
47 
48 TTErr TTMidiOutput::dictionary(const TTValue& aDictionaryValue, TTValue&)
49 {
50  TTDictionaryPtr d = NULL;
51  TTSymbol schema;
52 
53  //aDictionaryValue.get(0, (TTPtr*)(&d));
54  d = TTDictionaryPtr(TTPtr(aDictionaryValue[0]));
55 
56  schema = d->getSchema();
57  if (schema == TT("RawMidiEvent")) {
58  TTValue statusByte;
59  TTValue dataByte1;
60  TTValue dataByte2;
61  int msg;
62 
63  d->lookup(TT("status"), statusByte);
64  d->lookup(TT("data1"), dataByte1);
65  d->lookup(TT("data2"), dataByte2);
66  msg = Pm_Message(TTUInt8(statusByte), TTUInt8(dataByte1), TTUInt8(dataByte2));
67 
68  Pm_WriteShort(mStream, 0, msg);
69  return kTTErrNone;
70  }
71  else {
72  return kTTErrInvalidType;
73  }
74 
75 }
76 
77 
78 TTErr TTMidiOutput::getAvailableDeviceNames(const TTValue&, TTValue& returnedDeviceNames)
79 {
80  const PmDeviceInfo* deviceInfo = NULL;
81  int deviceCount = Pm_CountDevices();
82 
83  returnedDeviceNames.clear();
84 
85  if (deviceCount < 0) {
86  logError("Pa_CountDevices() returned 0x%x\n", deviceCount);
87  return kTTErrGeneric;
88  }
89 
90  for (int i=0; i<deviceCount; i++) {
91  deviceInfo = Pm_GetDeviceInfo(i);
92  if (deviceInfo->output)
93  returnedDeviceNames.append(TT(deviceInfo->name));
94  }
95  return kTTErrNone;
96 }
97 
98 
99 TTErr TTMidiOutput::setDevice(TTValue& newDeviceName)
100 {
101  TTSymbol newDevice = newDeviceName;
102  const PmDeviceInfo* deviceInfo;
103  int deviceCount;
104  PmError err = pmNoError;
105 
106  if (newDevice != mDevice) {
107  if (newDevice == TT("default")) {
108  mID = Pm_GetDefaultInputDeviceID();
109  mDeviceInfo = Pm_GetDeviceInfo(mID);
110  }
111  else {
112  int i;
113 
114  deviceCount = Pm_CountDevices();
115  for (i=0; i<deviceCount; i++) {
116  deviceInfo = Pm_GetDeviceInfo(i);
117  if (newDevice == TT(deviceInfo->name)) {
118  mDeviceInfo = deviceInfo;
119  mID = i;
120  break;
121  }
122  }
123  if (i == deviceCount)
124  return kTTErrGeneric;
125  }
126 
127  mDevice = newDevice;
128 
129  if (mStream) {
130  Pm_Close(mStream);
131  mStream = NULL;
132  }
133 
134  err = Pm_OpenOutput(&mStream, mID, NULL, kMidiBufferSize, NULL, NULL, 0);
135  if (err) {
136  logError("uh oh\n");
137  }
138  }
139  return kTTErrNone;
140 }
141 
TTSymbol mDevice
attr: selected device name
Definition: TTMidiOutput.h:26
TTErr logError(TTImmutableCString fmtstring,...)
Log errors scoped to this object instance.
Bad DataType for the context.
Definition: TTBase.h:347
const PmDeviceInfo * mDeviceInfo
selected device info struct
Definition: TTMidiOutput.h:27
Jamoma Asynchronous Object Graph Layer.
Symbol type.
Definition: TTBase.h:282
A type that represents the key as a C-String and the value as a pointer to the matching TTSymbol obje...
Definition: TTDictionary.h:47
#define TT
This macro is defined as a shortcut for doing a lookup in the symbol table.
Definition: TTSymbol.h:155
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
PortMidiStream * mStream
a descriptor for a MIDI device that is opened when the device is set
Definition: TTMidiOutput.h:29
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
const TTSymbol getSchema() const
TODO: Add documentation.
Definition: TTDictionary.h:181
#define addMessageWithArguments(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:27
void clear()
Clear all values from the vector, leaving with size of 0.
Definition: TTValue.h:131
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
TTErr lookup(const TTSymbol aKey, TTValue &aValue) const
Find the value for the given key.
Definition: TTDictionary.h:221
PmDeviceID mID
selected device ID number
Definition: TTMidiOutput.h:28
#define addAttributeWithSetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom setter...
Definition: TTAttribute.h:47
No Error.
Definition: TTBase.h:343
TTDictionary * TTDictionaryPtr
[doxygenAppendixC_typedefExample]
Definition: TTDictionary.h:279
TT_OBJECT_CONSTRUCTOR
Constructor macro.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
unsigned char TTUInt8
8 bit unsigned integer (char)
Definition: TTBase.h:174