tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / midi / MidiPort.cpp
blob78b6d0ab83d1416809acdf9f8af220c09fcd241b
1 /*
2 * Copyright 2006, Haiku.
3 *
4 * Copyright (c) 2002-2003 Matthijs Hollemans
5 * Copyright (c) 2002 Jerome Leveque
6 * Distributed under the terms of the MIT License.
8 * Authors:
9 * Matthijs Hollemans
10 * Jérôme Leveque
13 #include <MidiPort.h>
14 #include <MidiProducer.h>
15 #include <MidiRoster.h>
16 #include <stdlib.h>
18 #include "debug.h"
19 #include "MidiGlue.h"
21 using namespace BPrivate;
24 BMidiPort::BMidiPort(const char* name)
26 fPortName = NULL;
27 fDevices = new BList;
28 fStatus = B_ERROR;
30 fLocalSource = new BMidiLocalProducer("MidiPortGlue(out)");
31 fLocalSink = new BMidiPortGlue(this, "MidiPortGlue(in)");
32 fLocalSource->Register();
33 fLocalSink->Register();
35 fRemoteSource = NULL;
36 fRemoteSink = NULL;
38 ScanDevices();
40 if (name != NULL)
41 Open(name);
45 BMidiPort::~BMidiPort()
47 Close();
49 EmptyDeviceList();
50 delete fDevices;
52 fLocalSource->Unregister();
53 fLocalSink->Unregister();
54 fLocalSource->Release();
55 fLocalSink->Release();
59 status_t
60 BMidiPort::InitCheck() const
62 return fStatus;
66 status_t
67 BMidiPort::Open(const char* name)
69 fStatus = B_ERROR;
71 if (name != NULL) {
72 Close();
74 for (int32 t = 0; t < fDevices->CountItems(); ++t) {
75 BMidiEndpoint* endp = (BMidiEndpoint*)fDevices->ItemAt(t);
76 if (strcmp(name, endp->Name()) != 0)
77 continue;
78 if (!endp->IsValid()) // still exists?
79 continue;
80 if (endp->IsProducer()) {
81 if (fRemoteSource == NULL)
82 fRemoteSource = (BMidiProducer*)endp;
83 } else {
84 if (fRemoteSink == NULL) {
85 fRemoteSink = (BMidiConsumer*)endp;
86 fLocalSource->Connect(fRemoteSink);
91 if (fRemoteSource != NULL) {
92 fPortName = strdup(fRemoteSource->Name());
93 fStatus = B_OK;
94 } else if (fRemoteSink != NULL) {
95 fPortName = strdup(fRemoteSink->Name());
96 fStatus = B_OK;
100 return fStatus;
104 void
105 BMidiPort::Close()
107 if (fRemoteSource != NULL) {
108 fRemoteSource->Disconnect(fLocalSink);
109 fRemoteSource = NULL;
112 if (fRemoteSink != NULL) {
113 fLocalSource->Disconnect(fRemoteSink);
114 fRemoteSink = NULL;
117 if (fPortName != NULL) {
118 free(fPortName);
119 fPortName = NULL;
124 const char*
125 BMidiPort::PortName() const
127 return fPortName;
131 void
132 BMidiPort::NoteOff(
133 uchar channel, uchar note, uchar velocity, uint32 time)
135 fLocalSource->SprayNoteOff(channel - 1, note, velocity, MAKE_BIGTIME(time));
139 void
140 BMidiPort::NoteOn(
141 uchar channel, uchar note, uchar velocity, uint32 time)
143 fLocalSource->SprayNoteOn(channel - 1, note, velocity, MAKE_BIGTIME(time));
147 void
148 BMidiPort::KeyPressure(
149 uchar channel, uchar note, uchar pressure, uint32 time)
151 fLocalSource->SprayKeyPressure(
152 channel - 1, note, pressure, MAKE_BIGTIME(time));
156 void
157 BMidiPort::ControlChange(
158 uchar channel, uchar controlNumber, uchar controlValue, uint32 time)
160 fLocalSource->SprayControlChange(
161 channel - 1, controlNumber, controlValue, MAKE_BIGTIME(time));
165 void
166 BMidiPort::ProgramChange(
167 uchar channel, uchar programNumber, uint32 time)
169 fLocalSource->SprayProgramChange(
170 channel - 1, programNumber, MAKE_BIGTIME(time));
174 void
175 BMidiPort::ChannelPressure(uchar channel, uchar pressure, uint32 time)
177 fLocalSource->SprayChannelPressure(
178 channel - 1, pressure, MAKE_BIGTIME(time));
182 void
183 BMidiPort::PitchBend(uchar channel, uchar lsb, uchar msb, uint32 time)
185 fLocalSource->SprayPitchBend(channel - 1, lsb, msb, MAKE_BIGTIME(time));
189 void
190 BMidiPort::SystemExclusive(void* data, size_t length, uint32 time)
192 fLocalSource->SpraySystemExclusive(data, length, MAKE_BIGTIME(time));
196 void
197 BMidiPort::SystemCommon(
198 uchar status, uchar data1, uchar data2, uint32 time)
200 fLocalSource->SpraySystemCommon(status, data1, data2, MAKE_BIGTIME(time));
204 void
205 BMidiPort::SystemRealTime(uchar status, uint32 time)
207 fLocalSource->SpraySystemRealTime(status, MAKE_BIGTIME(time));
211 status_t
212 BMidiPort::Start()
214 status_t err = super::Start();
216 if ((err == B_OK) && (fRemoteSource != NULL)) {
217 return fRemoteSource->Connect(fLocalSink);
220 return err;
224 void
225 BMidiPort::Stop()
227 if (fRemoteSource != NULL) {
228 fRemoteSource->Disconnect(fLocalSink);
231 super::Stop();
235 int32
236 BMidiPort::CountDevices()
238 return fDevices->CountItems();
242 status_t
243 BMidiPort::GetDeviceName(int32 n, char* name, size_t bufSize)
245 BMidiEndpoint* endp = (BMidiEndpoint*)fDevices->ItemAt(n);
246 if (endp == NULL)
247 return B_BAD_VALUE;
249 size_t size = strlen(endp->Name());
250 if (size >= bufSize)
251 return B_NAME_TOO_LONG;
253 strcpy(name, endp->Name());
254 return B_OK;
258 void BMidiPort::_ReservedMidiPort1() { }
259 void BMidiPort::_ReservedMidiPort2() { }
260 void BMidiPort::_ReservedMidiPort3() { }
263 void
264 BMidiPort::Run()
266 while (KeepRunning())
267 snooze(50000);
271 void
272 BMidiPort::ScanDevices()
274 EmptyDeviceList();
276 int32 id = 0;
277 BMidiEndpoint* endp;
279 while ((endp = BMidiRoster::NextEndpoint(&id)) != NULL) {
280 // Each hardware port has two endpoints associated with it, a consumer
281 // and a producer. Both have the same name, so we add only one of them.
283 bool addItem = true;
284 for (int32 t = 0; t < fDevices->CountItems(); ++t) {
285 BMidiEndpoint* other = (BMidiEndpoint*)fDevices->ItemAt(t);
286 if (strcmp(endp->Name(), other->Name()) == 0) {
287 addItem = false;
288 break;
292 if (addItem) {
293 fDevices->AddItem(endp);
294 } else {
295 endp->Release();
301 void
302 BMidiPort::EmptyDeviceList()
304 for (int32 t = 0; t < fDevices->CountItems(); ++t)
305 ((BMidiEndpoint*)fDevices->ItemAt(t))->Release();
307 fDevices->MakeEmpty();