bool should_monitor () const;
bool send_silence () const;
+ void act_on_mute ();
+
private:
virtual boost::shared_ptr<Diskstream> diskstream_factory (XMLNode const &);
bool muted () const;
void set_mute (bool yn, void* src);
-
+
/* controls use set_solo() to modify this route's solo state
*/
boost::shared_ptr<MuteControllable> _mute_control;
boost::shared_ptr<MuteMaster> _mute_master;
+ virtual void act_on_mute () {}
+
std::string _comment;
bool _have_internal_generator;
bool _solo_safe;
void
MidiPort::resolve_notes (void* jack_buffer, MidiBuffer::TimeType when)
{
- uint8_t ev[3];
-
- ev[2] = 0;
for (uint8_t channel = 0; channel <= 0xF; channel++) {
- ev[0] = (MIDI_CMD_CONTROL | channel);
+
+ uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
/* we need to send all notes off AND turn the
* sustain/damper pedal off to handle synths
* that prioritize sustain over AllNotesOff
*/
- ev[1] = MIDI_CTL_SUSTAIN;
-
if (jack_midi_event_write (jack_buffer, when, ev, 3) != 0) {
cerr << "failed to deliver sustain-zero on channel " << channel << " on port " << name() << endl;
}
if (_resolve_required) {
/* resolve all notes at the start of the buffer */
resolve_notes (jack_buffer, 0);
- _resolve_required= false;
+ _resolve_required = false;
}
for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) {
continue;
}
+ /* catch AllNotesOff message and turn off all notes
+ */
+
+ if (ev.type() == MIDI_CTL_ALL_NOTES_OFF) {
+ cerr << "State tracker sees ALL_NOTES_OFF, silenceing " << sizeof (_active_notes) << endl;
+ memset (_active_notes, 0, sizeof (_active_notes));
+ }
+
track_note_onoffs (ev);
}
}
{
return midi_diskstream()->get_gui_feed_buffer ();
}
+
+void
+MidiTrack::act_on_mute ()
+{
+ /* this is called right after our mute status has changed.
+ if we are now muted, send suitable output to shutdown
+ all our notes.
+
+ XXX we should should also stop all relevant note trackers.
+ */
+
+ if (muted()) {
+ /* only send messages for channels we are using */
+
+ uint16_t mask = get_channel_mask();
+
+ for (uint8_t channel = 0; channel <= 0xF; channel++) {
+
+ if ((1<<channel) & mask) {
+
+ DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
+ uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
+ write_immediate_event (3, ev);
+ ev[1] = MIDI_CTL_ALL_NOTES_OFF;
+ write_immediate_event (3, ev);
+ }
+ }
+ }
+}
+
if (muted() != yn) {
_mute_master->set_muted_by_self (yn);
+ /* allow any derived classes to respond to the mute change
+ before anybody else knows about it.
+ */
+ act_on_mute ();
+ /* tell everyone else */
mute_changed (src); /* EMIT SIGNAL */
_mute_control->Changed (); /* EMIT SIGNAL */
}