Audacity  2.2.2
MidiIOPrefs.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  MidiIOPrefs.cpp
6 
7  Joshua Haberman
8  Dominic Mazzoni
9  James Crook
10 
11 *******************************************************************//********************************************************************/
25 
26 #include "../Audacity.h"
27 #include "../Experimental.h"
28 #ifdef EXPERIMENTAL_MIDI_OUT
29 
30 #include <wx/defs.h>
31 
32 #include <wx/choice.h>
33 #include <wx/intl.h>
34 
35 #include "../../lib-src/portmidi/pm_common/portmidi.h"
36 
37 #include "../AudioIO.h"
38 #include "../Internat.h"
39 #include "../Prefs.h"
40 #include "../Project.h"
41 #include "../ShuttleGui.h"
42 #include "../widgets/ErrorDialog.h"
43 
44 #include "MidiIOPrefs.h"
45 
46 enum {
47  HostID = 10000,
48  PlayID,
49  RecordID,
51 };
52 
53 BEGIN_EVENT_TABLE(MidiIOPrefs, PrefsPanel)
54  EVT_CHOICE(HostID, MidiIOPrefs::OnHost)
55 // EVT_CHOICE(RecordID, MidiIOPrefs::OnDevice)
57 
58 MidiIOPrefs::MidiIOPrefs(wxWindow * parent, wxWindowID winid)
59 /* i18n-hint: untranslatable acronym for "Musical Instrument Device Interface" */
60 : PrefsPanel(parent, winid, _("MIDI Devices"))
61 {
62  Populate();
63 }
64 
65 MidiIOPrefs::~MidiIOPrefs()
66 {
67 }
68 
69 void MidiIOPrefs::Populate()
70 {
71  // First any pre-processing for constructing the GUI.
72  GetNamesAndLabels();
73 
74  // Get current setting for devices
75  mPlayDevice = gPrefs->Read(wxT("/MidiIO/PlaybackDevice"), wxT(""));
76 #ifdef EXPERIMENTAL_MIDI_IN
77  mRecordDevice = gPrefs->Read(wxT("/MidiIO/RecordingDevice"), wxT(""));
78 #endif
79 // mRecordChannels = gPrefs->Read(wxT("/MidiIO/RecordChannels"), 2L);
80 
81  //------------------------- Main section --------------------
82  // Now construct the GUI itself.
83  // Use 'eIsCreatingFromPrefs' so that the GUI is
84  // initialised with values from gPrefs.
86  PopulateOrExchange(S);
87  // ----------------------- End of main section --------------
88 
89  wxCommandEvent e;
90  OnHost(e);
91 }
92 
97 void MidiIOPrefs::GetNamesAndLabels() {
98  // Gather list of hosts. Only added hosts that have devices attached.
99  Pm_Terminate(); // close and open to refresh device lists
100  Pm_Initialize();
101  int nDevices = Pm_CountDevices();
102  for (int i = 0; i < nDevices; i++) {
103  const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
104  if (info->output || info->input) { //should always happen
105  wxString name = wxSafeConvertMB2WX(info->interf);
106  if (mHostNames.Index(name) == wxNOT_FOUND) {
107  mHostNames.Add(name);
108  mHostLabels.Add(name);
109  }
110  }
111  }
112 }
113 
114 void MidiIOPrefs::PopulateOrExchange( ShuttleGui & S ) {
115  wxArrayString empty;
116 
117  S.SetBorder(2);
118  S.StartScroller();
119 
120  S.StartStatic(_("Interface"));
121  {
122  S.StartMultiColumn(2);
123  {
124  S.Id(HostID);
125  /* i18n-hint: (noun) */
126  mHost = S.TieChoice(_("&Host:"),
127  wxT("/MidiIO/Host"),
128  wxT(""),
129  mHostNames,
130  mHostLabels);
131  S.SetSizeHints(mHostNames);
132 
133  S.AddPrompt(_("Using: PortMidi"));
134  }
135  S.EndMultiColumn();
136  }
137  S.EndStatic();
138 
139  S.StartStatic(_("Playback"));
140  {
141  S.StartMultiColumn(2);
142  {
143  S.Id(PlayID);
144  mPlay = S.AddChoice(_("&Device:"),
145  wxEmptyString,
146  &empty);
147  int latency = gPrefs->Read(wxT("/MidiIO/OutputLatency"),
149  mLatency = S.TieNumericTextBox(_("MIDI Synth L&atency (ms):"),
150  wxT("/MidiIO/SynthLatency"),
151  latency, 3);
152  }
153  S.EndMultiColumn();
154  }
155  S.EndStatic();
156 #ifdef EXPERIMENTAL_MIDI_IN
157  S.StartStatic(_("Recording"));
158  {
159  S.StartMultiColumn(2);
160  {
161  S.Id(RecordID);
162  mRecord = S.AddChoice(_("De&vice:"),
163  wxEmptyString,
164  &empty);
165 
166  S.Id(ChannelsID);
167  /*
168  mChannels = S.AddChoice(_("&Channels:"),
169  wxEmptyString,
170  &empty);
171  */
172  }
173  S.EndMultiColumn();
174  }
175  S.EndStatic();
176 #endif
177  S.EndScroller();
178 
179 }
180 
181 void MidiIOPrefs::OnHost(wxCommandEvent & WXUNUSED(e))
182 {
183  wxString itemAtIndex;
184  int index = mHost->GetCurrentSelection();
185  if (index >= 0 && index < (int)mHostNames.Count())
186  itemAtIndex = mHostNames.Item(index);
187  int nDevices = Pm_CountDevices();
188 
189  if (nDevices == 0) {
190  mHost->Clear();
191  mHost->Append(_("No MIDI interfaces"), (void *) NULL);
192  mHost->SetSelection(0);
193  }
194 
195  mPlay->Clear();
196 #ifdef EXPERIMENTAL_MIDI_IN
197  mRecord->Clear();
198 #endif
199 
200  wxArrayString playnames;
201  wxArrayString recordnames;
202 
203  for (int i = 0; i < nDevices; i++) {
204  const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
205  wxString interf = wxSafeConvertMB2WX(info->interf);
206  if (itemAtIndex.IsSameAs(interf)) {
207  wxString name = wxSafeConvertMB2WX(info->name);
208  wxString device = wxString::Format(wxT("%s: %s"),
209  interf,
210  name);
211  int index;
212 
213  if (info->output) {
214  playnames.Add(name);
215  index = mPlay->Append(name, (void *) info);
216  if (device == mPlayDevice) {
217  mPlay->SetSelection(index);
218  }
219  }
220 #ifdef EXPERIMENTAL_MIDI_IN
221  if (info->input) {
222  recordnames.Add(name);
223  index = mRecord->Append(name, (void *) info);
224  if (device == mRecordDevice) {
225  mRecord->SetSelection(index);
226  }
227  }
228 #endif
229  }
230  }
231 
232  if (mPlay->GetCount() == 0) {
233  playnames.Add(_("No devices found"));
234  mPlay->Append(playnames[0], (void *) NULL);
235  }
236 #ifdef EXPERIMENTAL_MIDI_IN
237  if (mRecord->GetCount() == 0) {
238  recordnames.Add(_("No devices found"));
239  mRecord->Append(recordnames[0], (void *) NULL);
240  }
241 #endif
242  if (mPlay->GetCount() && mPlay->GetSelection() == wxNOT_FOUND) {
243  mPlay->SetSelection(0);
244  }
245 #ifdef EXPERIMENTAL_MIDI_IN
246  if (mRecord->GetCount() && mRecord->GetSelection() == wxNOT_FOUND) {
247  mRecord->SetSelection(0);
248  }
249 #endif
250  ShuttleGui S(this, eIsCreating);
251  S.SetSizeHints(mPlay, playnames);
252 #ifdef EXPERIMENTAL_MIDI_IN
253  S.SetSizeHints(mRecord, recordnames);
254 #endif
255 // OnDevice(e);
256 }
257 
258 bool MidiIOPrefs::Commit()
259 {
260  ShuttleGui S(this, eIsSavingToPrefs);
261  PopulateOrExchange(S);
262 
263  const PmDeviceInfo *info;
264 
265  info = (const PmDeviceInfo *) mPlay->GetClientData(mPlay->GetSelection());
266  if (info) {
267  gPrefs->Write(wxT("/MidiIO/PlaybackDevice"),
268  wxString::Format(wxT("%s: %s"),
269  wxString(wxSafeConvertMB2WX(info->interf)),
270  wxString(wxSafeConvertMB2WX(info->name))));
271  }
272 #ifdef EXPERIMENTAL_MIDI_IN
273  info = (const PmDeviceInfo *) mRecord->GetClientData(mRecord->GetSelection());
274  if (info) {
275  gPrefs->Write(wxT("/MidiIO/RecordingDevice"),
276  wxString::Format(wxT("%s: %s"),
277  wxString(wxSafeConvertMB2WX(info->interf)),
278  wxString(wxSafeConvertMB2WX(info->name))));
279  }
280 #endif
281  return gPrefs->Flush();
282 }
283 
284 bool MidiIOPrefs::Validate()
285 {
286  long latency;
287  if (!mLatency->GetValue().ToLong(&latency)) {
288  AudacityMessageBox(_("The MIDI Synthesizer Latency must be an integer"));
289  return false;
290  }
291  return true;
292 }
293 
294 wxString MidiIOPrefs::HelpPageName()
295 {
296  return "MIDI_Devices_Preferences";
297 }
298 
299 PrefsPanel *MidiIOPrefsFactory::operator () (wxWindow *parent, wxWindowID winid)
300 {
301  wxASSERT(parent); // to justify safenew
302  return safenew MidiIOPrefs(parent, winid);
303 }
304 
305 #endif
wxChoice * TieChoice(const wxString &Prompt, WrappedType &WrappedRef, const wxArrayString *pChoices)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:366
void EndMultiColumn()
int AudacityMessageBox(const wxString &message, const wxString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: ErrorDialog.h:92
void EndScroller()
Definition: ShuttleGui.cpp:770
#define safenew
Definition: Audacity.h:223
void AddPrompt(const wxString &Prompt)
Right aligned text string.
Definition: ShuttleGui.cpp:215
void SetSizeHints(int minX=-1, int minY=-1)
wxFileConfig * gPrefs
Definition: Prefs.cpp:72
wxScrolledWindow * StartScroller(int iStyle=0)
Definition: ShuttleGui.cpp:733
#define DEFAULT_SYNTH_LATENCY
Definition: AudioIO.h:82
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:998
wxChoice * AddChoice(const wxString &Prompt, const wxString &Selected, const wxArrayString *pChoices)
Definition: ShuttleGui.cpp:331
ShuttleGui & Id(int id)
wxTextCtrl * TieNumericTextBox(const wxString &Prompt, WrappedType &WrappedRef, const int nChars)
A PrefsPanel used to select recording and playback devices and other settings.
Used within the PrefsDialog, classes derived from this class include AudioIOPrefs, BatchPrefs, DirectoriesPrefs, FileFormatPrefs, GUIPrefs, KeyConfigPrefs, MousePrefs, QualityPrefs, SpectrumPrefs and ThemePrefs.
Definition: PrefsPanel.h:43
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
const wxChar * name
Definition: Distortion.cpp:94
wxStaticBox * StartStatic(const wxString &Str, int iProp=0)
Definition: ShuttleGui.cpp:701
END_EVENT_TABLE()
void SetBorder(int Border)
Definition: ShuttleGui.h:251