diff options
author | Robin Gareus <robin@gareus.org> | 2020-04-01 06:53:26 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2020-04-01 16:31:58 +0200 |
commit | 3b77472ac0634f77a938c34c60e2b66804eee94c (patch) | |
tree | 350dc179be1d089d846f5608c43c490b51cd7407 /libs | |
parent | 26c6d3c4c9d8d02aee3c58004b7b616b66630d22 (diff) |
Overhaul InstrumentInfo
* Remove unused direct calls into plugin
* Assume empty model to mean plugin-provided MIDNAM (!)
The route owned Instrument-Info is the central access point used
by the GUI for MIDI name lookups.
At this point in time, custom settings are saved/restored by the
GUI (MidiTimeAxisView). InstrumentInfo provides a volatile store
for MIDNAM mode and model.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/instrument_info.h | 59 | ||||
-rw-r--r-- | libs/ardour/ardour/plugin.h | 20 | ||||
-rw-r--r-- | libs/ardour/instrument_info.cc | 284 | ||||
-rw-r--r-- | libs/ardour/route.cc | 4 | ||||
-rw-r--r-- | libs/midi++2/midi++/midnam_patch.h | 2 | ||||
-rw-r--r-- | libs/midi++2/midnam_patch.cc | 131 |
6 files changed, 159 insertions, 341 deletions
diff --git a/libs/ardour/ardour/instrument_info.h b/libs/ardour/ardour/instrument_info.h index 59ff34fc3a..6799c8a0fa 100644 --- a/libs/ardour/ardour/instrument_info.h +++ b/libs/ardour/ardour/instrument_info.h @@ -19,8 +19,8 @@ #ifndef __ardour_instrument_info_h__ #define __ardour_instrument_info_h__ -#include <string> #include <stdint.h> +#include <string> #include <boost/weak_ptr.hpp> @@ -28,13 +28,16 @@ #include "evoral/Parameter.h" -#include "midi++/libmidi_visibility.h" #include "ardour/libardour_visibility.h" +#include "midi++/libmidi_visibility.h" namespace MIDI { namespace Name { class ChannelNameSet; class Patch; + class ValueNameList; + class MasterDeviceNames; + class ControlNameList; typedef std::list<boost::shared_ptr<Patch> > PatchNameList; } } @@ -43,40 +46,44 @@ namespace ARDOUR { class Processor; -class LIBARDOUR_API InstrumentInfo { - public: - InstrumentInfo(); - ~InstrumentInfo (); +class LIBARDOUR_API InstrumentInfo +{ +public: + InstrumentInfo (); + ~InstrumentInfo (); - void set_external_instrument (const std::string& model, const std::string& mode); - void set_internal_instrument (boost::shared_ptr<ARDOUR::Processor>); + void set_external_instrument (const std::string& model, const std::string& mode); + void set_internal_instrument (boost::shared_ptr<ARDOUR::Processor>); - std::string get_patch_name (uint16_t bank, uint8_t program, uint8_t channel) const; - std::string get_patch_name_without (uint16_t bank, uint8_t program, uint8_t channel) const; - std::string get_controller_name (Evoral::Parameter param) const; - std::string get_instrument_name () const; + std::string get_note_name (uint16_t bank, uint8_t program, uint8_t channel, uint8_t note) const; - boost::shared_ptr<MIDI::Name::ChannelNameSet> get_patches (uint8_t channel); + std::string get_patch_name (uint16_t bank, uint8_t program, uint8_t channel) const; + std::string get_patch_name_without (uint16_t bank, uint8_t program, uint8_t channel) const; + std::string get_controller_name (Evoral::Parameter param) const; - PBD::Signal0<void> Changed; + boost::shared_ptr<MIDI::Name::MasterDeviceNames> master_device_names () const; - static const MIDI::Name::PatchNameList& general_midi_patches(); + boost::shared_ptr<MIDI::Name::ChannelNameSet> get_patches (uint8_t channel); + boost::shared_ptr<MIDI::Name::ControlNameList> control_name_list (uint8_t channel); - private: - std::string external_instrument_model; - std::string external_instrument_mode; + boost::shared_ptr<const MIDI::Name::ValueNameList> value_name_list_by_control (uint8_t channel, uint8_t number) const; - boost::weak_ptr<ARDOUR::Processor> internal_instrument; + PBD::Signal0<void> Changed; - 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; - std::string get_plugin_controller_name (boost::shared_ptr<ARDOUR::Processor>, Evoral::Parameter) const; + bool have_custom_plugin_info () const; - std::string get_patch_name (uint16_t bank, uint8_t program, uint8_t channel, bool with_extra) const; - static MIDI::Name::PatchNameList _gm_patches; -}; +private: + std::string model () const; + std::string mode () const; -} /* namespace ARDOUR */ + std::string get_patch_name (uint16_t bank, uint8_t program, uint8_t channel, bool with_extra) const; + std::string external_instrument_model; + std::string external_instrument_mode; + + boost::weak_ptr<ARDOUR::Processor> internal_instrument; +}; + +} #endif /* __ardour_instrument_info_h__ */ diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index cdcc313578..7ffbc1fdf9 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -250,26 +250,6 @@ public: std::vector<PresetRecord> get_presets (); - /** @return true if this plugin will respond to MIDI program - * change messages by changing 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 false; } - - /** @return true if this plugin is General MIDI compliant, false - * otherwise. - * - * It is important to note that it is is almost impossible for a host - * (e.g. Ardour) to determine this for just about any plugin API - * known as of June 2012 - */ - virtual bool current_preset_uses_general_midi () const { return false; } - /** @return Last preset to be requested; the settings may have * been changed since; find out with parameter_changed_since_last_preset. */ diff --git a/libs/ardour/instrument_info.cc b/libs/ardour/instrument_info.cc index 82f1306e74..f52671d3da 100644 --- a/libs/ardour/instrument_info.cc +++ b/libs/ardour/instrument_info.cc @@ -26,9 +26,9 @@ #include "ardour/instrument_info.h" #include "ardour/midi_patch_manager.h" -#include "ardour/processor.h" #include "ardour/plugin.h" #include "ardour/plugin_insert.h" +#include "ardour/processor.h" #include "ardour/rc_configuration.h" #include "pbd/i18n.h" @@ -37,8 +37,6 @@ using namespace ARDOUR; using namespace MIDI::Name; using std::string; -MIDI::Name::PatchNameList InstrumentInfo::_gm_patches; - InstrumentInfo::InstrumentInfo () : external_instrument_model (_("Unknown")) { @@ -51,63 +49,139 @@ InstrumentInfo::~InstrumentInfo () void InstrumentInfo::set_external_instrument (const string& model, const string& mode) { - if (external_instrument_model == model && external_instrument_mode == mode && internal_instrument.expired ()) { + if (external_instrument_model == model && external_instrument_mode == mode) { + //std::cerr << "InstrumentInfo::set_external_instrument '" << model << "' '" << mode << "' -- no change\n"; return; } + //std::cerr << "InstrumentInfo::set_external_instrument '" << model << "' '" << mode << "'\n"; external_instrument_model = model; - external_instrument_mode = mode; - internal_instrument.reset (); - Changed(); /* EMIT SIGNAL */ + external_instrument_mode = mode; + Changed (); /* EMIT SIGNAL */ } void InstrumentInfo::set_internal_instrument (boost::shared_ptr<Processor> p) { - bool changed = !external_instrument_mode.empty (); - external_instrument_mode = ""; + if (p == internal_instrument.lock ()) { + //std::cerr << "InstrumentInfo::set_internal_instrument -- NO CHANGE\n"; + return; + } + //std::cerr << "InstrumentInfo::set_internal_instrument -> '" << (p ? p->name () : "(NULL)") << "'\n"; + internal_instrument = p; + if (external_instrument_model.empty () || external_instrument_model == _("Unknown")) { + Changed (); /* EMIT SIGNAL */ + } +} + +bool +InstrumentInfo::have_custom_plugin_info () const +{ + boost::shared_ptr<Processor> p = internal_instrument.lock (); - boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert>(p); + boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (p); if (pi && pi->plugin ()->has_midnam ()) { - /* really back hack, following MidiTimeAxisView::model_changed() - * - * InstrumentInfo::get_plugin_patch_name() needs to be overhauled, - * it limits all PluginInsert to generic-midi or only numbers. - */ - changed |= !internal_instrument.expired (); - changed |= external_instrument_model != pi->plugin ()->midnam_model (); - - internal_instrument.reset (); - external_instrument_model = pi->plugin ()->midnam_model (); - const std::list<std::string> device_modes = MIDI::Name::MidiPatchManager::instance().custom_device_mode_names_by_model (external_instrument_model); - if (device_modes.size() > 0) { - changed |= external_instrument_mode != device_modes.front(); - external_instrument_mode = device_modes.front(); + std::string model = pi->plugin ()->midnam_model (); + const std::list<std::string> device_modes = MidiPatchManager::instance ().custom_device_mode_names_by_model (model); + if (device_modes.size () > 0) { + return true; } - } else { - changed |= internal_instrument.lock () != p || external_instrument_model != _("Unknown"); - internal_instrument = p; - external_instrument_model = _("Unknown"); } - if (changed) { - Changed(); /* EMIT SIGNAL */ + return false; +} + +std::string +InstrumentInfo::model () const +{ + if (!external_instrument_model.empty ()) { + return external_instrument_model; + } + // TODO: cache plugin model + boost::shared_ptr<Processor> p = internal_instrument.lock (); + boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (p); + if (pi && pi->plugin ()->has_midnam ()) { + return pi->plugin ()->midnam_model (); + } + return ""; +} + +std::string +InstrumentInfo::mode () const +{ + if (!external_instrument_model.empty ()) { + return external_instrument_mode; + } + // TODO: cache plugin mode + boost::shared_ptr<Processor> p = internal_instrument.lock (); + boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (p); + if (pi && pi->plugin ()->has_midnam ()) { + const std::list<std::string> device_modes = MidiPatchManager::instance ().custom_device_mode_names_by_model (model ()); + if (device_modes.size () > 0) { + return device_modes.front (); + } } + return ""; } string -InstrumentInfo::get_instrument_name () const +InstrumentInfo::get_note_name (uint16_t bank, uint8_t program, uint8_t channel, uint8_t note) const { - boost::shared_ptr<Processor> p = internal_instrument.lock(); - if (p) { - return p->name(); + boost::shared_ptr<MasterDeviceNames> const& dev_names (MidiPatchManager::instance ().master_device_by_model (model ())); + if (dev_names) { + return dev_names->note_name (mode (), channel, bank, program, note); } + return ""; +} - if (external_instrument_mode.empty()) { - return external_instrument_model; - } else { - return string_compose ("%1 (%2)", external_instrument_model, external_instrument_mode); +boost::shared_ptr<const ValueNameList> +InstrumentInfo::value_name_list_by_control (uint8_t channel, uint8_t number) const +{ + boost::shared_ptr<MasterDeviceNames> const& dev_names (MidiPatchManager::instance ().master_device_by_model (model ())); + if (dev_names) { + return dev_names->value_name_list_by_control (mode (), channel, number); + } + return boost::shared_ptr<const ValueNameList> (); +} + +boost::shared_ptr<MasterDeviceNames> +InstrumentInfo::master_device_names () const +{ +#if 1 + /* this safe if model does not exist */ + boost::shared_ptr<MIDINameDocument> midnam = MidiPatchManager::instance ().document_by_model (model ()); + if (midnam) { + return midnam->master_device_names (model ()); + } + return boost::shared_ptr<MasterDeviceNames> (); +#else + return MidiPatchManager::instance ().master_device_by_model (model ()); +#endif +} + +boost::shared_ptr<ControlNameList> +InstrumentInfo::control_name_list (uint8_t channel) +{ + boost::shared_ptr<MasterDeviceNames> const& dev_names (MidiPatchManager::instance ().master_device_by_model (model ())); + boost::shared_ptr<ChannelNameSet> const& chan_names (dev_names->channel_name_set_by_channel (mode (), channel)); + if (!chan_names) { + return boost::shared_ptr<ControlNameList> (); } + return dev_names->control_name_list (chan_names->control_list_name ()); } +#if 0 +MasterDeviceNames::ControlNameLists const& +InstrumentInfo::master_control_names () const +{ + static MasterDeviceNames::ControlNameLists empty_list; + + boost::shared_ptr<MasterDeviceNames> const& dev_names (MidiPatchManager::instance ().master_device_by_model (model ())); + if (dev_names) { + return dev_names->controls(); + } + return empty_list; +} +#endif + string InstrumentInfo::get_patch_name (uint16_t bank, uint8_t program, uint8_t channel) const { @@ -123,26 +197,19 @@ InstrumentInfo::get_patch_name_without (uint16_t bank, uint8_t program, uint8_t string InstrumentInfo::get_patch_name (uint16_t bank, uint8_t program, uint8_t channel, bool with_extra) const { - boost::shared_ptr<Processor> p = internal_instrument.lock(); - if (p) { - return get_plugin_patch_name (p, bank, program, channel); - } + PatchPrimaryKey patch_key (program, bank); - MIDI::Name::PatchPrimaryKey patch_key (program, bank); - - boost::shared_ptr<MIDI::Name::Patch> patch = - MIDI::Name::MidiPatchManager::instance().find_patch (external_instrument_model, - external_instrument_mode, channel, patch_key); + boost::shared_ptr<MIDI::Name::Patch> const& patch (MidiPatchManager::instance ().find_patch (model (), mode (), channel, patch_key)); if (patch) { - return patch->name(); + return patch->name (); } else { /* program and bank numbers are zero-based: convert to one-based: MIDI_BP_ZERO */ -#define MIDI_BP_ZERO ((Config->get_first_midi_bank_is_zero())?0:1) +#define MIDI_BP_ZERO ((Config->get_first_midi_bank_is_zero ()) ? 0 : 1) if (with_extra) { - return string_compose ("prg %1 bnk %2",program + MIDI_BP_ZERO , bank + MIDI_BP_ZERO); + return string_compose ("prg %1 bnk %2", program + MIDI_BP_ZERO, bank + MIDI_BP_ZERO); } else { return string_compose ("%1", program + MIDI_BP_ZERO); } @@ -152,136 +219,35 @@ InstrumentInfo::get_patch_name (uint16_t bank, uint8_t program, uint8_t channel, string InstrumentInfo::get_controller_name (Evoral::Parameter param) const { - boost::shared_ptr<Processor> p = internal_instrument.lock(); - if (param.type() != MidiCCAutomation) { + if (param.type () != MidiCCAutomation) { return ""; } - if (p) { - return get_plugin_controller_name (p, param); - } - boost::shared_ptr<MIDI::Name::MasterDeviceNames> dev_names( - MIDI::Name::MidiPatchManager::instance().master_device_by_model( - external_instrument_model)); + boost::shared_ptr<MasterDeviceNames> const& dev_names (MidiPatchManager::instance ().master_device_by_model (model ())); if (!dev_names) { return ""; } - boost::shared_ptr<ChannelNameSet> chan_names( - dev_names->channel_name_set_by_channel( - external_instrument_mode, param.channel())); + boost::shared_ptr<ChannelNameSet> const& chan_names (dev_names->channel_name_set_by_channel (mode (), param.channel ())); if (!chan_names) { return ""; } - boost::shared_ptr<ControlNameList> control_names( - dev_names->control_name_list(chan_names->control_list_name())); + boost::shared_ptr<ControlNameList> const& control_names (dev_names->control_name_list (chan_names->control_list_name ())); if (!control_names) { return ""; } - boost::shared_ptr<const Control> c = control_names->control(param.id()); + boost::shared_ptr<const Control> const& c = control_names->control (param.id ()); if (c) { - return string_compose(c->name() + " [%1]", int(param.channel()) + 1); + return string_compose (c->name () + " [%1]", int(param.channel ()) + 1); } return ""; } -boost::shared_ptr<MIDI::Name::ChannelNameSet> +boost::shared_ptr<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); - } - - boost::shared_ptr<MIDI::Name::ChannelNameSet> channel_name_set = - MidiPatchManager::instance().find_channel_name_set (external_instrument_model, - external_instrument_mode, - channel); - - //std::cerr << "got channel name set with name '" << channel_name_set->name() << std::endl; - - return channel_name_set; -} - -boost::shared_ptr<MIDI::Name::ChannelNameSet> -InstrumentInfo::plugin_programs_to_channel_name_set (boost::shared_ptr<Processor> p) -{ - 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; - - for (n = 0, i = presets.begin(); i != presets.end(); ++i, ++n) { - if ((*i).valid) { - patch_list.push_back (boost::shared_ptr<Patch> (new Patch ((*i).label, n))); - } else { - patch_list.push_back (boost::shared_ptr<Patch> (new Patch (string_compose ("program %1", n), n))); - } - } - } else { - for (int n = 0; n < 127; ++n) { - patch_list.push_back (boost::shared_ptr<Patch> (new Patch (string_compose ("program %1", n), n))); - } - } - - boost::shared_ptr<PatchBank> pb (new PatchBank (0, 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::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 (general_midi_program_names[n], n))); - } - } - - return _gm_patches; -} - -string -InstrumentInfo::get_plugin_controller_name (boost::shared_ptr<ARDOUR::Processor>, Evoral::Parameter param) const -{ - return ""; -} - -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); + return MidiPatchManager::instance ().find_channel_name_set (model (), mode (), channel); } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index f71f87e02f..af7e0890e7 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -1701,9 +1701,7 @@ void Route::reset_instrument_info () { boost::shared_ptr<Processor> instr = the_instrument(); - if (instr) { - _instrument_info.set_internal_instrument (instr); - } + _instrument_info.set_internal_instrument (instr); } /** Caller must hold process lock */ diff --git a/libs/midi++2/midi++/midnam_patch.h b/libs/midi++2/midi++/midnam_patch.h index d95a9e1ff0..fd172e5bc9 100644 --- a/libs/midi++2/midi++/midnam_patch.h +++ b/libs/midi++2/midi++/midnam_patch.h @@ -498,8 +498,6 @@ private: MasterDeviceNames::Models _all_models; }; -LIBMIDIPP_API extern const char* general_midi_program_names[128]; /* 0 .. 127 */ - } } diff --git a/libs/midi++2/midnam_patch.cc b/libs/midi++2/midnam_patch.cc index a6253b8619..3d8f2a233c 100644 --- a/libs/midi++2/midnam_patch.cc +++ b/libs/midi++2/midnam_patch.cc @@ -967,137 +967,6 @@ MIDINameDocument::master_device_names(const std::string& model) return boost::shared_ptr<MasterDeviceNames>(); } -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 } //namespace MIDI |