Mercurial > hg > sonic-visualiser
comparison main/MainWindow.cpp @ 307:d4ff14feca76
* Make it possible to record live MIDI to a note layer.
  Now we're a proper MIDI sequencer. Ha, ha.
| author | Chris Cannam | 
|---|---|
| date | Wed, 25 Feb 2009 12:02:53 +0000 | 
| parents | 8fbbfea74058 | 
| children | 4ad11b1cf050 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 306:8fbbfea74058 | 307:d4ff14feca76 | 
|---|---|
| 30 #include "base/Preferences.h" | 30 #include "base/Preferences.h" | 
| 31 #include "layer/WaveformLayer.h" | 31 #include "layer/WaveformLayer.h" | 
| 32 #include "layer/TimeRulerLayer.h" | 32 #include "layer/TimeRulerLayer.h" | 
| 33 #include "layer/TimeInstantLayer.h" | 33 #include "layer/TimeInstantLayer.h" | 
| 34 #include "layer/TimeValueLayer.h" | 34 #include "layer/TimeValueLayer.h" | 
| 35 #include "layer/NoteLayer.h" | |
| 35 #include "layer/Colour3DPlotLayer.h" | 36 #include "layer/Colour3DPlotLayer.h" | 
| 36 #include "layer/SliceLayer.h" | 37 #include "layer/SliceLayer.h" | 
| 37 #include "layer/SliceableLayer.h" | 38 #include "layer/SliceableLayer.h" | 
| 38 #include "layer/ImageLayer.h" | 39 #include "layer/ImageLayer.h" | 
| 39 #include "widgets/Fader.h" | 40 #include "widgets/Fader.h" | 
| 135 m_rightButtonTransformsMenu(0), | 136 m_rightButtonTransformsMenu(0), | 
| 136 m_rightButtonPlaybackMenu(0), | 137 m_rightButtonPlaybackMenu(0), | 
| 137 m_soloAction(0), | 138 m_soloAction(0), | 
| 138 m_soloModified(false), | 139 m_soloModified(false), | 
| 139 m_prevSolo(false), | 140 m_prevSolo(false), | 
| 140 m_lastInsertedMIDITime(0), | |
| 141 m_rwdStartAction(0), | 141 m_rwdStartAction(0), | 
| 142 m_rwdAction(0), | 142 m_rwdAction(0), | 
| 143 m_ffwdAction(0), | 143 m_ffwdAction(0), | 
| 144 m_ffwdEndAction(0), | 144 m_ffwdEndAction(0), | 
| 145 m_playAction(0), | 145 m_playAction(0), | 
| 3411 } | 3411 } | 
| 3412 | 3412 | 
| 3413 void | 3413 void | 
| 3414 MainWindow::midiEventsAvailable() | 3414 MainWindow::midiEventsAvailable() | 
| 3415 { | 3415 { | 
| 3416 Pane *currentPane = 0; | |
| 3417 NoteLayer *currentNoteLayer = 0; | |
| 3418 | |
| 3419 if (m_paneStack) currentPane = m_paneStack->getCurrentPane(); | |
| 3420 if (currentPane) { | |
| 3421 currentNoteLayer = dynamic_cast<NoteLayer *> | |
| 3422 (currentPane->getSelectedLayer()); | |
| 3423 } | |
| 3424 | |
| 3416 // This is called through a serialised signal/slot invocation | 3425 // This is called through a serialised signal/slot invocation | 
| 3417 // (across threads). It could happen quite some time after the | 3426 // (across threads). It could happen quite some time after the | 
| 3418 // event was actually received, which is why event timestamping | 3427 // event was actually received, which is why event timestamping | 
| 3419 // happens in the MIDI input class and not here. | 3428 // happens in the MIDI input class and not here. | 
| 3429 | |
| 3420 while (m_midiInput->getEventsAvailable() > 0) { | 3430 while (m_midiInput->getEventsAvailable() > 0) { | 
| 3421 MIDIEvent ev(m_midiInput->readEvent()); | 3431 MIDIEvent ev(m_midiInput->readEvent()); | 
| 3422 if (ev.getMessageType() != MIDIConstants::MIDI_NOTE_ON) { | 3432 | 
| 3423 continue; | 3433 if (currentNoteLayer) { | 
| 3424 } | 3434 | 
| 3425 insertInstantAt(ev.getTime()); | 3435 if (ev.getMessageType() == MIDIConstants::MIDI_NOTE_ON) { | 
| 3436 | |
| 3437 currentNoteLayer->addNoteOn(ev.getTime(), | |
| 3438 ev.getPitch(), | |
| 3439 ev.getVelocity()); | |
| 3440 | |
| 3441 } else if (ev.getMessageType() == MIDIConstants::MIDI_NOTE_OFF) { | |
| 3442 | |
| 3443 currentNoteLayer->addNoteOff(ev.getTime(), | |
| 3444 ev.getPitch()); | |
| 3445 | |
| 3446 } | |
| 3447 | |
| 3448 } else { | |
| 3449 if (ev.getMessageType() != MIDIConstants::MIDI_NOTE_ON) { | |
| 3450 continue; | |
| 3451 } | |
| 3452 insertInstantAt(ev.getTime()); | |
| 3453 } | |
| 3426 } | 3454 } | 
| 3427 } | 3455 } | 
| 3428 | 3456 | 
| 3429 void | 3457 void | 
| 3430 MainWindow::playStatusChanged(bool playing) | 3458 MainWindow::playStatusChanged(bool playing) | 
| 3431 { | 3459 { | 
| 3432 m_lastInsertedMIDITime = -1.0; // <0 means "never during this playback" | 3460 Pane *currentPane = 0; | 
| 3461 NoteLayer *currentNoteLayer = 0; | |
| 3462 | |
| 3463 if (m_paneStack) currentPane = m_paneStack->getCurrentPane(); | |
| 3464 if (currentPane) { | |
| 3465 currentNoteLayer = dynamic_cast<NoteLayer *>(currentPane->getSelectedLayer()); | |
| 3466 } | |
| 3467 | |
| 3468 if (currentNoteLayer) { | |
| 3469 currentNoteLayer->abandonNoteOns(); | |
| 3470 } | |
| 3433 } | 3471 } | 
| 3434 | 3472 | 
| 3435 void | 3473 void | 
| 3436 MainWindow::layerRemoved(Layer *layer) | 3474 MainWindow::layerRemoved(Layer *layer) | 
| 3437 { | 3475 { | 
