2 * Copyright 2006, Haiku.
4 * Copyright (c) 2002-2003 Matthijs Hollemans
5 * Copyright (c) 2002 Jerome Leveque
6 * Distributed under the terms of the MIT License.
14 #include <MidiProducer.h>
15 #include <MidiRoster.h>
21 using namespace BPrivate
;
24 BMidiPort::BMidiPort(const char* name
)
30 fLocalSource
= new BMidiLocalProducer("MidiPortGlue(out)");
31 fLocalSink
= new BMidiPortGlue(this, "MidiPortGlue(in)");
32 fLocalSource
->Register();
33 fLocalSink
->Register();
45 BMidiPort::~BMidiPort()
52 fLocalSource
->Unregister();
53 fLocalSink
->Unregister();
54 fLocalSource
->Release();
55 fLocalSink
->Release();
60 BMidiPort::InitCheck() const
67 BMidiPort::Open(const char* name
)
74 for (int32 t
= 0; t
< fDevices
->CountItems(); ++t
) {
75 BMidiEndpoint
* endp
= (BMidiEndpoint
*)fDevices
->ItemAt(t
);
76 if (strcmp(name
, endp
->Name()) != 0)
78 if (!endp
->IsValid()) // still exists?
80 if (endp
->IsProducer()) {
81 if (fRemoteSource
== NULL
)
82 fRemoteSource
= (BMidiProducer
*)endp
;
84 if (fRemoteSink
== NULL
) {
85 fRemoteSink
= (BMidiConsumer
*)endp
;
86 fLocalSource
->Connect(fRemoteSink
);
91 if (fRemoteSource
!= NULL
) {
92 fPortName
= strdup(fRemoteSource
->Name());
94 } else if (fRemoteSink
!= NULL
) {
95 fPortName
= strdup(fRemoteSink
->Name());
107 if (fRemoteSource
!= NULL
) {
108 fRemoteSource
->Disconnect(fLocalSink
);
109 fRemoteSource
= NULL
;
112 if (fRemoteSink
!= NULL
) {
113 fLocalSource
->Disconnect(fRemoteSink
);
117 if (fPortName
!= NULL
) {
125 BMidiPort::PortName() const
133 uchar channel
, uchar note
, uchar velocity
, uint32 time
)
135 fLocalSource
->SprayNoteOff(channel
- 1, note
, velocity
, MAKE_BIGTIME(time
));
141 uchar channel
, uchar note
, uchar velocity
, uint32 time
)
143 fLocalSource
->SprayNoteOn(channel
- 1, note
, velocity
, MAKE_BIGTIME(time
));
148 BMidiPort::KeyPressure(
149 uchar channel
, uchar note
, uchar pressure
, uint32 time
)
151 fLocalSource
->SprayKeyPressure(
152 channel
- 1, note
, pressure
, MAKE_BIGTIME(time
));
157 BMidiPort::ControlChange(
158 uchar channel
, uchar controlNumber
, uchar controlValue
, uint32 time
)
160 fLocalSource
->SprayControlChange(
161 channel
- 1, controlNumber
, controlValue
, MAKE_BIGTIME(time
));
166 BMidiPort::ProgramChange(
167 uchar channel
, uchar programNumber
, uint32 time
)
169 fLocalSource
->SprayProgramChange(
170 channel
- 1, programNumber
, MAKE_BIGTIME(time
));
175 BMidiPort::ChannelPressure(uchar channel
, uchar pressure
, uint32 time
)
177 fLocalSource
->SprayChannelPressure(
178 channel
- 1, pressure
, MAKE_BIGTIME(time
));
183 BMidiPort::PitchBend(uchar channel
, uchar lsb
, uchar msb
, uint32 time
)
185 fLocalSource
->SprayPitchBend(channel
- 1, lsb
, msb
, MAKE_BIGTIME(time
));
190 BMidiPort::SystemExclusive(void* data
, size_t length
, uint32 time
)
192 fLocalSource
->SpraySystemExclusive(data
, length
, MAKE_BIGTIME(time
));
197 BMidiPort::SystemCommon(
198 uchar status
, uchar data1
, uchar data2
, uint32 time
)
200 fLocalSource
->SpraySystemCommon(status
, data1
, data2
, MAKE_BIGTIME(time
));
205 BMidiPort::SystemRealTime(uchar status
, uint32 time
)
207 fLocalSource
->SpraySystemRealTime(status
, MAKE_BIGTIME(time
));
214 status_t err
= super::Start();
216 if ((err
== B_OK
) && (fRemoteSource
!= NULL
)) {
217 return fRemoteSource
->Connect(fLocalSink
);
227 if (fRemoteSource
!= NULL
) {
228 fRemoteSource
->Disconnect(fLocalSink
);
236 BMidiPort::CountDevices()
238 return fDevices
->CountItems();
243 BMidiPort::GetDeviceName(int32 n
, char* name
, size_t bufSize
)
245 BMidiEndpoint
* endp
= (BMidiEndpoint
*)fDevices
->ItemAt(n
);
249 size_t size
= strlen(endp
->Name());
251 return B_NAME_TOO_LONG
;
253 strcpy(name
, endp
->Name());
258 void BMidiPort::_ReservedMidiPort1() { }
259 void BMidiPort::_ReservedMidiPort2() { }
260 void BMidiPort::_ReservedMidiPort3() { }
266 while (KeepRunning())
272 BMidiPort::ScanDevices()
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.
284 for (int32 t
= 0; t
< fDevices
->CountItems(); ++t
) {
285 BMidiEndpoint
* other
= (BMidiEndpoint
*)fDevices
->ItemAt(t
);
286 if (strcmp(endp
->Name(), other
->Name()) == 0) {
293 fDevices
->AddItem(endp
);
302 BMidiPort::EmptyDeviceList()
304 for (int32 t
= 0; t
< fDevices
->CountItems(); ++t
)
305 ((BMidiEndpoint
*)fDevices
->ItemAt(t
))->Release();
307 fDevices
->MakeEmpty();