mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-01 08:29:27 +02:00
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 "portaudio.h"
|
||||||
#include "portmixer.h"
|
#include "portmixer.h"
|
||||||
|
|
||||||
#include "../Audacity.h"
|
#include "Audacity.h"
|
||||||
|
#include "AudioIO.h"
|
||||||
|
|
||||||
#include "DeviceManager.h"
|
#include "DeviceManager.h"
|
||||||
|
#include "toolbars/DeviceToolBar.h"
|
||||||
|
|
||||||
DeviceManager DeviceManager::dm;
|
DeviceManager DeviceManager::dm;
|
||||||
|
|
||||||
@ -30,13 +32,13 @@ void DeviceManager::Destroy()
|
|||||||
std::vector<DeviceSourceMap> &DeviceManager::GetInputDeviceMaps()
|
std::vector<DeviceSourceMap> &DeviceManager::GetInputDeviceMaps()
|
||||||
{
|
{
|
||||||
if (!m_inited)
|
if (!m_inited)
|
||||||
Rescan();
|
Init();
|
||||||
return mInputDeviceSourceMaps;
|
return mInputDeviceSourceMaps;
|
||||||
}
|
}
|
||||||
std::vector<DeviceSourceMap> &DeviceManager::GetOutputDeviceMaps()
|
std::vector<DeviceSourceMap> &DeviceManager::GetOutputDeviceMaps()
|
||||||
{
|
{
|
||||||
if (!m_inited)
|
if (!m_inited)
|
||||||
Rescan();
|
Init();
|
||||||
return mOutputDeviceSourceMaps;
|
return mOutputDeviceSourceMaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,8 +192,18 @@ void DeviceManager::Rescan()
|
|||||||
// if we are doing a second scan then restart portaudio to get new devices
|
// if we are doing a second scan then restart portaudio to get new devices
|
||||||
if (m_inited) {
|
if (m_inited) {
|
||||||
// check to see if there is a stream open - can happen if monitoring,
|
// 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_Terminate();
|
||||||
Pa_Initialize();
|
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;
|
m_inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ simplifies construction of menu items.
|
|||||||
#include "FileDialog.h"
|
#include "FileDialog.h"
|
||||||
#include "SplashDialog.h"
|
#include "SplashDialog.h"
|
||||||
#include "widgets/ErrorDialog.h"
|
#include "widgets/ErrorDialog.h"
|
||||||
|
#include "DeviceManager.h"
|
||||||
|
|
||||||
#include "CaptureEvents.h"
|
#include "CaptureEvents.h"
|
||||||
|
|
||||||
@ -643,6 +644,7 @@ void AudacityProject::CreateMenusAndCommands()
|
|||||||
#ifdef AUTOMATED_INPUT_LEVEL_ADJUSTMENT
|
#ifdef AUTOMATED_INPUT_LEVEL_ADJUSTMENT
|
||||||
c->AddCheck(wxT("AutomatedInputLevelAdjustmentOnOff"), _("Automated Input Level Adjustment (on/off)"), FN(OnToogleAutomatedInputLevelAdjustment), 0);
|
c->AddCheck(wxT("AutomatedInputLevelAdjustmentOnOff"), _("Automated Input Level Adjustment (on/off)"), FN(OnToogleAutomatedInputLevelAdjustment), 0);
|
||||||
#endif
|
#endif
|
||||||
|
c->AddItem(wxT("RescanDevices"), _("Rescan Audio Devices"), FN(OnRescanDevices));
|
||||||
|
|
||||||
if (!mCleanSpeechMode) {
|
if (!mCleanSpeechMode) {
|
||||||
|
|
||||||
@ -5391,6 +5393,11 @@ void AudacityProject::OnSoundActivated()
|
|||||||
dialog.ShowModal();
|
dialog.ShowModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudacityProject::OnRescanDevices()
|
||||||
|
{
|
||||||
|
DeviceManager::Instance()->Rescan();
|
||||||
|
}
|
||||||
|
|
||||||
int AudacityProject::DoAddLabel(double left, double right)
|
int AudacityProject::DoAddLabel(double left, double right)
|
||||||
{
|
{
|
||||||
LabelTrack *lt = NULL;
|
LabelTrack *lt = NULL;
|
||||||
|
@ -294,6 +294,7 @@ void OnToggleSWPlaythrough();
|
|||||||
#ifdef AUTOMATED_INPUT_LEVEL_ADJUSTMENT
|
#ifdef AUTOMATED_INPUT_LEVEL_ADJUSTMENT
|
||||||
void OnToogleAutomatedInputLevelAdjustment();
|
void OnToogleAutomatedInputLevelAdjustment();
|
||||||
#endif
|
#endif
|
||||||
|
void OnRescanDevices();
|
||||||
|
|
||||||
// Tracks Menu
|
// Tracks Menu
|
||||||
|
|
||||||
|
@ -103,31 +103,18 @@ void DeviceToolBar::DeinitChildren()
|
|||||||
|
|
||||||
void DeviceToolBar::Populate()
|
void DeviceToolBar::Populate()
|
||||||
{
|
{
|
||||||
wxArrayString inputs;
|
|
||||||
wxArrayString outputs;
|
|
||||||
wxArrayString hosts;
|
|
||||||
wxArrayString channels;
|
|
||||||
|
|
||||||
DeinitChildren();
|
DeinitChildren();
|
||||||
|
|
||||||
channels.Add(wxT("1 (Mono)"));
|
|
||||||
|
|
||||||
// Hosts
|
// Hosts
|
||||||
FillHosts(hosts);
|
|
||||||
mHost = new wxChoice(this,
|
mHost = new wxChoice(this,
|
||||||
wxID_ANY,
|
wxID_ANY,
|
||||||
wxDefaultPosition,
|
wxDefaultPosition,
|
||||||
wxDefaultSize,
|
wxDefaultSize);
|
||||||
hosts);
|
|
||||||
mHost->SetName(_("Audio Host"));
|
mHost->SetName(_("Audio Host"));
|
||||||
|
|
||||||
Add(mHost, 0, wxALIGN_CENTER);
|
Add(mHost, 0, wxALIGN_CENTER);
|
||||||
if (hosts.GetCount() == 0)
|
|
||||||
mHost->Enable(false);
|
|
||||||
|
|
||||||
// Output device
|
// Output device
|
||||||
mPlayBitmap = new wxBitmap(theTheme.Bitmap(bmpSpeaker));
|
mPlayBitmap = new wxBitmap(theTheme.Bitmap(bmpSpeaker));
|
||||||
|
|
||||||
Add(new wxStaticBitmap(this,
|
Add(new wxStaticBitmap(this,
|
||||||
wxID_ANY,
|
wxID_ANY,
|
||||||
*mPlayBitmap), 0, wxALIGN_CENTER);
|
*mPlayBitmap), 0, wxALIGN_CENTER);
|
||||||
@ -135,13 +122,9 @@ void DeviceToolBar::Populate()
|
|||||||
mOutput = new wxChoice(this,
|
mOutput = new wxChoice(this,
|
||||||
wxID_ANY,
|
wxID_ANY,
|
||||||
wxDefaultPosition,
|
wxDefaultPosition,
|
||||||
wxDefaultSize,
|
wxDefaultSize);
|
||||||
outputs);
|
|
||||||
mOutput->SetName(_("Output Device"));
|
mOutput->SetName(_("Output Device"));
|
||||||
|
|
||||||
Add(mOutput, 0, wxALIGN_CENTER);
|
Add(mOutput, 0, wxALIGN_CENTER);
|
||||||
if (outputs.GetCount() == 0)
|
|
||||||
mOutput->Enable(false);
|
|
||||||
|
|
||||||
// Input device
|
// Input device
|
||||||
mRecordBitmap = new wxBitmap(theTheme.Bitmap(bmpMic));
|
mRecordBitmap = new wxBitmap(theTheme.Bitmap(bmpMic));
|
||||||
@ -153,23 +136,16 @@ void DeviceToolBar::Populate()
|
|||||||
mInput = new wxChoice(this,
|
mInput = new wxChoice(this,
|
||||||
wxID_ANY,
|
wxID_ANY,
|
||||||
wxDefaultPosition,
|
wxDefaultPosition,
|
||||||
wxDefaultSize,
|
wxDefaultSize);
|
||||||
inputs);
|
|
||||||
mInput->SetName(_("Input Device"));
|
mInput->SetName(_("Input Device"));
|
||||||
Add(mInput, 0, wxALIGN_CENTER);
|
Add(mInput, 0, wxALIGN_CENTER);
|
||||||
if (inputs.GetCount() == 0)
|
|
||||||
mInput->Enable(false);
|
|
||||||
|
|
||||||
|
|
||||||
mInputChannels = new wxChoice(this,
|
mInputChannels = new wxChoice(this,
|
||||||
wxID_ANY,
|
wxID_ANY,
|
||||||
wxDefaultPosition,
|
wxDefaultPosition,
|
||||||
wxDefaultSize,
|
wxDefaultSize);
|
||||||
channels);
|
|
||||||
mInputChannels->SetName(_("Input Channels"));
|
mInputChannels->SetName(_("Input Channels"));
|
||||||
Add(mInputChannels, 0, wxALIGN_CENTER);
|
Add(mInputChannels, 0, wxALIGN_CENTER);
|
||||||
// hide the number of channels until we have some to display
|
|
||||||
mInputChannels->Enable(false);
|
|
||||||
|
|
||||||
mHost->Connect(wxEVT_SET_FOCUS,
|
mHost->Connect(wxEVT_SET_FOCUS,
|
||||||
wxFocusEventHandler(DeviceToolBar::OnFocus),
|
wxFocusEventHandler(DeviceToolBar::OnFocus),
|
||||||
@ -204,6 +180,12 @@ void DeviceToolBar::Populate()
|
|||||||
NULL,
|
NULL,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
|
RefillCombos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceToolBar::RefillCombos()
|
||||||
|
{
|
||||||
|
FillHosts();
|
||||||
FillHostDevices();
|
FillHostDevices();
|
||||||
FillInputChannels();
|
FillInputChannels();
|
||||||
// make the device display selection reflect the prefs if they exist
|
// make the device display selection reflect the prefs if they exist
|
||||||
@ -474,20 +456,26 @@ void DeviceToolBar::RepositionCombos()
|
|||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceToolBar::FillHosts(wxArrayString &hosts)
|
void DeviceToolBar::FillHosts()
|
||||||
{
|
{
|
||||||
|
wxArrayString hosts;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
|
std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
|
||||||
std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
|
std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
|
||||||
// go over our lists add the host to the list if it isn't there yet
|
// go over our lists add the host to the list if it isn't there yet
|
||||||
|
|
||||||
for (i = 0; i < inMaps.size(); i++)
|
for (i = 0; i < inMaps.size(); i++)
|
||||||
if (hosts.Index(inMaps[i].hostString) == wxNOT_FOUND)
|
if (hosts.Index(inMaps[i].hostString) == wxNOT_FOUND)
|
||||||
hosts.Add(inMaps[i].hostString);
|
hosts.Add(inMaps[i].hostString);
|
||||||
for (i = 0; i < outMaps.size(); i++)
|
for (i = 0; i < outMaps.size(); i++)
|
||||||
if (hosts.Index(outMaps[i].hostString) == wxNOT_FOUND)
|
if (hosts.Index(outMaps[i].hostString) == wxNOT_FOUND)
|
||||||
hosts.Add(outMaps[i].hostString);
|
hosts.Add(outMaps[i].hostString);
|
||||||
|
|
||||||
|
mHost->Clear();
|
||||||
|
mHost->Append(hosts);
|
||||||
|
|
||||||
|
if (hosts.GetCount() == 0)
|
||||||
|
mHost->Enable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceToolBar::FillHostDevices()
|
void DeviceToolBar::FillHostDevices()
|
||||||
@ -499,6 +487,12 @@ void DeviceToolBar::FillHostDevices()
|
|||||||
wxString host = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
|
wxString host = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
|
||||||
size_t i;
|
size_t i;
|
||||||
int foundHostIndex = -1;
|
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++) {
|
for (i = 0; i < outMaps.size(); i++) {
|
||||||
if (outMaps[i].hostString == host) {
|
if (outMaps[i].hostString == host) {
|
||||||
foundHostIndex = outMaps[i].hostIndex;
|
foundHostIndex = outMaps[i].hostIndex;
|
||||||
@ -535,6 +529,7 @@ void DeviceToolBar::FillHostDevices()
|
|||||||
if (host == wxT("")) {
|
if (host == wxT("")) {
|
||||||
host = inMaps[i].hostString;
|
host = inMaps[i].hostString;
|
||||||
gPrefs->Write(wxT("/AudioIO/Host"), host);
|
gPrefs->Write(wxT("/AudioIO/Host"), host);
|
||||||
|
mHost->SetStringSelection(host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,6 +542,7 @@ void DeviceToolBar::FillHostDevices()
|
|||||||
if (host == wxT("")) {
|
if (host == wxT("")) {
|
||||||
host = outMaps[i].hostString;
|
host = outMaps[i].hostString;
|
||||||
gPrefs->Write(wxT("/AudioIO/Host"), host);
|
gPrefs->Write(wxT("/AudioIO/Host"), host);
|
||||||
|
mHost->SetStringSelection(host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,12 @@ class DeviceToolBar:public ToolBar {
|
|||||||
void ShowHostDialog();
|
void ShowHostDialog();
|
||||||
void ShowChannelsDialog();
|
void ShowChannelsDialog();
|
||||||
|
|
||||||
|
void RefillCombos();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int ChangeHost();
|
int ChangeHost();
|
||||||
void ChangeDevice(bool isInput);
|
void ChangeDevice(bool isInput);
|
||||||
void FillHosts(wxArrayString &hosts);
|
void FillHosts();
|
||||||
void FillHostDevices();
|
void FillHostDevices();
|
||||||
void FillInputChannels();
|
void FillInputChannels();
|
||||||
void SetDevices(DeviceSourceMap *in, DeviceSourceMap *out);
|
void SetDevices(DeviceSourceMap *in, DeviceSourceMap *out);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user