<menuitem action='lower-region-to-bottom'/>
</menu>
<menu action='RegionMenuMIDI'>
+ <menuitem action='insert-program-change'/>
<menuitem action='quantize-region'/>
<menuitem action='fork-region'/>
<menuitem action='show-region-list-editor'/>
<menuitem action='lower-region-to-bottom'/>
</menu>
<menu action='RegionMenuMIDI'>
+ <menuitem action='insert-program-change'/>
<menuitem action='quantize-region'/>
<menuitem action='fork-region'/>
<menuitem action='show-region-list-editor'/>
void reset_region_scale_amplitude ();
void adjust_region_gain (bool up);
void quantize_region ();
+ void insert_program_change ();
void fork_region ();
void do_insert_time ();
);
reg_sens (_region_actions, "quantize-region", _("Quantize"), sigc::mem_fun (*this, &Editor::quantize_region));
+ reg_sens (_region_actions, "insert-program-change", _("Insert Program Change..."), sigc::mem_fun (*this, &Editor::insert_program_change));
reg_sens (_region_actions, "fork-region", _("Fork"), sigc::mem_fun (*this, &Editor::fork_region));
reg_sens (_region_actions, "strip-region-silence", _("Strip Silence..."), sigc::mem_fun (*this, &Editor::strip_region_silence));
reg_sens (_region_actions, "set-selection-from-region", _("Set Range Selection"), sigc::mem_fun (*this, &Editor::set_selection_from_region));
case EndTrim:
_pointer_frame_offset = raw_grab_frame() - i->initial_end;
break;
+ case ContentsTrim:
+ break;
}
}
#include "normalize_dialog.h"
#include "editor_cursors.h"
#include "mouse_cursors.h"
+#include "program_change_dialog.h"
#include "i18n.h"
}
}
+void
+Editor::insert_program_change ()
+{
+ RegionSelection rs = get_regions_from_selection_and_entered ();
+ if (rs.empty ()) {
+ return;
+ }
+
+ ProgramChangeDialog d;
+ if (d.run() == RESPONSE_CANCEL) {
+ return;
+ }
+
+ framepos_t const p = get_preferred_edit_position (false);
+
+ for (RegionSelection::iterator i = rs.begin (); i != rs.end(); ++i) {
+ MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*i);
+ if (mrv) {
+ if (p >= mrv->region()->first_frame() && p <= mrv->region()->last_frame()) {
+ mrv->add_program_change (p - mrv->region()->position(), d.channel (), d.program ());
+ }
+ }
+ }
+}
+
void
Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress)
{
PCEvent program_change(event_time, uint8_t(program_number), channel);
if (patch != 0) {
- add_pgm_change(program_change, patch->name());
+ add_canvas_program_change (program_change, patch->name());
} else {
char buf[4];
// program_number is zero-based: convert to one-based
snprintf(buf, 4, "%d", int(program_number+1));
- add_pgm_change(program_change, buf);
+ add_canvas_program_change (program_change, buf);
}
}
}
}
void
-MidiRegionView::add_pgm_change(PCEvent& program, const string& displaytext)
+MidiRegionView::add_canvas_program_change (PCEvent& program, const string& displaytext)
{
assert(program.time >= 0);
display_program_changes (); // XXX would be nice to limit to just old_program.channel
}
+/** @param t Time in frames relative to region position */
void
-MidiRegionView::move_program_change (PCEvent pc, double t)
+MidiRegionView::add_program_change (framecnt_t t, uint8_t channel, uint8_t value)
+{
+ boost::shared_ptr<Evoral::Control> control = midi_region()->model()->control (
+ Evoral::Parameter (MidiPgmChangeAutomation, channel, 0), true
+ );
+
+ assert (control);
+
+ Evoral::MusicalTime const b = frames_to_beats (t + midi_region()->start());
+
+ control->list()->add (b, value);
+
+ _pgm_changes.clear ();
+ display_program_changes ();
+}
+
+void
+MidiRegionView::move_program_change (PCEvent pc, Evoral::MusicalTime t)
{
boost::shared_ptr<Evoral::Control> control = _model->control (Evoral::Parameter (MidiPgmChangeAutomation, pc.channel, 0));
assert (control);
* @param program the MidiRegionView::PCEvent to add
* @param the text to display in the flag
*/
- void add_pgm_change(PCEvent& program, const std::string& displaytext);
+ void add_canvas_program_change (PCEvent& program, const std::string& displaytext);
/** Look up the given time and channel in the 'automation' and set keys accordingly.
* @param time the time of the program change event
*/
void alter_program_change(PCEvent& old_program, const MIDI::Name::PatchPrimaryKey& new_patch);
- void move_program_change (PCEvent, double);
+ void add_program_change (framecnt_t, uint8_t, uint8_t);
+ void move_program_change (PCEvent, Evoral::MusicalTime);
void delete_program_change (ArdourCanvas::CanvasProgramChange *);
/** Alter a given program to the new given one.
--- /dev/null
+/*
+ Copyright (C) 2010 Paul Davis
+ Author: Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <gtkmm/stock.h>
+#include <gtkmm/table.h>
+#include "program_change_dialog.h"
+
+using namespace Gtk;
+
+ProgramChangeDialog::ProgramChangeDialog ()
+ : ArdourDialog (_("Add Program Change"), true)
+ , _channel (*manage (new Adjustment (1, 1, 16, 1, 2)))
+ , _program (*manage (new Adjustment (1, 1, 128, 1, 16)))
+{
+ Table* t = manage (new Table (2, 2));
+ t->set_spacings (6);
+
+ Label* l = manage (new Label (_("Channel")));
+ l->set_alignment (0, 0.5);
+ t->attach (*l, 0, 1, 0, 1);
+
+ t->attach (_channel, 1, 2, 0, 1);
+
+ l = manage (new Label (_("Program")));
+ l->set_alignment (0, 0.5);
+ t->attach (*l, 0, 1, 1, 2);
+ t->attach (_program, 1, 2, 1, 2);
+
+ get_vbox()->add (*t);
+
+ add_button (Stock::CANCEL, RESPONSE_CANCEL);
+ add_button (Stock::ADD, RESPONSE_ACCEPT);
+ set_default_response (RESPONSE_ACCEPT);
+
+ show_all ();
+}
+
+/** @return Channel, counted from 0 */
+uint8_t
+ProgramChangeDialog::channel () const
+{
+ return _channel.get_value_as_int () - 1;
+}
+
+/** @return Program change number, counted from 0 */
+uint8_t
+ProgramChangeDialog::program () const
+{
+ return _program.get_value_as_int () - 1;
+}
--- /dev/null
+/*
+ Copyright (C) 2010 Paul Davis
+ Author: Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <gtkmm/spinbutton.h>
+#include "ardour_dialog.h"
+
+class ProgramChangeDialog : public ArdourDialog
+{
+public:
+ ProgramChangeDialog ();
+
+ uint8_t channel () const;
+ uint8_t program () const;
+
+private:
+ Gtk::SpinButton _channel;
+ Gtk::SpinButton _program;
+};
'port_matrix_labels.cc',
'port_matrix_row_labels.cc',
'processor_box.cc',
+ 'program_change_dialog.cc',
'progress_reporter.cc',
'prompter.cc',
'public_editor.cc',