bug 29/11 - add rescan capability for devices.
This is a workaround for the portaudio issue where changing the default device in xp will corrupt the portaudio device indecies. This combined with the portmixer fix (earlier today) should address bug 29.
This commit is contained in:
parent
271c4b0112
commit
4a762fc936
|
@ -9,9 +9,11 @@
|
|||
#include "portaudio.h"
|
||||
#include "portmixer.h"
|
||||
|
||||
#include "../Audacity.h"
|
||||
#include "Audacity.h"
|
||||
#include "AudioIO.h"
|
||||
|
||||
#include "DeviceManager.h"
|
||||
#include "toolbars/DeviceToolBar.h"
|
||||
|
||||
DeviceManager DeviceManager::dm;
|
||||
|
||||
|
@ -30,13 +32,13 @@ void DeviceManager::Destroy()
|
|||
std::vector<DeviceSourceMap> &DeviceManager::GetInputDeviceMaps()
|
||||
{
|
||||
if (!m_inited)
|
||||
Rescan();
|
||||
Init();
|
||||
return mInputDeviceSourceMaps;
|
||||
}
|
||||
std::vector<DeviceSourceMap> &DeviceManager::GetOutputDeviceMaps()
|
||||
{
|
||||
if (!m_inited)
|
||||
Rescan();
|
||||
Init();
|
||||
return mOutputDeviceSourceMaps;
|
||||
}
|
||||
|
||||
|
@ -190,8 +192,18 @@ void DeviceManager::Rescan()
|
|||
// if we are doing a second scan then restart portaudio to get new devices
|
||||
if (m_inited) {
|
||||
// check to see if there is a stream open - can happen if monitoring,
|
||||
// but otherwise Rescan() should not be available to the user.
|
||||
|
||||
// but otherwise Rescan() should not be available to the user.
|
||||
if (gAudioIO) {
|
||||
if (gAudioIO->IsMonitoring())
|
||||
{
|
||||
gAudioIO->StopStream();
|
||||
while (gAudioIO->IsBusy())
|
||||
wxMilliSleep(100);
|
||||
}
|
||||
gAudioIO->HandleDeviceChange();
|
||||
}
|
||||
|
||||
// restart portaudio - this updates the device list
|
||||
Pa_Terminate();
|
||||
Pa_Initialize();
|
||||
}
|
||||
|
@ -213,6 +225,15 @@ void DeviceManager::Rescan()
|
|||
}
|
||||
}
|
||||
|
||||
// If this was not an initial scan update each device toolbar.
|
||||
// Hosts may have disappeared or appeared so a complete repopulate is needed.
|
||||
if (m_inited) {
|
||||
DeviceToolBar *dt;
|
||||
for (size_t i = 0; i < gAudacityProjects.GetCount(); i++) {
|
||||
dt = gAudacityProjects[i]->GetDeviceToolBar();
|
||||
dt->RefillCombos();
|
||||
}
|
||||
}
|
||||
m_inited = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ simplifies construction of menu items.
|
|||
#include "FileDialog.h"
|
||||
#include "SplashDialog.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
#include "DeviceManager.h"
|
||||
|
||||
#include "CaptureEvents.h"
|
||||
|
||||
|
@ -643,6 +644,7 @@ void AudacityProject::CreateMenusAndCommands()
|
|||
#ifdef AUTOMATED_INPUT_LEVEL_ADJUSTMENT
|
||||
c->AddCheck(wxT("AutomatedInputLevelAdjustmentOnOff"), _("Automated Input Level Adjustment (on/off)"), FN(OnToogleAutomatedInputLevelAdjustment), 0);
|
||||
#endif
|
||||
c->AddItem(wxT("RescanDevices"), _("Rescan Audio Devices"), FN(OnRescanDevices));
|
||||
|
||||
if (!mCleanSpeechMode) {
|
||||
|
||||
|
@ -5391,6 +5393,11 @@ void AudacityProject::OnSoundActivated()
|
|||
dialog.ShowModal();
|
||||
}
|
||||
|
||||
void AudacityProject::OnRescanDevices()
|
||||
{
|
||||
DeviceManager::Instance()->Rescan();
|
||||
}
|
||||
|
||||
int AudacityProject::DoAddLabel(double left, double right)
|
||||
{
|
||||
LabelTrack *lt = NULL;
|
||||
|
|
|
@ -294,6 +294,7 @@ void OnToggleSWPlaythrough();
|
|||
#ifdef AUTOMATED_INPUT_LEVEL_ADJUSTMENT
|
||||
void OnToogleAutomatedInputLevelAdjustment();
|
||||
#endif
|
||||
void OnRescanDevices();
|
||||
|
||||
// Tracks Menu
|
||||
|
||||
|
|
|
@ -103,31 +103,18 @@ void DeviceToolBar::DeinitChildren()
|
|||
|
||||
void DeviceToolBar::Populate()
|
||||
{
|
||||
wxArrayString inputs;
|
||||
wxArrayString outputs;
|
||||
wxArrayString hosts;
|
||||
wxArrayString channels;
|
||||
|
||||
DeinitChildren();
|
||||
|
||||
channels.Add(wxT("1 (Mono)"));
|
||||
|
||||
// Hosts
|
||||
FillHosts(hosts);
|
||||
mHost = new wxChoice(this,
|
||||
wxID_ANY,
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
hosts);
|
||||
wxDefaultSize);
|
||||
mHost->SetName(_("Audio Host"));
|
||||
|
||||
Add(mHost, 0, wxALIGN_CENTER);
|
||||
if (hosts.GetCount() == 0)
|
||||
mHost->Enable(false);
|
||||
|
||||
// Output device
|
||||
mPlayBitmap = new wxBitmap(theTheme.Bitmap(bmpSpeaker));
|
||||
|
||||
Add(new wxStaticBitmap(this,
|
||||
wxID_ANY,
|
||||
*mPlayBitmap), 0, wxALIGN_CENTER);
|
||||
|
@ -135,13 +122,9 @@ void DeviceToolBar::Populate()
|
|||
mOutput = new wxChoice(this,
|
||||
wxID_ANY,
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
outputs);
|
||||
wxDefaultSize);
|
||||
mOutput->SetName(_("Output Device"));
|
||||
|
||||
Add(mOutput, 0, wxALIGN_CENTER);
|
||||
if (outputs.GetCount() == 0)
|
||||
mOutput->Enable(false);
|
||||
|
||||
// Input device
|
||||
mRecordBitmap = new wxBitmap(theTheme.Bitmap(bmpMic));
|
||||
|
@ -153,23 +136,16 @@ void DeviceToolBar::Populate()
|
|||
mInput = new wxChoice(this,
|
||||
wxID_ANY,
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
inputs);
|
||||
wxDefaultSize);
|
||||
mInput->SetName(_("Input Device"));
|
||||
Add(mInput, 0, wxALIGN_CENTER);
|
||||
if (inputs.GetCount() == 0)
|
||||
mInput->Enable(false);
|
||||
|
||||
|
||||
mInputChannels = new wxChoice(this,
|
||||
wxID_ANY,
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
channels);
|
||||
wxDefaultSize);
|
||||
mInputChannels->SetName(_("Input Channels"));
|
||||
Add(mInputChannels, 0, wxALIGN_CENTER);
|
||||
// hide the number of channels until we have some to display
|
||||
mInputChannels->Enable(false);
|
||||
|
||||
mHost->Connect(wxEVT_SET_FOCUS,
|
||||
wxFocusEventHandler(DeviceToolBar::OnFocus),
|
||||
|
@ -204,6 +180,12 @@ void DeviceToolBar::Populate()
|
|||
NULL,
|
||||
this);
|
||||
|
||||
RefillCombos();
|
||||
}
|
||||
|
||||
void DeviceToolBar::RefillCombos()
|
||||
{
|
||||
FillHosts();
|
||||
FillHostDevices();
|
||||
FillInputChannels();
|
||||
// make the device display selection reflect the prefs if they exist
|
||||
|
@ -474,20 +456,26 @@ void DeviceToolBar::RepositionCombos()
|
|||
Update();
|
||||
}
|
||||
|
||||
void DeviceToolBar::FillHosts(wxArrayString &hosts)
|
||||
void DeviceToolBar::FillHosts()
|
||||
{
|
||||
wxArrayString hosts;
|
||||
size_t i;
|
||||
|
||||
std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
|
||||
std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
|
||||
// go over our lists add the host to the list if it isn't there yet
|
||||
|
||||
for (i = 0; i < inMaps.size(); i++)
|
||||
if (hosts.Index(inMaps[i].hostString) == wxNOT_FOUND)
|
||||
hosts.Add(inMaps[i].hostString);
|
||||
for (i = 0; i < outMaps.size(); i++)
|
||||
if (hosts.Index(outMaps[i].hostString) == wxNOT_FOUND)
|
||||
hosts.Add(outMaps[i].hostString);
|
||||
|
||||
mHost->Clear();
|
||||
mHost->Append(hosts);
|
||||
|
||||
if (hosts.GetCount() == 0)
|
||||
mHost->Enable(false);
|
||||
}
|
||||
|
||||
void DeviceToolBar::FillHostDevices()
|
||||
|
@ -499,6 +487,12 @@ void DeviceToolBar::FillHostDevices()
|
|||
wxString host = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
|
||||
size_t i;
|
||||
int foundHostIndex = -1;
|
||||
|
||||
// if the host is not in the hosts combo then we rescanned.
|
||||
// set it to blank so we search for another host.
|
||||
if (mHost->FindString(host) == wxNOT_FOUND)
|
||||
host = wxT("");
|
||||
|
||||
for (i = 0; i < outMaps.size(); i++) {
|
||||
if (outMaps[i].hostString == host) {
|
||||
foundHostIndex = outMaps[i].hostIndex;
|
||||
|
@ -535,6 +529,7 @@ void DeviceToolBar::FillHostDevices()
|
|||
if (host == wxT("")) {
|
||||
host = inMaps[i].hostString;
|
||||
gPrefs->Write(wxT("/AudioIO/Host"), host);
|
||||
mHost->SetStringSelection(host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -547,6 +542,7 @@ void DeviceToolBar::FillHostDevices()
|
|||
if (host == wxT("")) {
|
||||
host = outMaps[i].hostString;
|
||||
gPrefs->Write(wxT("/AudioIO/Host"), host);
|
||||
mHost->SetStringSelection(host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,10 +53,12 @@ class DeviceToolBar:public ToolBar {
|
|||
void ShowHostDialog();
|
||||
void ShowChannelsDialog();
|
||||
|
||||
void RefillCombos();
|
||||
|
||||
private:
|
||||
int ChangeHost();
|
||||
void ChangeDevice(bool isInput);
|
||||
void FillHosts(wxArrayString &hosts);
|
||||
void FillHosts();
|
||||
void FillHostDevices();
|
||||
void FillInputChannels();
|
||||
void SetDevices(DeviceSourceMap *in, DeviceSourceMap *out);
|
||||
|
|
Loading…
Reference in New Issue