send sustain=off and all-notes-off when a MIDI track is muted (may fix #4295)
git-svn-id: svn://localhost/ardour2/branches/3.0@11005 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
60872a8504
commit
96585e532c
@ -117,6 +117,8 @@ protected:
|
||||
bool should_monitor () const;
|
||||
bool send_silence () const;
|
||||
|
||||
void act_on_mute ();
|
||||
|
||||
private:
|
||||
|
||||
virtual boost::shared_ptr<Diskstream> diskstream_factory (XMLNode const &);
|
||||
|
@ -140,7 +140,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
||||
|
||||
bool muted () const;
|
||||
void set_mute (bool yn, void* src);
|
||||
|
||||
|
||||
/* controls use set_solo() to modify this route's solo state
|
||||
*/
|
||||
|
||||
@ -468,6 +468,8 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
||||
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;
|
||||
|
@ -128,20 +128,16 @@ MidiPort::cycle_split ()
|
||||
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;
|
||||
}
|
||||
@ -164,7 +160,7 @@ MidiPort::flush_buffers (pframes_t nframes, framepos_t /*time*/)
|
||||
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) {
|
||||
|
@ -85,6 +85,14 @@ MidiStateTracker::track (const MidiBuffer::iterator &from, const MidiBuffer::ite
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -715,3 +715,33 @@ MidiTrack::get_gui_feed_buffer () const
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -805,6 +805,11 @@ Route::set_mute (bool yn, void *src)
|
||||
|
||||
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 */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user