lots more work trying to create a common structure for accessing plugin and MIDNAME patch/preset/program names. still not done
git-svn-id: svn://localhost/ardour2/branches/3.0@12665 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
c816917411
commit
d97312d438
|
@ -22,7 +22,7 @@
|
|||
#include <glibmm/regex.h>
|
||||
|
||||
#include "gtkmm2ext/keyboard.h"
|
||||
#include "ardour/midi_patch_manager.h"
|
||||
#include "ardour/instrument_info.h"
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "midi_region_view.h"
|
||||
|
@ -44,8 +44,7 @@ CanvasPatchChange::CanvasPatchChange(
|
|||
double height,
|
||||
double x,
|
||||
double y,
|
||||
string& model_name,
|
||||
string& custom_device_mode,
|
||||
ARDOUR::InstrumentInfo& info,
|
||||
ARDOUR::MidiModel::PatchChangePtr patch,
|
||||
bool active_channel)
|
||||
: CanvasFlag(
|
||||
|
@ -60,12 +59,11 @@ CanvasPatchChange::CanvasPatchChange(
|
|||
ARDOUR_UI::config()->canvasvar_MidiPatchChangeInactiveChannelFill.get(),
|
||||
x,
|
||||
y)
|
||||
, _model_name(model_name)
|
||||
, _custom_device_mode(custom_device_mode)
|
||||
, _info (info)
|
||||
, _patch (patch)
|
||||
, _popup_initialized(false)
|
||||
{
|
||||
set_text(text);
|
||||
set_text (text);
|
||||
}
|
||||
|
||||
CanvasPatchChange::~CanvasPatchChange()
|
||||
|
@ -75,9 +73,7 @@ CanvasPatchChange::~CanvasPatchChange()
|
|||
void
|
||||
CanvasPatchChange::initialize_popup_menus()
|
||||
{
|
||||
boost::shared_ptr<ChannelNameSet> channel_name_set =
|
||||
MidiPatchManager::instance()
|
||||
.find_channel_name_set(_model_name, _custom_device_mode, _patch->channel());
|
||||
boost::shared_ptr<ChannelNameSet> channel_name_set = _info.get_patches (_patch->channel());
|
||||
|
||||
if (!channel_name_set) {
|
||||
return;
|
||||
|
@ -193,22 +189,28 @@ CanvasPatchChange::on_event (GdkEvent* ev)
|
|||
break;
|
||||
|
||||
case GDK_SCROLL:
|
||||
if (ev->scroll.direction == GDK_SCROLL_UP) {
|
||||
if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
|
||||
_region.previous_bank (*this);
|
||||
} else {
|
||||
_region.previous_patch (*this);
|
||||
{
|
||||
/* XXX: icky dcast */
|
||||
Editor* e = dynamic_cast<Editor*> (&_region.get_time_axis_view().editor());
|
||||
if (e->current_mouse_mode() == Editing::MouseObject && e->internal_editing()) {
|
||||
if (ev->scroll.direction == GDK_SCROLL_UP) {
|
||||
if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
|
||||
_region.previous_bank (*this);
|
||||
} else {
|
||||
_region.previous_patch (*this);
|
||||
}
|
||||
return true;
|
||||
} else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
|
||||
if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
|
||||
_region.next_bank (*this);
|
||||
} else {
|
||||
_region.next_patch (*this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
} else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
|
||||
if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
|
||||
_region.next_bank (*this);
|
||||
} else {
|
||||
_region.next_patch (*this);
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GDK_ENTER_NOTIFY:
|
||||
_region.patch_entered (this);
|
||||
|
@ -218,6 +220,9 @@ CanvasPatchChange::on_event (GdkEvent* ev)
|
|||
_region.patch_left (this);
|
||||
break;
|
||||
|
||||
case GDK_KEY_RELEASE:
|
||||
return true;
|
||||
|
||||
case GDK_BUTTON_RELEASE:
|
||||
return true;
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@ namespace MIDI {
|
|||
}
|
||||
}
|
||||
|
||||
namespace ARDOUR {
|
||||
class InstrumentInfo;
|
||||
}
|
||||
|
||||
namespace Gnome {
|
||||
namespace Canvas {
|
||||
|
||||
|
@ -43,8 +47,7 @@ public:
|
|||
double height,
|
||||
double x,
|
||||
double y,
|
||||
string& model_name,
|
||||
string& custom_device_mode,
|
||||
ARDOUR::InstrumentInfo& info,
|
||||
ARDOUR::MidiModel::PatchChangePtr patch,
|
||||
bool
|
||||
);
|
||||
|
@ -53,8 +56,6 @@ public:
|
|||
|
||||
virtual bool on_event(GdkEvent* ev);
|
||||
|
||||
string model_name () const { return _model_name; }
|
||||
string custom_device_mode () const { return _custom_device_mode; }
|
||||
ARDOUR::MidiModel::PatchChangePtr patch () const { return _patch; }
|
||||
|
||||
void initialize_popup_menus();
|
||||
|
@ -62,8 +63,7 @@ public:
|
|||
void on_patch_menu_selected(const MIDI::Name::PatchPrimaryKey& key);
|
||||
|
||||
private:
|
||||
string _model_name;
|
||||
string _custom_device_mode;
|
||||
ARDOUR::InstrumentInfo& _info;
|
||||
ARDOUR::MidiModel::PatchChangePtr _patch;
|
||||
Gtk::Menu _popup;
|
||||
bool _popup_initialized;
|
||||
|
|
|
@ -4730,6 +4730,8 @@ Editor::insert_patch_change (bool from_context)
|
|||
|
||||
const framepos_t p = get_preferred_edit_position (false, from_context);
|
||||
|
||||
cerr << "Got " << rs.size() << " regions to add patch change to\n";
|
||||
|
||||
/* XXX: bit of a hack; use the MIDNAM from the first selected region;
|
||||
there may be more than one, but the PatchChangeDialog can only offer
|
||||
one set of patch menus.
|
||||
|
@ -4737,7 +4739,7 @@ Editor::insert_patch_change (bool from_context)
|
|||
MidiRegionView* first = dynamic_cast<MidiRegionView*> (rs.front ());
|
||||
|
||||
Evoral::PatchChange<Evoral::MusicalTime> empty (0, 0, 0, 0);
|
||||
PatchChangeDialog d (0, _session, empty, first->model_name(), first->custom_device_mode(), Gtk::Stock::ADD);
|
||||
PatchChangeDialog d (0, _session, empty, first->instrument_info(), Gtk::Stock::ADD);
|
||||
|
||||
if (d.run() == RESPONSE_CANCEL) {
|
||||
return;
|
||||
|
@ -4747,6 +4749,7 @@ Editor::insert_patch_change (bool from_context)
|
|||
MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*i);
|
||||
if (mrv) {
|
||||
if (p >= mrv->region()->first_frame() && p <= mrv->region()->last_frame()) {
|
||||
cerr << "Adding patch change @ " << p << " to " << mrv->region()->name() << endl;
|
||||
mrv->add_patch_change (p - mrv->region()->position(), d.patch ());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -283,11 +283,8 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
|
|||
midi_view()->signal_channel_mode_changed().connect(
|
||||
sigc::mem_fun(this, &MidiRegionView::midi_channel_mode_changed));
|
||||
|
||||
RouteUI* route_ui = dynamic_cast<RouteUI*> (&trackview);
|
||||
if (route_ui) {
|
||||
route_ui->route()->instrument_info().Changed.connect (_instrument_changed_connection, invalidator (*this),
|
||||
boost::bind (&MidiRegionView::instrument_settings_changed, this), gui_context());
|
||||
}
|
||||
instrument_info().Changed.connect (_instrument_changed_connection, invalidator (*this),
|
||||
boost::bind (&MidiRegionView::instrument_settings_changed, this), gui_context());
|
||||
|
||||
trackview.editor().SnapChanged.connect(snap_changed_connection, invalidator(*this),
|
||||
boost::bind (&MidiRegionView::snap_changed, this),
|
||||
|
@ -299,6 +296,13 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
|
|||
SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), boost::bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
|
||||
}
|
||||
|
||||
InstrumentInfo&
|
||||
MidiRegionView::instrument_info () const
|
||||
{
|
||||
RouteUI* route_ui = dynamic_cast<RouteUI*> (&trackview);
|
||||
return route_ui->route()->instrument_info();
|
||||
}
|
||||
|
||||
const boost::shared_ptr<ARDOUR::MidiRegion>
|
||||
MidiRegionView::midi_region() const
|
||||
{
|
||||
|
@ -1204,10 +1208,8 @@ MidiRegionView::display_patch_changes_on_channel (uint8_t channel, bool active_c
|
|||
continue;
|
||||
}
|
||||
|
||||
// MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
|
||||
//string patch_name = mtv->get_patch_name ((*i)->bank(), (*i)->program(), channel);
|
||||
|
||||
// add_canvas_patch_change (*i, patch_name, active_channel);
|
||||
string patch_name = instrument_info().get_patch_name ((*i)->bank(), (*i)->program(), channel);
|
||||
add_canvas_patch_change (*i, patch_name, active_channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1792,8 +1794,7 @@ MidiRegionView::add_canvas_patch_change (MidiModel::PatchChangePtr patch, const
|
|||
displaytext,
|
||||
height,
|
||||
x, 1.0,
|
||||
_model_name,
|
||||
_custom_device_mode,
|
||||
instrument_info(),
|
||||
patch,
|
||||
active_channel)
|
||||
);
|
||||
|
@ -3709,7 +3710,7 @@ MidiRegionView::trim_front_ending ()
|
|||
void
|
||||
MidiRegionView::edit_patch_change (ArdourCanvas::CanvasPatchChange* pc)
|
||||
{
|
||||
PatchChangeDialog d (&_source_relative_time_converter, trackview.session(), *pc->patch (), _model_name, _custom_device_mode, Gtk::Stock::APPLY);
|
||||
PatchChangeDialog d (&_source_relative_time_converter, trackview.session(), *pc->patch (), instrument_info(), Gtk::Stock::APPLY);
|
||||
if (d.run () != Gtk::RESPONSE_ACCEPT) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -300,13 +300,7 @@ public:
|
|||
|
||||
void clear_selection (bool signal = true) { clear_selection_except (0, signal); }
|
||||
|
||||
std::string model_name () const {
|
||||
return _model_name;
|
||||
}
|
||||
|
||||
std::string custom_device_mode () const {
|
||||
return _custom_device_mode;
|
||||
}
|
||||
ARDOUR::InstrumentInfo& instrument_info() const;
|
||||
|
||||
protected:
|
||||
/** Allows derived types to specify their visibility requirements
|
||||
|
@ -381,12 +375,6 @@ private:
|
|||
uint8_t _current_range_min;
|
||||
uint8_t _current_range_max;
|
||||
|
||||
/// MIDNAM information of the current track: Model name of MIDNAM file
|
||||
std::string _model_name;
|
||||
|
||||
/// MIDNAM information of the current track: CustomDeviceMode
|
||||
std::string _custom_device_mode;
|
||||
|
||||
typedef std::list<ArdourCanvas::CanvasNoteEvent*> Events;
|
||||
typedef std::vector< boost::shared_ptr<ArdourCanvas::CanvasPatchChange> > PatchChanges;
|
||||
typedef std::vector< boost::shared_ptr<ArdourCanvas::CanvasSysEx> > SysExes;
|
||||
|
|
|
@ -208,8 +208,12 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
|||
_model_selector.set_active_text (gui_property (X_("midnam-model-name")));
|
||||
_custom_device_mode_selector.set_active_text (gui_property (X_("midnam-custom-device-mode")));
|
||||
|
||||
ARDOUR_UI::instance()->set_tip (_model_selector, _("external MIDI Device selector"));
|
||||
ARDOUR_UI::instance()->set_tip (_custom_device_mode_selector, _("external MIDI Device Mode"));
|
||||
|
||||
midi_controls_hbox->pack_start(_channel_selector, true, false);
|
||||
if (!patch_manager.all_models().empty()) {
|
||||
_midi_controls_box.set_border_width (5);
|
||||
_midi_controls_box.pack_start(_model_selector, true, false);
|
||||
_midi_controls_box.pack_start(_custom_device_mode_selector, true, false);
|
||||
}
|
||||
|
|
|
@ -20,11 +20,17 @@
|
|||
|
||||
#include <gtkmm/stock.h>
|
||||
#include <gtkmm/table.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "gtkmm2ext/utils.h"
|
||||
|
||||
#include "ardour/midi_patch_manager.h"
|
||||
#include "ardour/beats_frames_converter.h"
|
||||
#include "ardour/instrument_info.h"
|
||||
|
||||
#include "patch_change_dialog.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -36,14 +42,12 @@ PatchChangeDialog::PatchChangeDialog (
|
|||
const ARDOUR::BeatsFramesConverter* tc,
|
||||
ARDOUR::Session* session,
|
||||
Evoral::PatchChange<Evoral::MusicalTime> const & patch,
|
||||
string const & model_name,
|
||||
string const & custom_device_node,
|
||||
ARDOUR::InstrumentInfo& info,
|
||||
const Gtk::BuiltinStockID& ok
|
||||
)
|
||||
: ArdourDialog (_("Patch Change"), true)
|
||||
, _time_converter (tc)
|
||||
, _model_name (model_name)
|
||||
, _custom_device_mode (custom_device_node)
|
||||
, _info (info)
|
||||
, _time (X_("patchchangetime"), true, "", true, false)
|
||||
, _channel (*manage (new Adjustment (1, 1, 16, 1, 4)))
|
||||
, _program (*manage (new Adjustment (1, 1, 128, 1, 16)))
|
||||
|
@ -139,12 +143,9 @@ PatchChangeDialog::patch () const
|
|||
void
|
||||
PatchChangeDialog::fill_bank_combo ()
|
||||
{
|
||||
MIDI::Name::ChannelNameSet::PatchBanks const * banks = get_banks ();
|
||||
if (banks == 0) {
|
||||
return;
|
||||
}
|
||||
boost::shared_ptr<MIDI::Name::ChannelNameSet> cns = _info.get_patches (_channel.get_value_as_int() - 1);
|
||||
|
||||
for (MIDI::Name::ChannelNameSet::PatchBanks::const_iterator i = banks->begin(); i != banks->end(); ++i) {
|
||||
for (MIDI::Name::ChannelNameSet::PatchBanks::const_iterator i = cns->patch_banks().begin(); i != cns->patch_banks().end(); ++i) {
|
||||
string n = (*i)->name ();
|
||||
boost::replace_all (n, "_", " ");
|
||||
_bank_combo.append_text (n);
|
||||
|
@ -157,12 +158,10 @@ PatchChangeDialog::set_active_bank_combo ()
|
|||
{
|
||||
_current_patch_bank.reset ();
|
||||
|
||||
MIDI::Name::ChannelNameSet::PatchBanks const * banks = get_banks ();
|
||||
if (banks == 0) {
|
||||
return;
|
||||
}
|
||||
boost::shared_ptr<MIDI::Name::ChannelNameSet> cns = _info.get_patches (_channel.get_value_as_int() - 1);
|
||||
|
||||
for (MIDI::Name::ChannelNameSet::PatchBanks::const_iterator i = cns->patch_banks().begin(); i != cns->patch_banks().end(); ++i) {
|
||||
|
||||
for (MIDI::Name::ChannelNameSet::PatchBanks::const_iterator i = banks->begin(); i != banks->end(); ++i) {
|
||||
string n = (*i)->name ();
|
||||
boost::replace_all (n, "_", " ");
|
||||
|
||||
|
@ -193,12 +192,9 @@ PatchChangeDialog::bank_combo_changed ()
|
|||
|
||||
_current_patch_bank.reset ();
|
||||
|
||||
MIDI::Name::ChannelNameSet::PatchBanks const * banks = get_banks ();
|
||||
if (banks == 0) {
|
||||
return;
|
||||
}
|
||||
boost::shared_ptr<MIDI::Name::ChannelNameSet> cns = _info.get_patches (_channel.get_value_as_int() - 1);
|
||||
|
||||
for (MIDI::Name::ChannelNameSet::PatchBanks::const_iterator i = banks->begin(); i != banks->end(); ++i) {
|
||||
for (MIDI::Name::ChannelNameSet::PatchBanks::const_iterator i = cns->patch_banks().begin(); i != cns->patch_banks().end(); ++i) {
|
||||
string n = (*i)->name ();
|
||||
boost::replace_all (n, "_", " ");
|
||||
if (n == _bank_combo.get_active_text()) {
|
||||
|
@ -327,17 +323,3 @@ PatchChangeDialog::bank_changed ()
|
|||
set_active_patch_combo ();
|
||||
}
|
||||
|
||||
MIDI::Name::ChannelNameSet::PatchBanks const *
|
||||
PatchChangeDialog::get_banks ()
|
||||
{
|
||||
MIDI::Name::MidiPatchManager& mpm = MIDI::Name::MidiPatchManager::instance ();
|
||||
boost::shared_ptr<MIDI::Name::ChannelNameSet> channel_name_set = mpm.find_channel_name_set (
|
||||
_model_name, _custom_device_mode, _channel.get_value_as_int() - 1
|
||||
);
|
||||
|
||||
if (!channel_name_set) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return &channel_name_set->patch_banks ();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
namespace ARDOUR {
|
||||
class BeatsFramesConverter;
|
||||
class Session;
|
||||
class InstrumentInfo;
|
||||
}
|
||||
|
||||
namespace MIDI {
|
||||
|
@ -43,8 +44,7 @@ public:
|
|||
const ARDOUR::BeatsFramesConverter *,
|
||||
ARDOUR::Session *,
|
||||
Evoral::PatchChange<Evoral::MusicalTime> const &,
|
||||
std::string const &,
|
||||
std::string const &,
|
||||
ARDOUR::InstrumentInfo&,
|
||||
const Gtk::BuiltinStockID &
|
||||
);
|
||||
|
||||
|
@ -61,11 +61,8 @@ private:
|
|||
void bank_changed ();
|
||||
void program_changed ();
|
||||
|
||||
MIDI::Name::ChannelNameSet::PatchBanks const * get_banks ();
|
||||
|
||||
const ARDOUR::BeatsFramesConverter* _time_converter;
|
||||
std::string _model_name;
|
||||
std::string _custom_device_mode;
|
||||
ARDOUR::InstrumentInfo& _info;
|
||||
AudioClock _time;
|
||||
Gtk::SpinButton _channel;
|
||||
Gtk::SpinButton _program;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "pbd/signals.h"
|
||||
|
||||
#include "midi++/midnam_patch.h"
|
||||
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
@ -41,13 +43,22 @@ class InstrumentInfo {
|
|||
std::string get_patch_name (uint16_t bank, uint8_t program, uint8_t channel) const;
|
||||
std::string get_instrument_name () const;
|
||||
|
||||
boost::shared_ptr<MIDI::Name::ChannelNameSet> get_patches (uint8_t channel);
|
||||
|
||||
PBD::Signal0<void> Changed;
|
||||
|
||||
static const MIDI::Name::PatchBank::PatchNameList& general_midi_patches();
|
||||
|
||||
private:
|
||||
std::string external_instrument_model;
|
||||
std::string external_instrument_mode;
|
||||
|
||||
boost::weak_ptr<ARDOUR::Processor> internal_instrument;
|
||||
|
||||
boost::shared_ptr<MIDI::Name::ChannelNameSet> plugin_programs_to_channel_name_set (boost::shared_ptr<Processor> p);
|
||||
std::string get_plugin_patch_name (boost::shared_ptr<ARDOUR::Processor>, uint16_t bank, uint8_t program, uint8_t channel) const;
|
||||
|
||||
static MIDI::Name::PatchBank::PatchNameList _gm_patches;
|
||||
};
|
||||
|
||||
} /* namespace ARDOUR */
|
||||
|
|
|
@ -166,16 +166,17 @@ class Plugin : public PBD::StatefulDestructible, public Latent
|
|||
void monitoring_changed ();
|
||||
|
||||
struct PresetRecord {
|
||||
PresetRecord () : user (true) {}
|
||||
PresetRecord (const std::string& u, const std::string& l, bool s = true) : uri (u), label (l), user (s) {}
|
||||
|
||||
bool operator!= (PresetRecord const & a) const {
|
||||
return uri != a.uri || label != a.label;
|
||||
}
|
||||
|
||||
std::string uri;
|
||||
std::string label;
|
||||
bool user;
|
||||
PresetRecord () : number (-1), user (true) {}
|
||||
PresetRecord (const std::string& u, const std::string& l, int n = -1, bool s = true) : uri (u), label (l), number (n), user (s) {}
|
||||
|
||||
bool operator!= (PresetRecord const & a) const {
|
||||
return number != a.number || uri != a.uri || label != a.label;
|
||||
}
|
||||
|
||||
std::string uri;
|
||||
std::string label;
|
||||
int number; // if <0, invalid
|
||||
bool user;
|
||||
};
|
||||
|
||||
PresetRecord save_preset (std::string);
|
||||
|
@ -188,6 +189,15 @@ class Plugin : public PBD::StatefulDestructible, public Latent
|
|||
|
||||
std::vector<PresetRecord> get_presets ();
|
||||
|
||||
/* This is hard to return a correct value for because most plugin APIs
|
||||
do not specify plugin behaviour. However, if you want to force
|
||||
the display of plugin built-in preset names rather than MIDI program
|
||||
numbers, return true. If you want a generic description, return
|
||||
false.
|
||||
*/
|
||||
virtual bool presets_are_MIDI_programs() const { return true; }
|
||||
virtual bool current_preset_uses_general_midi() const { return true; }
|
||||
|
||||
/** @return Last preset to be requested; the settings may have
|
||||
* been changed since; find out with parameter_changed_since_last_preset.
|
||||
*/
|
||||
|
|
|
@ -603,6 +603,8 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
|||
boost::weak_ptr<Processor> _processor_after_last_custom_meter;
|
||||
/** true if the last custom meter position was at the end of the processor list */
|
||||
bool _last_custom_meter_was_at_end;
|
||||
|
||||
void reset_instrument_info ();
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
@ -2107,7 +2107,7 @@ AUPlugin::find_presets ()
|
|||
for (FactoryPresetMap::iterator i = factory_preset_map.begin(); i != factory_preset_map.end(); ++i) {
|
||||
/* XXX: dubious */
|
||||
string const uri = string_compose ("%1", _presets.size ());
|
||||
_presets.insert (make_pair (uri, Plugin::PresetRecord (uri, i->first)));
|
||||
_presets.insert (make_pair (uri, Plugin::PresetRecord (uri, i->first, i->second)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "pbd/compose.h"
|
||||
|
||||
#include "midi++/midnam_patch.h"
|
||||
|
@ -23,13 +25,17 @@
|
|||
#include "ardour/instrument_info.h"
|
||||
#include "ardour/midi_patch_manager.h"
|
||||
#include "ardour/processor.h"
|
||||
#include "ardour/plugin.h"
|
||||
#include "ardour/rc_configuration.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace MIDI::Name;
|
||||
using std::string;
|
||||
|
||||
MIDI::Name::PatchBank::PatchNameList InstrumentInfo::_gm_patches;
|
||||
|
||||
InstrumentInfo::InstrumentInfo ()
|
||||
: external_instrument_model (_("Unknown"))
|
||||
{
|
||||
|
@ -79,7 +85,7 @@ InstrumentInfo::get_patch_name (uint16_t bank, uint8_t program, uint8_t channel)
|
|||
boost::shared_ptr<Processor> p = internal_instrument.lock();
|
||||
|
||||
if (p) {
|
||||
return "some plugin program";
|
||||
return get_plugin_patch_name (p, bank, program, channel);
|
||||
}
|
||||
|
||||
MIDI::Name::PatchPrimaryKey patch_key (bank, program);
|
||||
|
@ -95,6 +101,103 @@ InstrumentInfo::get_patch_name (uint16_t bank, uint8_t program, uint8_t channel)
|
|||
|
||||
#define MIDI_BP_ZERO ((Config->get_first_midi_bank_is_zero())?0:1)
|
||||
|
||||
return string_compose ("%1 %2",program + MIDI_BP_ZERO , bank + MIDI_BP_ZERO);
|
||||
return string_compose ("prg %1 bnk %2",program + MIDI_BP_ZERO , bank + MIDI_BP_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<MIDI::Name::ChannelNameSet>
|
||||
InstrumentInfo::get_patches (uint8_t channel)
|
||||
{
|
||||
boost::shared_ptr<Processor> p = internal_instrument.lock();
|
||||
|
||||
if (p) {
|
||||
return plugin_programs_to_channel_name_set (p);
|
||||
}
|
||||
|
||||
return MidiPatchManager::instance().find_channel_name_set (external_instrument_model,
|
||||
external_instrument_mode,
|
||||
channel);
|
||||
|
||||
}
|
||||
|
||||
boost::shared_ptr<MIDI::Name::ChannelNameSet>
|
||||
InstrumentInfo::plugin_programs_to_channel_name_set (boost::shared_ptr<Processor> p)
|
||||
{
|
||||
PatchBank::PatchNameList patch_list;
|
||||
|
||||
boost::shared_ptr<PluginInsert> insert = boost::dynamic_pointer_cast<PluginInsert> (p);
|
||||
|
||||
if (!insert) {
|
||||
return boost::shared_ptr<ChannelNameSet>();
|
||||
}
|
||||
|
||||
boost::shared_ptr<Plugin> pp = insert->plugin();
|
||||
|
||||
if (pp->current_preset_uses_general_midi()) {
|
||||
|
||||
patch_list = InstrumentInfo::general_midi_patches ();
|
||||
|
||||
} else if (pp->presets_are_MIDI_programs()) {
|
||||
|
||||
std::vector<Plugin::PresetRecord> presets = pp->get_presets ();
|
||||
std::vector<Plugin::PresetRecord>::iterator i;
|
||||
int n;
|
||||
|
||||
/* XXX note the assumption that plugin presets start their numbering at
|
||||
* zero
|
||||
*/
|
||||
|
||||
for (n = 0, i = presets.begin(); i != presets.end(); ++i, ++n) {
|
||||
if ((*i).number >= 0) {
|
||||
patch_list.push_back (boost::shared_ptr<Patch> (new Patch (string_compose ("%1", n), (*i).label)));
|
||||
} else {
|
||||
patch_list.push_back (boost::shared_ptr<Patch> (new Patch (string_compose ("%1", n),
|
||||
string_compose ("program %1", n))));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int n = 0; n < 127; ++n) {
|
||||
patch_list.push_back (boost::shared_ptr<Patch> (new Patch (string_compose ("%1", n),
|
||||
string_compose ("program %1", n))));
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<PatchBank> pb (new PatchBank (p->name()));
|
||||
pb->set_patch_name_list (patch_list);
|
||||
|
||||
ChannelNameSet::PatchBanks patch_banks;
|
||||
patch_banks.push_back (pb);
|
||||
|
||||
boost::shared_ptr<MIDI::Name::ChannelNameSet> cns (new ChannelNameSet);
|
||||
cns->set_patch_banks (patch_banks);
|
||||
|
||||
return cns;
|
||||
}
|
||||
|
||||
const MIDI::Name::PatchBank::PatchNameList&
|
||||
InstrumentInfo::general_midi_patches()
|
||||
{
|
||||
if (_gm_patches.empty()) {
|
||||
for (int n = 0; n < 128; n++) {
|
||||
_gm_patches.push_back (boost::shared_ptr<Patch> (new Patch (string_compose ("%1", n), general_midi_program_names[n])));
|
||||
}
|
||||
}
|
||||
|
||||
return _gm_patches;
|
||||
}
|
||||
|
||||
string
|
||||
InstrumentInfo::get_plugin_patch_name (boost::shared_ptr<Processor> p, uint16_t bank, uint8_t program, uint8_t channel) const
|
||||
{
|
||||
boost::shared_ptr<PluginInsert> insert = boost::dynamic_pointer_cast<PluginInsert> (p);
|
||||
|
||||
if (insert) {
|
||||
boost::shared_ptr<Plugin> pp = insert->plugin();
|
||||
|
||||
if (pp->current_preset_uses_general_midi()) {
|
||||
return MIDI::Name::general_midi_program_names[std::min((uint8_t) 127,program)];
|
||||
}
|
||||
}
|
||||
|
||||
return string_compose (_("preset %1 (bank %2)"), (int) program, (int) bank);
|
||||
}
|
||||
|
|
|
@ -1014,11 +1014,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
|
|||
_output->set_user_latency (0);
|
||||
}
|
||||
|
||||
boost::shared_ptr<Processor> instr = the_instrument();
|
||||
if (instr) {
|
||||
_instrument_info.set_internal_instrument (instr);
|
||||
}
|
||||
|
||||
reset_instrument_info ();
|
||||
processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
|
||||
set_processor_positions ();
|
||||
|
||||
|
@ -1167,11 +1163,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
|
|||
_output->set_user_latency (0);
|
||||
}
|
||||
|
||||
boost::shared_ptr<Processor> instr = the_instrument();
|
||||
if (instr) {
|
||||
_instrument_info.set_internal_instrument (instr);
|
||||
}
|
||||
|
||||
reset_instrument_info ();
|
||||
processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
|
||||
set_processor_positions ();
|
||||
|
||||
|
@ -1378,7 +1370,7 @@ Route::clear_processors (Placement p)
|
|||
processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
|
||||
set_processor_positions ();
|
||||
|
||||
_instrument_info.set_internal_instrument (boost::shared_ptr<Processor>());
|
||||
reset_instrument_info ();
|
||||
|
||||
if (!already_deleting) {
|
||||
_session.clear_deletion_in_progress();
|
||||
|
@ -1478,11 +1470,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
|
|||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<Processor> instr = the_instrument();
|
||||
if (instr) {
|
||||
_instrument_info.set_internal_instrument (instr);
|
||||
}
|
||||
|
||||
reset_instrument_info ();
|
||||
processor->drop_references ();
|
||||
processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
|
||||
set_processor_positions ();
|
||||
|
@ -1579,12 +1567,20 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
|
|||
(*i)->drop_references ();
|
||||
}
|
||||
|
||||
reset_instrument_info ();
|
||||
processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
|
||||
set_processor_positions ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Route::reset_instrument_info ()
|
||||
{
|
||||
boost::shared_ptr<Processor> instr = the_instrument();
|
||||
_instrument_info.set_internal_instrument (instr);
|
||||
}
|
||||
|
||||
/** Caller must hold process lock */
|
||||
int
|
||||
Route::configure_processors (ProcessorStreams* err)
|
||||
|
@ -2543,6 +2539,7 @@ Route::set_processor_state (const XMLNode& node)
|
|||
}
|
||||
}
|
||||
|
||||
reset_instrument_info ();
|
||||
processors_changed (RouteProcessorChange ());
|
||||
set_processor_positions ();
|
||||
}
|
||||
|
@ -4067,9 +4064,11 @@ Route::the_instrument () const
|
|||
{
|
||||
Glib::RWLock::WriterLock lm (_processor_lock);
|
||||
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
|
||||
if ((*i)->input_streams().n_midi() > 0 &&
|
||||
(*i)->output_streams().n_audio() > 0) {
|
||||
return (*i);
|
||||
if (boost::dynamic_pointer_cast<PluginInsert>(*i)) {
|
||||
if ((*i)->input_streams().n_midi() > 0 &&
|
||||
(*i)->output_streams().n_audio() > 0) {
|
||||
return (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return boost::shared_ptr<Processor>();
|
||||
|
|
|
@ -598,7 +598,7 @@ VSTPlugin::find_presets ()
|
|||
|
||||
int const vst_version = _plugin->dispatcher (_plugin, effGetVstVersion, 0, 0, NULL, 0);
|
||||
for (int i = 0; i < _plugin->numPrograms; ++i) {
|
||||
PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id (), i), "", false);
|
||||
PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id (), i), "", -1, false);
|
||||
|
||||
if (vst_version >= 2) {
|
||||
char buf[256];
|
||||
|
@ -628,7 +628,7 @@ VSTPlugin::find_presets ()
|
|||
assert (uri);
|
||||
assert (label);
|
||||
|
||||
PresetRecord r (uri->value(), label->value(), true);
|
||||
PresetRecord r (uri->value(), label->value(), -1, true);
|
||||
_presets.insert (make_pair (r.uri, r));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,6 +200,8 @@ public:
|
|||
XMLNode& get_state (void);
|
||||
int set_state (const XMLTree&, const XMLNode&);
|
||||
|
||||
void set_patch_banks (const PatchBanks&);
|
||||
|
||||
private:
|
||||
std::string _name;
|
||||
AvailableForChannels _available_for_channels;
|
||||
|
@ -352,6 +354,8 @@ private:
|
|||
MasterDeviceNames::Models _all_models;
|
||||
};
|
||||
|
||||
extern const char* general_midi_program_names[128]; /* 0 .. 127 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -262,6 +262,28 @@ PatchBank::set_patch_name_list (const PatchNameList& pnl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ChannelNameSet::set_patch_banks (const ChannelNameSet::PatchBanks& pb)
|
||||
{
|
||||
_patch_banks = pb;
|
||||
|
||||
_patch_map.clear ();
|
||||
_patch_list.clear ();
|
||||
_patch_list_name = "";
|
||||
_available_for_channels.clear ();
|
||||
|
||||
for (PatchBanks::const_iterator pbi = _patch_banks.begin(); pbi != _patch_banks.end(); ++pbi) {
|
||||
for (PatchBank::PatchNameList::const_iterator pni = (*pbi)->patch_name_list().begin(); pni != (*pbi)->patch_name_list().end(); ++pni) {
|
||||
_patch_map[(*pni)->patch_primary_key()] = (*pni);
|
||||
_patch_list.push_back ((*pni)->patch_primary_key());
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t n = 0; n < 16; ++n) {
|
||||
_available_for_channels.insert (n);
|
||||
}
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
ChannelNameSet::get_state (void)
|
||||
{
|
||||
|
@ -526,6 +548,136 @@ MIDINameDocument::get_state(void)
|
|||
return nothing;
|
||||
}
|
||||
|
||||
const char* general_midi_program_names[128] = {
|
||||
"Acoustic Grand Piano",
|
||||
"Bright Acoustic Piano",
|
||||
"Electric Grand Piano",
|
||||
"Honky-tonk Piano",
|
||||
"Rhodes Piano",
|
||||
"Chorused Piano",
|
||||
"Harpsichord",
|
||||
"Clavinet",
|
||||
"Celesta",
|
||||
"Glockenspiel",
|
||||
"Music Box",
|
||||
"Vibraphone",
|
||||
"Marimba",
|
||||
"Xylophone",
|
||||
"Tubular Bells",
|
||||
"Dulcimer",
|
||||
"Hammond Organ",
|
||||
"Percussive Organ",
|
||||
"Rock Organ",
|
||||
"Church Organ",
|
||||
"Reed Organ",
|
||||
"Accordion",
|
||||
"Harmonica",
|
||||
"Tango Accordion",
|
||||
"Acoustic Guitar (nylon)",
|
||||
"Acoustic Guitar (steel)",
|
||||
"Electric Guitar (jazz)",
|
||||
"Electric Guitar (clean)",
|
||||
"Electric Guitar (muted)",
|
||||
"Overdriven Guitar",
|
||||
"Distortion Guitar",
|
||||
"Guitar Harmonics",
|
||||
"Acoustic Bass",
|
||||
"Electric Bass (finger)",
|
||||
"Electric Bass (pick)",
|
||||
"Fretless Bass",
|
||||
"Slap Bass 1",
|
||||
"Slap Bass 2",
|
||||
"Synth Bass 1",
|
||||
"Synth Bass 2",
|
||||
"Violin",
|
||||
"Viola",
|
||||
"Cello",
|
||||
"Contrabass",
|
||||
"Tremolo Strings",
|
||||
"Pizzicato Strings",
|
||||
"Orchestral Harp",
|
||||
"Timpani",
|
||||
"String Ensemble 1",
|
||||
"String Ensemble 2",
|
||||
"SynthStrings 1",
|
||||
"SynthStrings 2",
|
||||
"Choir Aahs",
|
||||
"Voice Oohs",
|
||||
"Synth Voice",
|
||||
"Orchestra Hit",
|
||||
"Trumpet",
|
||||
"Trombone",
|
||||
"Tuba",
|
||||
"Muted Trumpet",
|
||||
"French Horn",
|
||||
"Brass Section",
|
||||
"Synth Brass 1",
|
||||
"Synth Brass 2",
|
||||
"Soprano Sax",
|
||||
"Alto Sax",
|
||||
"Tenor Sax",
|
||||
"Baritone Sax",
|
||||
"Oboe",
|
||||
"English Horn",
|
||||
"Bassoon",
|
||||
"Clarinet",
|
||||
"Piccolo",
|
||||
"Flute",
|
||||
"Recorder",
|
||||
"Pan Flute",
|
||||
"Bottle Blow",
|
||||
"Shakuhachi",
|
||||
"Whistle",
|
||||
"Ocarina",
|
||||
"Lead 1 (square)",
|
||||
"Lead 2 (sawtooth)",
|
||||
"Lead 3 (calliope lead)",
|
||||
"Lead 4 (chiff lead)",
|
||||
"Lead 5 (charang)",
|
||||
"Lead 6 (voice)",
|
||||
"Lead 7 (fifths)",
|
||||
"Lead 8 (bass + lead)",
|
||||
"Pad 1 (new age)",
|
||||
"Pad 2 (warm)",
|
||||
"Pad 3 (polysynth)",
|
||||
"Pad 4 (choir)",
|
||||
"Pad 5 (bowed)",
|
||||
"Pad 6 (metallic)",
|
||||
"Pad 7 (halo)",
|
||||
"Pad 8 (sweep)",
|
||||
"FX 1 (rain)",
|
||||
"FX 2 (soundtrack)",
|
||||
"FX 3 (crystal)",
|
||||
"FX 4 (atmosphere)",
|
||||
"FX 5 (brightness)",
|
||||
"FX 6 (goblins)",
|
||||
"FX 7 (echoes)",
|
||||
"FX 8 (sci-fi)",
|
||||
"Sitar",
|
||||
"Banjo",
|
||||
"Shamisen",
|
||||
"Koto",
|
||||
"Kalimba",
|
||||
"Bagpipe",
|
||||
"Fiddle",
|
||||
"Shanai",
|
||||
"Tinkle Bell",
|
||||
"Agogo",
|
||||
"Steel Drums",
|
||||
"Woodblock",
|
||||
"Taiko Drum",
|
||||
"Melodic Tom",
|
||||
"Synth Drum",
|
||||
"Reverse Cymbal",
|
||||
"Guitar Fret Noise",
|
||||
"Breath Noise",
|
||||
"Seashore",
|
||||
"Bird Tweet",
|
||||
"Telephone Ring",
|
||||
"Helicopter",
|
||||
"Applause",
|
||||
"Gunshot",
|
||||
};
|
||||
|
||||
} //namespace Name
|
||||
|
||||
|
|
Loading…
Reference in New Issue