31#include <wx/settings.h>
33#include <wx/statbmp.h>
34#include <wx/stattext.h>
35#include <wx/tooltip.h>
38#include "../TrackPanel.h"
44#include "../KeyboardCapture.h"
48#include "../widgets/Grabber.h"
52#if wxUSE_ACCESSIBILITY
69 static int value = wxNewId();
111 wxSizeEvent event(GetSize(), GetId());
112 event.SetEventObject(
this);
113 GetEventHandler()->ProcessEvent(event);
134#if wxUSE_ACCESSIBILITY
138 Add(
mHost, 15, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
148#if wxUSE_ACCESSIBILITY
152 Add(
mInput, 30, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
159#if wxUSE_ACCESSIBILITY
173#if wxUSE_ACCESSIBILITY
177 Add(
mOutput, 30, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
179#if defined(__WXGTK3__)
181#elif defined(__WXGTK__)
183 wxFont font =
mHost->GetFont();
187 mHost->SetFont(font);
193 mHost->Bind(wxEVT_SET_FOCUS,
196 mHost->Bind(wxEVT_KILL_FOCUS,
202 mOutput->Bind(wxEVT_KILL_FOCUS,
205 mInput->Bind(wxEVT_SET_FOCUS,
208 mInput->Bind(wxEVT_KILL_FOCUS,
230 wxKeyEvent *kevent = (wxKeyEvent *)event.GetEventObject();
231 int keyCode = kevent->GetKeyCode();
234 if (
FindFocus() ==
mInput && (keyCode == WXK_LEFT || keyCode == WXK_RIGHT
235 || keyCode == WXK_UP || keyCode == WXK_DOWN)) {
240 || keyCode == WXK_UP || keyCode == WXK_DOWN)) {
255 int hostSelectionIndex =
mHost->GetSelection();
256 wxString oldHost = hostSelectionIndex >= 0 ?
mHost->GetString(hostSelectionIndex) :
262 if (oldHost != hostName)
267 if (sourceName.empty())
270 desc = devName +
wxT(
": ") + sourceName;
277 for (
size_t i = 0; i < inMaps.size(); i++) {
278 if (inMaps[i].hostString == hostName &&
297 if (sourceName.empty())
300 desc = devName +
wxT(
": ") + sourceName;
305 }
else if (
mOutput->GetStringSelection() !=
desc &&
307 for (
size_t i = 0; i < outMaps.size(); i++) {
308 if (outMaps[i].hostString == hostName &&
328 if (newChannels > 0 && oldChannels != newChannels)
331 if (!hostName.empty() &&
mHost->GetStringSelection() != hostName)
332 mHost->SetStringSelection(hostName);
359 bool audioStreamActive = gAudioIO->IsStreamActive() && !gAudioIO->IsMonitoring();
362 if (audioStreamActive) {
368 mHost->Enable(!audioStreamActive);
369 mInput->Enable(!audioStreamActive);
370 mOutput->Enable(!audioStreamActive);
378 mOutput->SetName(
_(
"Playback Device"));
380 mInput->SetName(
_(
"Recording Device"));
381 mHost->SetName(
_(
"Audio Host"));
414 for (
auto & device : inMaps) {
416 hosts.push_back(device.hostString);
420 for (
auto & device : outMaps) {
422 hosts.push_back(device.hostString);
427 mHost->Append(hosts);
429 if (hosts.size() == 0) {
430 mHost->Enable(
false);
433 mHost->SetMinSize(wxSize(50, wxDefaultCoord));
443 int foundHostIndex = -1;
447 if (
mHost->FindString(host) == wxNOT_FOUND) {
451 for (
auto & device : outMaps) {
452 if (device.hostString == host) {
453 foundHostIndex = device.hostIndex;
458 if (foundHostIndex == -1) {
459 for (
auto & device : inMaps) {
460 if (device.hostString == host) {
461 foundHostIndex = device.hostIndex;
468 if (foundHostIndex == -1) {
469 if (outMaps.size()) {
470 foundHostIndex = outMaps[0].hostIndex;
472 else if (inMaps.size()) {
473 foundHostIndex = inMaps[0].hostIndex;
482 if (foundHostIndex == -1) {
487 for (
auto & device : inMaps) {
488 if (foundHostIndex == device.hostIndex) {
491 host = device.hostString;
493 mHost->SetStringSelection(host);
499 mInput->SetMinSize(wxSize(50, wxDefaultCoord));
501 for (
auto & device : outMaps) {
502 if (foundHostIndex == device.hostIndex) {
505 host = device.hostString;
508 mHost->SetStringSelection(host);
514 mOutput->SetMinSize(wxSize(50, wxDefaultCoord));
529 for (
auto & dev: inMaps) {
530 if (source == dev.sourceString &&
531 device == dev.deviceString &&
532 host == dev.hostString) {
535 for (
size_t j = 0; j < (
unsigned int) dev.numChannels; j++) {
539 name =
_(
"1 (Mono) Recording Channel");
542 name =
_(
"2 (Stereo) Recording Channels");
545 name = wxString::Format(
wxT(
"%d"), (
int) j + 1);
549 newChannels = dev.numChannels;
550 if (oldChannels <= newChannels && oldChannels >= 1) {
551 newChannels = oldChannels;
553 if (newChannels >= 1) {
575 int hostSelectionIndex;
576 hostSelectionIndex =
mHost->GetSelection();
579 wxString newHost = hostSelectionIndex >= 0 ?
mHost->GetString(hostSelectionIndex) :
582 if (oldHost == newHost)
626 int selectionIndex = combo->GetSelection();
632 if (selectionIndex >= 0 ) {
633 wxString newDevice = combo->GetStringSelection();
634 for (i = 0; i < maps.size(); ++i) {
637 if (
name == newDevice && maps[i].hostString == host) {
644 wxLogDebug(
wxT(
"DeviceToolBar::OnChoice(): couldn't find device indices"));
649 isInput ? NULL : &maps[newIndex]);
654 wxObject *eventObject =
event.GetEventObject();
656 if (eventObject ==
mHost) {
660 if (channelsSelectionIndex >= 0)
662 }
else if (eventObject ==
mInput) {
665 else if (eventObject ==
mOutput) {
684 if (gAudioIO->IsMonitoring())
686 gAudioIO->StopStream();
687 while (gAudioIO->IsBusy()) {
688 using namespace std::chrono;
689 std::this_thread::sleep_for(100ms);
692 gAudioIO->HandleDeviceChange();
717 if (!combo || combo->GetCount() == 0) {
730 S.StartVerticalLay(
true);
732 S.StartHorizontalLay(wxCENTER,
false);
734 c =
S.AddChoice(
Verbatim( combo->GetName() ),
735 transform_container<TranslatableStrings>( inputSources,
Verbatim ),
736 combo->GetSelection());
737 c->SetMinSize(c->GetBestSize());
739 S.EndHorizontalLay();
742 S.AddStandardButtons();
744 dlg.GetSizer()->SetSizeHints(&dlg);
747 if (dlg.ShowModal() == wxID_OK)
749 wxCommandEvent dummyEvent;
750 dummyEvent.SetEventObject(combo);
752 combo->SetSelection(c->GetSelection());
774#include "../CommonCommandFlags.h"
781 tb.ShowInputDialog();
788 tb.ShowOutputDialog();
795 tb.ShowChannelsDialog();
811 static auto menu = std::shared_ptr{
813 Command(
wxT(
"InputDevice"),
XXO(
"Change &Recording Device..."),
816 Command(
wxT(
"OutputDevice"),
XXO(
"Change &Playback Device..."),
821 Command(
wxT(
"InputChannels"),
XXO(
"Change Recording Cha&nnels..."),
829 Placement{
wxT(
"Optional/Extra/Part1"), { OrderingHint::End } }
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
StringSetting AudioIORecordingSource
StringSetting AudioIOPlaybackSource
StringSetting AudioIOPlaybackDevice
StringSetting AudioIORecordingDevice
StringSetting AudioIOHost
IntSetting AudioIORecordingSourceIndex
IntSetting AudioIORecordChannels
AttachedItem sAttachment2
const ReservedCommandFlag & AudioIONotBusyFlag()
wxString MakeDeviceSourceString(const DeviceSourceMap *map)
XXO("&Cut/Copy/Paste Toolbar")
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
audacity::BasicSettings * gPrefs
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
A widget for bitmaps which ignores the erase event for flicker-free use.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static AudioIOBase * Get()
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
DeviceSourceMap * GetDefaultInputDevice(int hostIndex)
const std::vector< DeviceSourceMap > & GetInputDeviceMaps()
const std::vector< DeviceSourceMap > & GetOutputDeviceMaps()
static DeviceManager * Instance()
Gets the singleton instance.
DeviceSourceMap * GetDefaultOutputDevice(int hostIndex)
An explicitly nonlocalized string, not meant for the user to see.
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
static void Broadcast(int id=0)
Call this static function to notify all PrefsListener objects.
virtual void UpdateSelectedPrefs(int id)
Generates classes whose instances register items at construction.
bool Write(const T &value)
Write value to config and return true if successful.
bool ReadWithDefault(T *pVar, const T &defaultValue) const
overload of ReadWithDefault returning a boolean that is true if the value was previously defined */
bool Reset()
Reset to the default value.
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined */
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
wxColour & Colour(int iIndex)
wxBitmap & Bitmap(int iIndex)
static TrackPanel & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
virtual bool Flush() noexcept=0
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
void SetName(const TranslatableString &title)
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
void OnFocus(wxWindow &window, wxFocusEvent &event)
a function useful to implement a focus event handler The window releases the keyboard if the event is...
std::unique_ptr< detail::IndirectItem< Item > > Indirect(const std::shared_ptr< Item > &ptr)
A convenience function.
const TranslatableString desc