1/* 2 * Copyright 2006, Haiku. 3 * 4 * Copyright (c) 2002-2003 Matthijs Hollemans 5 * Copyright (c) 2002 Michael Pfeiffer 6 * Copyright (c) 2002 Jerome Leveque 7 * Copyright (c) 2002 Paul Stadler 8 * Distributed under the terms of the MIT License. 9 * 10 * Authors: 11 * Matthijs Hollemans 12 * Michael Pfeiffer 13 * J��r��me Leveque 14 * Paul Stadler 15 */ 16 17#include <List.h> 18#include <Midi.h> 19#include <MidiProducer.h> 20 21#include "MidiGlue.h" 22#include "debug.h" 23 24using namespace BPrivate; 25 26 27status_t 28_run_thread(void* data) 29{ 30 BMidi* midi = (BMidi*)data; 31 midi->Run(); 32 midi->fIsRunning = false; 33 return 0; 34} 35 36 37BMidi::BMidi() 38{ 39 fConnections = new BList; 40 fThreadId = -1; 41 fIsRunning = false; 42 43 fProducer = new BMidiLocalProducer("MidiGlue(out)"); 44 fConsumer = new BMidiGlue(this, "MidiGlue(in)"); 45} 46 47 48BMidi::~BMidi() 49{ 50 Stop(); 51 52 status_t result; 53 wait_for_thread(fThreadId, &result); 54 55 fProducer->Release(); 56 fConsumer->Release(); 57 58 delete fConnections; 59} 60 61 62void 63BMidi::NoteOff(uchar channel, uchar note, uchar velocity, uint32 time) 64{ 65 // do nothing 66} 67 68 69void 70BMidi::NoteOn(uchar channel, uchar note, uchar velocity, uint32 time) 71{ 72 // do nothing 73} 74 75 76void 77BMidi::KeyPressure( 78 uchar channel, uchar note, uchar pressure, uint32 time) 79{ 80 // do nothing 81} 82 83 84void 85BMidi::ControlChange( 86 uchar channel, uchar controlNumber, uchar controlValue, uint32 time) 87{ 88 // do nothing 89} 90 91 92void 93BMidi::ProgramChange(uchar channel, uchar programNumber, uint32 time) 94{ 95 // do nothing 96} 97 98 99void 100BMidi::ChannelPressure(uchar channel, uchar pressure, uint32 time) 101{ 102 // do nothing 103} 104 105 106void 107BMidi::PitchBend(uchar channel, uchar lsb, uchar msb, uint32 time) 108{ 109 // do nothing 110} 111 112 113void 114BMidi::SystemExclusive(void* data, size_t length, uint32 time) 115{ 116 // do nothing 117} 118 119 120void 121BMidi::SystemCommon(uchar status, uchar data1, uchar data2, uint32 time) 122{ 123 // do nothing 124} 125 126 127void 128BMidi::SystemRealTime(uchar status, uint32 time) 129{ 130 // do nothing 131} 132 133 134void 135BMidi::TempoChange(int32 beatsPerMinute, uint32 time) 136{ 137 // do nothing 138} 139 140 141void 142BMidi::AllNotesOff(bool justChannel, uint32 time) 143{ 144 for (uchar channel = 1; channel <= 16; ++channel) { 145 SprayControlChange(channel, B_ALL_NOTES_OFF, 0, time); 146 147 if (!justChannel) { 148 for (uchar note = 0; note <= 0x7F; ++note) { 149 SprayNoteOff(channel, note, 0, time); 150 } 151 } 152 } 153} 154 155 156status_t 157BMidi::Start() 158{ 159 if (fIsRunning) 160 return B_OK; 161 162 status_t err = spawn_thread( 163 _run_thread, "MidiRunThread", B_URGENT_PRIORITY, this); 164 165 if (err < B_OK) 166 return err; 167 168 fThreadId = err; 169 fIsRunning = true; 170 171 err = resume_thread(fThreadId); 172 if (err != B_OK) { 173 fThreadId = -1; 174 fIsRunning = false; 175 } 176 177 return err; 178} 179 180 181void 182BMidi::Stop() 183{ 184 AllNotesOff(); 185 fThreadId = -1; 186} 187 188 189bool 190BMidi::IsRunning() const 191{ 192 return fIsRunning; 193} 194 195 196void 197BMidi::Connect(BMidi* toObject) 198{ 199 if (toObject != NULL) { 200 if (fProducer->Connect(toObject->fConsumer) == B_OK) { 201 fConnections->AddItem(toObject); 202 } 203 } 204} 205 206 207void 208BMidi::Disconnect(BMidi* fromObject) 209{ 210 if (fromObject == NULL) 211 return; 212 213 if (fProducer->Disconnect(fromObject->fConsumer) == B_OK) { 214 fConnections->RemoveItem(fromObject); 215 } 216} 217 218 219bool 220BMidi::IsConnected(BMidi* toObject) const 221{ 222 if (toObject != NULL) 223 return fProducer->IsConnected(toObject->fConsumer); 224 225 return false; 226} 227 228 229BList* 230BMidi::Connections() const 231{ 232 return fConnections; 233} 234 235 236void 237BMidi::SnoozeUntil(uint32 time) const 238{ 239 snooze_until(MAKE_BIGTIME(time), B_SYSTEM_TIMEBASE); 240} 241 242 243bool 244BMidi::KeepRunning() 245{ 246 return (fThreadId != -1); 247} 248 249 250void BMidi::_ReservedMidi1() {} 251void BMidi::_ReservedMidi2() {} 252void BMidi::_ReservedMidi3() {} 253 254 255void 256BMidi::Run() 257{ 258 // do nothing 259} 260 261 262void 263BMidi::SprayNoteOff( 264 uchar channel, uchar note, uchar velocity, uint32 time) const 265{ 266 fProducer->SprayNoteOff( 267 channel - 1, note, velocity, MAKE_BIGTIME(time)); 268} 269 270 271void 272BMidi::SprayNoteOn( 273 uchar channel, uchar note, uchar velocity, uint32 time) const 274{ 275 fProducer->SprayNoteOn( 276 channel - 1, note, velocity, MAKE_BIGTIME(time)); 277} 278 279 280void 281BMidi::SprayKeyPressure( 282 uchar channel, uchar note, uchar pressure, uint32 time) const 283{ 284 fProducer->SprayKeyPressure( 285 channel - 1, note, pressure, MAKE_BIGTIME(time)); 286} 287 288 289void 290BMidi::SprayControlChange( 291 uchar channel, uchar controlNumber, uchar controlValue, 292 uint32 time) const 293{ 294 fProducer->SprayControlChange( 295 channel - 1, controlNumber, controlValue, MAKE_BIGTIME(time)); 296} 297 298 299void 300BMidi::SprayProgramChange( 301 uchar channel, uchar programNumber, uint32 time) const 302{ 303 fProducer->SprayProgramChange( 304 channel - 1, programNumber, MAKE_BIGTIME(time)); 305} 306 307 308void 309BMidi::SprayChannelPressure( 310 uchar channel, uchar pressure, uint32 time) const 311{ 312 fProducer->SprayChannelPressure( 313 channel - 1, pressure, MAKE_BIGTIME(time)); 314} 315 316 317void 318BMidi::SprayPitchBend( 319 uchar channel, uchar lsb, uchar msb, uint32 time) const 320{ 321 fProducer->SprayPitchBend(channel - 1, lsb, msb, MAKE_BIGTIME(time)); 322} 323 324 325void 326BMidi::SpraySystemExclusive( 327 void* data, size_t length, uint32 time) const 328{ 329 fProducer->SpraySystemExclusive(data, length, MAKE_BIGTIME(time)); 330} 331 332 333void 334BMidi::SpraySystemCommon( 335 uchar status, uchar data1, uchar data2, uint32 time) const 336{ 337 fProducer->SpraySystemCommon(status, data1, data2, MAKE_BIGTIME(time)); 338} 339 340 341void 342BMidi::SpraySystemRealTime(uchar status, uint32 time) const 343{ 344 fProducer->SpraySystemRealTime(status, MAKE_BIGTIME(time)); 345} 346 347 348void 349BMidi::SprayTempoChange(int32 beatsPerMinute, uint32 time) const 350{ 351 fProducer->SprayTempoChange(beatsPerMinute, MAKE_BIGTIME(time)); 352} 353 354