A MIDI sequence which has been generated for use on a General MIDI Instrument should play correctly on any General MIDI synthesizer or sound module.
The wxMidi package has a database with the General Midi standard (GM) instruments list. Instruments are grouped into sections, to facilitate the user to search for a specific instrument. The database includes methods to populate a combo box, a list box and, in general, any other control derived from wxControlWithItems.
wxMidiSystem is a singleton and, therefore, the constructor is not public. Access to the only instance must be through method GetInstance.
The General MIDI system specifies which instrument or sound corresponds with each program/patch number, but General MIDI does not specify how these sounds are produced. Thus, program number 0 should select the Acoustic Grand Piano sound on any General MIDI instrument. However, the Acoustic Grand Piano sound on two General MIDI synthesizers which use different synthesis techniques may sound quite different.
The General MIDI system utilizes MIDI channels 0-8 and 10-15 for chromatic instrument sounds, while channel number 9 is utilized for "key-based" percussion sounds.
For sounds on channels 0-8 and 10-15, the note number in a NoteOn message is used to select the pitch of the sound which will be played. For example if the Vibraphone instrument (program number 11) has been selected on channel 2, then playing note number 60 on channel 2 would play the middle C note (this would be the default note to pitch assignment on most instruments), and note number 59 on channel 2 would play B below middle C. Both notes would be played using the Vibraphone sound.
The General MIDI system specifies sounds (or instruments, in wxMidi terminilogy) by using program numbers 0 through 127. The list of all these 128 sounds could be obtained by using different methods; for example, by calling PopulateWithAllInstruments.
These instrument sounds are grouped into "sets" of related sounds. For example, instruments 0-7 are piano sounds, 8-15 are chromatic percussion sounds, 16-23 are organ sounds, 24-31 are guitar sounds, etc. Each one of these "sets" is called a "section" in the wxMidiDatabaseGM. There are two specific methods to deal with sections: GetNumSections, GetSectionName and PopulateWithSections.
The list of instruments in a section is available through method PopulateWithInstruments .
As said, channel 9 reserved for "key-based" percussion sounds. For these "key-based" sounds, the note number data in a NoteOn message is used differently. Note numbers on channel 9 are used to select which drum sound will be played. For example, a NoteOn message on channel 9 with note number 60 will play a Hi Bongo drum sound. Note number 59 on channel 9 will play the Ride Cymbal 2 sound. The list of all key-based percussion sounds is accesible trhough method PopulateWithPercusionInstr
The wxMidiDatabaseGM object includes additional methods for retrieving an instrumen name given its number or the number of the section and the index inside the section. See, for example, GetInstrFromSection, GetInstrumentName, GetNumInstrumentsInSection
Members
wxMidiDatabaseGM::~wxMidiDatabaseGM
wxMidiDatabaseGM::GetInstance
wxMidiDatabaseGM::GetInstrFromSection
wxMidiDatabaseGM::GetInstrumentName
wxMidiDatabaseGM::GetNumInstrumentsInSection
wxMidiDatabaseGM::GetNumSections
wxMidiDatabaseGM::GetSectionName
wxMidiDatabaseGM::PopulateWithAllInstruments
wxMidiDatabaseGM::PopulateWithInstruments
wxMidiDatabaseGM::PopulateWithPercusionInstr
wxMidiDatabaseGM::PopulateWithSections
Returns a pointer to the only wxMidiDatabaseGM instance. Note that wxMidiDatabaseGM is a singleton and, therefore, the constructor is not public. Access to the only instance must be through this GetInstance() method.
Returns the GM number of the nth instrument in section nSect.
Parameters
nSect
n
Remarks
This method is useful when in your application, the instruments are presented organized into sections instead of in a single list with all GM instruments.
In the first case, when the user selects an instrument, it is necessary to translate the pair (section number, instrument number - relative to section - ) to the GM standard program number , as in following example:
// It is assumed that combo box m_pSectCombo is loaded // with section names and that combo box m_pInstrCombo // is loaded with the names of the instruments // in the selected section. void MyFrame::OnComboInstruments(wxCommandEvent &event) { // A new instrument has been selected. Change Midi program int nInstr = m_pInstrCombo->GetSelection(); int nSect = m_pSectCombo->GetSelection(); wxMidiDatabaseGM* pMidiGM = wxMidiDatabaseGM::GetInstance(); int nProgram = pMidiGM->GetInstrFromSection(nSect, nInstr); int nChannel = m_channel; wxMidiError nErr = m_pOutDev->ProgramChange(nChannel, nProgram); if (nErr) { ... } else { ... } }
See also:
GetNumInstrumentsInSection, GetNumSections, PopulateWithInstruments
Returns a string with the name of instrumen nInstr.
Parameters
nInstr
Remarks
To populate a control (i.e. a combo box) with the names of all instruments you can do it in a single call by using method PopulateWithAllInstruments instead of doing it inside a loop of calls to GetInstrumentName().
See also:
PopulateWithAllInstruments, PopulateWithInstruments, PopulateWithPercusionInstr
Returns the number of instruments that are included in section number nSect. In the wxMidiDatabaseGM, the number of instruments in a section is always eight. This method was included to allow for future extensions and to deal with other MIDI standards.
Parameters
nSect
See also:
GetInstrFromSection, GetNumSections, GetSectionName, PopulateWithInstruments
Returns the number of sections in which the instruments in the GM standard has been organized. In the wxMidiDatabaseGM, the number sections is always 16. This method was included to allow for future extensions and to deal with other MIDI standards.
See also:
GetNumInstrumentsInSection, GetSectionName, PopulateWithSections
Returns a string containig the name of section number nSect.
Parameters
nSect
Remarks
To populate a control (i.e. a combo box) with the names of all sections you can do it in a single call by using method PopulateWithSections instead of doing it inside a loop of calls to GetSectionName().
See also:
GetInstrFromSection, GetNumInstrumentsInSection, GetNumSections, PopulateWithSections
Load control pCtrol with the list of all instrumens in the GM standard. If nInstr is specified, the name of that instrument is left selected in the control. Otherwise, the first instrument is left selected.
Parameters
pCtrol
nInstr
Example:
pInstrCombo = new wxComboBox(panel, ID_COMBO_INSTRUMENTS, _T("This"), wxPoint(20,25), wxSize(270, wxDefaultCoord), 0, NULL, wxCB_DROPDOWN | wxCB_READONLY | wxPROCESS_ENTER); wxMidiDatabaseGM* pMidiGM = wxMidiDatabaseGM::GetInstance(); pMidiGM->PopulateWithAllInstruments(pInstrCombo);
See also:
PopulateWithInstruments, PopulateWithPercusionInstr,
Load control pCtrol with the list of all instrumens that belong to section nSection. If nInstr is specified, the name of that instrument is left selected in the control. Otherwise, the first instrument of the section is left selected.
Parameters
pCtrol
nSection
nInstr
Remarks:
This method is useful when in your application, the instruments are presented organized into sections instead of in a single long list with all GM instruments.
For example, you have to load a combo box with the list of all sections and other combo box with the list of instruments in currently selected section, as in following example:
MyFrame::MyFrame (...) { ... wxMidiDatabaseGM* pMidiGM = wxMidiDatabaseGM::GetInstance(); m_pSectCombo = new wxComboBox(this, ID_COMBO_SECTIONS, _T("This"), wxPoint(20,25), wxSize(270, wxDefaultCoord), 0, NULL, wxCB_DROPDOWN | wxCB_READONLY | wxPROCESS_ENTER); pMidiGM->PopulateWithSections(m_pSectCombo); m_pInstrCombo = new wxComboBox(this, ID_COMBO_INSTRUMENTS, _T("This"), wxPoint(20,25), wxSize(270, wxDefaultCoord), 0, NULL, wxCB_DROPDOWN | wxCB_READONLY | wxPROCESS_ENTER); pMidiGM->PopulateWithInstruments(m_pInstrCombo, 0, 0); ... } void MyFrame::OnComboSections(wxCommandEvent &event) { // A new section selected. Reload Instruments combo // with the instruments in the selected section wxMidiDatabaseGM* pMidiGM = wxMidiDatabaseGM::GetInstance(); int nSect = m_pSectCombo->GetSelection(); pMidiGM->PopulateWithInstruments(m_pInstrCombo, nSect); DoProgramChange(); } void MyFrame::OnComboInstruments(wxCommandEvent &event) { // A new instrument selected. Change Midi program DoProgramChange(); } void MyFrame::DoProgramChange() { // A new instrument has been selected. Change Midi program int nInstr = m_pInstrCombo->GetSelection(); int nSect = m_pSectCombo->GetSelection(); wxMidiDatabaseGM* pMidiGM = wxMidiDatabaseGM::GetInstance(); int nProgram = pMidiGM->GetInstrFromSection(nSect, nInstr); int nChannel = m_channel; wxMidiError nErr = m_pOutDev->ProgramChange(nChannel, nProgram); if (nErr) { ... } else { ... } }
See also:
PopulateWithAllInstruments, PopulateWithPercusionInstr, PopulateWithSections
In the MIDI standard channel 9 is reserved for "key-based" percussion sounds. For these "key-based" sounds, the note number data in a NoteOn message is used to select which drum sound will be played. For example, a NoteOn message on channel 9 with note number 60 will play a Hi Bongo drum sound. Note number 59 on channel 9 will play the Ride Cymbal 2 sound. Method PopulateWithPercusionInstr is used to load a control (combo box, list box, or other derived from wxControlWithItems) whit the list of all key-based percussion sounds in the GM standard.
Parameters
pCtrol
iSel
The list of percussion sounds in the GM standard is included here for your conveniece:
35-Acoustic Bass Drum | 59-Ride Cymbal 2 |
36-Bass Drum 1 | 60-High Bongo |
37-Side Stick | 61-Low Bongo |
38-Acoustic Snare | 62-Mute High Conga |
39-Hand clap | 63-Open High Conga |
40-Electric Snare | 64-Low Conga |
41_Low Floor Tom | 65-High Timbale |
42_Closed High-Hat | 66-Low Timbale |
43-High Floor Tom | 67-High Agogo |
44-Pedal High-Hat | 68-Low Agogo |
45-Low Tom | 69-Casaba |
46-Open High-Hat | 70-Maracas |
47-Low-Mid Tom | 71-Short Whistle |
48-High-Mid Tom | 72-Long Whistle |
49-Crash Cymbal 1 | 73-Short Guiro |
50-High Tom | 74-Long Guiro |
51-Ride Cymbal 1 | 75-Claves |
52-Chinese Cymbal | 76-High Wood Block |
53-Ride Bell | 77-Low Wood Block |
54-Tambourine | 78-Mute Cuica |
55-Splash Cymbal | 79-Open Cuica |
56-Cowbell | 80-Mute Triangle |
57-Crash Cymbal 2 | 81-Open Triangle |
58-Vibraslap |
Load control pCtrol with the list of all sections in which the instruments in the GM standard have been organized in the wxMidiDatabaseGM. If nSelInstris specified, the name of that section is left selected in the control. Otherwise, the first section is left selected.
Parameters
pCtrol
nSelInstr
Remarks:
This method is useful when in your application, the instruments are presented organized into sections instead of in a single long list with all GM instruments.
See an example in PopulateWithInstruments
See also:
PopulateWithAllInstruments, PopulateWithPercusionInstr, PopulateWithInstruments
Destructor.