Skip to content

Commit

Permalink
Brad's patch for automatically sorted out USB devices that have chang…
Browse files Browse the repository at this point in the history
…ed order - thanks Brad
  • Loading branch information
drowe67 committed Mar 18, 2019
1 parent 6256da3 commit b178f4f
Show file tree
Hide file tree
Showing 6 changed files with 420 additions and 156 deletions.
341 changes: 244 additions & 97 deletions src/dlg_audiooptions.cpp

Large diffs are not rendered by default.

20 changes: 12 additions & 8 deletions src/dlg_audiooptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,26 @@ class AudioOptsDialog : public wxDialog
PaError pa_err;
bool m_isPaInitialized;

int rxInAudioDeviceNum;
int rxOutAudioDeviceNum;
int txInAudioDeviceNum;
int txOutAudioDeviceNum;
std::string rxInAudioDeviceName;
std::string rxOutAudioDeviceName;
std::string txInAudioDeviceName;
std::string txOutAudioDeviceName;

void buildTestControls(PlotScalar **plotScalar, wxButton **btnTest,
wxPanel *parentPanel, wxBoxSizer *bSizer, wxString buttonLabel);
void plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar);
void plotDeviceOutputForAFewSecs(int devNum, PlotScalar *plotScalar);
void plotDeviceInputForAFewSecs(const std::string &soundCardName, PlotScalar *plotScalar);
void plotDeviceOutputForAFewSecs(const std::string &soundCardName, PlotScalar *plotScalar);

int buildListOfSupportedSampleRates(wxComboBox *cbSampleRate, int devNum, int in_out);
void populateParams(AudioInfoDisplay);
void showAPIInfo();
int setTextCtrlIfDevNumValid(wxTextCtrl *textCtrl, wxListCtrl *listCtrl, int devNum);
std::string setTextCtrlIfDevNameValid(wxTextCtrl *textCtrl, wxListCtrl *listCtrl, std::string &audioDevName);
std::string stripAudioDevName(std::string & devName);
int CountNumberOfCodecDevices(wxListCtrl *listCtrl);
void Pa_Init(void);
void OnDeviceSelect(wxComboBox *cbSampleRate,
wxTextCtrl *textCtrl,
int *devNum,
std::string & audioDevName,
wxListCtrl *listCtrlDevices,
int index,
int in_out);
Expand Down Expand Up @@ -172,5 +174,7 @@ class AudioOptsDialog : public wxDialog
AudioOptsDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Audio Config"), const wxPoint& pos = wxPoint(1,1), const wxSize& size = wxSize( 800, 650 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~AudioOptsDialog();
int ExchangeData(int inout);
static int displayConfigErrorCount;

};
#endif //__AudioOptsDialog__
134 changes: 93 additions & 41 deletions src/fdmdv2_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ int g_soundCard2InDeviceNum;
int g_soundCard2OutDeviceNum;
int g_soundCard2SampleRate;

std::string g_soundCard1InDeviceName;
std::string g_soundCard1OutDeviceName;
std::string g_soundCard2InDeviceName;
std::string g_soundCard2OutDeviceName;

// PortAudio over/underflow counters

int g_infifo1_full;
Expand Down Expand Up @@ -263,6 +268,11 @@ bool MainApp::OnInit()
frame->Show();
g_parent =frame;

AudioOptsDialog *dlg = new AudioOptsDialog(NULL);
dlg->ExchangeData(EXCHANGE_DATA_IN);
delete dlg;


return true;
}

Expand Down Expand Up @@ -426,20 +436,54 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam
wxGetApp().m_framesPerBuffer = pConfig->Read(wxT("/Audio/framesPerBuffer"), (int)PA_FPB);
wxGetApp().m_fifoSize_ms = pConfig->Read(wxT("/Audio/fifoSize_ms"), (int)FIFO_SIZE);

g_soundCard1InDeviceNum = pConfig->Read(wxT("/Audio/soundCard1InDeviceNum"), -1);
g_soundCard1OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard1OutDeviceNum"), -1);
g_soundCard1SampleRate = pConfig->Read(wxT("/Audio/soundCard1SampleRate"), -1);
// Legacy FreeDV would use sound card device numbers in the config file, but these numbers
// are not static within the OS. Newer FreeDV uses device names instead.
g_soundCard1InDeviceNum = pConfig->Read(wxT("/Audio/soundCard1InDeviceNum"), paNoDevice);
g_soundCard1OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard1OutDeviceNum"), paNoDevice);
g_soundCard1SampleRate = pConfig->Read(wxT("/Audio/soundCard1SampleRate"), -1);

g_soundCard2InDeviceNum = pConfig->Read(wxT("/Audio/soundCard2InDeviceNum"), -1);
g_soundCard2OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard2OutDeviceNum"), -1);
g_soundCard2SampleRate = pConfig->Read(wxT("/Audio/soundCard2SampleRate"), -1);
g_soundCard2InDeviceNum = pConfig->Read(wxT("/Audio/soundCard2InDeviceNum"), paNoDevice);
g_soundCard2OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard2OutDeviceNum"), paNoDevice);
g_soundCard2SampleRate = pConfig->Read(wxT("/Audio/soundCard2SampleRate"), -1);

g_soundCard1InDeviceName = pConfig->Read(wxT("/Audio/soundCard1InDeviceName"), wxT(""));
g_soundCard1OutDeviceName = pConfig->Read(wxT("/Audio/soundCard1OutDeviceName"), wxT(""));

g_soundCard2InDeviceName = pConfig->Read(wxT("/Audio/soundCard2InDeviceName"), wxT(""));
g_soundCard2OutDeviceName = pConfig->Read(wxT("/Audio/soundCard2OutDeviceName"), wxT(""));

// Temporarily initialize port audio so we can attempt to get device names based on
// previous device numbers. Temp redirect stderr so ALSA lib doesn't clutter term output

freopen("/dev/null", "w", stderr);

if(Pa_Initialize())
{
wxMessageBox(wxT("Port Audio failed to initialize"), wxT("Pa_Initialize"), wxOK);
}
freopen("/dev/tty", "w", stderr);

// In the event the user's config file uses legacy device numbers and not strings, use
// device numbers if they, and not the strings, are available. Save names instead later.
if ((g_soundCard1InDeviceNum != -1) && (g_soundCard1InDeviceName == ""))
g_soundCard1InDeviceName = PortAudioWrap::getDeviceNameStr(g_soundCard1InDeviceNum);

if ((g_soundCard1OutDeviceNum != -1) && (g_soundCard1OutDeviceName == ""))
g_soundCard1OutDeviceName = PortAudioWrap::getDeviceNameStr(g_soundCard1OutDeviceNum);

if ((g_soundCard2InDeviceNum != -1) && (g_soundCard2InDeviceName == ""))
g_soundCard2InDeviceName = PortAudioWrap::getDeviceNameStr(g_soundCard2InDeviceNum);

if ((g_soundCard2OutDeviceNum != -1) && (g_soundCard2OutDeviceName == ""))
g_soundCard2OutDeviceName = PortAudioWrap::getDeviceNameStr(g_soundCard2OutDeviceNum);

g_nSoundCards = 0;
if ((g_soundCard1InDeviceNum > -1) && (g_soundCard1OutDeviceNum > -1)) {
if ((g_soundCard1InDeviceName != "") && (g_soundCard1OutDeviceName != "")) {
g_nSoundCards = 1;
if ((g_soundCard2InDeviceNum > -1) && (g_soundCard2OutDeviceNum > -1))
if ((g_soundCard2InDeviceName != "") && (g_soundCard2OutDeviceName != ""))
g_nSoundCards = 2;
}
Pa_Terminate();

wxGetApp().m_playFileToMicInPath = pConfig->Read("/File/playFileToMicInPath", wxT(""));
wxGetApp().m_recFileFromRadioPath = pConfig->Read("/File/recFileFromRadioPath", wxT(""));
Expand Down Expand Up @@ -679,6 +723,7 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam
wxGetApp().m_txRxThreadHighPriority = true;
g_dump_timing = g_dump_fifo_state = 0;


UDPInit();
}

Expand Down Expand Up @@ -747,12 +792,12 @@ MainFrame::~MainFrame()
pConfig->Write(wxT("/Audio/framesPerBuffer"), wxGetApp().m_framesPerBuffer);
pConfig->Write(wxT("/Audio/fifoSize_ms"), wxGetApp().m_fifoSize_ms);

pConfig->Write(wxT("/Audio/soundCard1InDeviceNum"), g_soundCard1InDeviceNum);
pConfig->Write(wxT("/Audio/soundCard1OutDeviceNum"), g_soundCard1OutDeviceNum);
pConfig->Write(wxT("/Audio/soundCard1InDeviceName"), wxString(g_soundCard1InDeviceName));
pConfig->Write(wxT("/Audio/soundCard1OutDeviceName"), wxString(g_soundCard1OutDeviceName));
pConfig->Write(wxT("/Audio/soundCard1SampleRate"), g_soundCard1SampleRate );

pConfig->Write(wxT("/Audio/soundCard2InDeviceNum"), g_soundCard2InDeviceNum);
pConfig->Write(wxT("/Audio/soundCard2OutDeviceNum"), g_soundCard2OutDeviceNum);
pConfig->Write(wxT("/Audio/soundCard2InDeviceName"), wxString(g_soundCard2InDeviceName));
pConfig->Write(wxT("/Audio/soundCard2OutDeviceName"), wxString(g_soundCard2OutDeviceName));
pConfig->Write(wxT("/Audio/soundCard2SampleRate"), g_soundCard2SampleRate );

pConfig->Write(wxT("/VoiceKeyer/WaveFilePath"), wxGetApp().m_txtVoiceKeyerWaveFilePath);
Expand Down Expand Up @@ -2455,7 +2500,6 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
//
// Start Running -------------------------------------------------
//

// modify some button states when running

m_togBtnOnOff->SetLabel(wxT("Stop"));
Expand Down Expand Up @@ -2854,11 +2898,12 @@ void MainFrame::startRxStream()
}

m_rxInPa = new PortAudioWrap();
if(g_soundCard1InDeviceNum != g_soundCard1OutDeviceNum)

if(g_soundCard1InDeviceName != g_soundCard1OutDeviceName)
two_rx=true;
if(g_soundCard2InDeviceNum != g_soundCard2OutDeviceNum)
if(g_soundCard2InDeviceName != g_soundCard2OutDeviceName)
two_tx=true;

//fprintf(stderr, "two_rx: %d two_tx: %d\n", two_rx, two_tx);
if(two_rx)
m_rxOutPa = new PortAudioWrap();
Expand All @@ -2876,25 +2921,26 @@ void MainFrame::startRxStream()

// Init Sound card 1 ----------------------------------------------
// sanity check on sound card device numbers

if ((m_rxInPa->getDeviceCount() <= g_soundCard1InDeviceNum) ||
(m_rxOutPa->getDeviceCount() <= g_soundCard1OutDeviceNum)) {
if( !PortAudioWrap::isSoundCardNameValid(g_soundCard1InDeviceName)
|| !PortAudioWrap::isSoundCardNameValid(g_soundCard1OutDeviceName)) {
wxMessageBox(wxT("Sound Card 1 not present"), wxT("Error"), wxOK);
delete m_rxInPa;
if(two_rx)
delete m_rxOutPa;
delete m_rxOutPa;
m_RxRunning = false;
return;

}

// work out how many input channels this device supports.

deviceInfo1 = Pa_GetDeviceInfo(g_soundCard1InDeviceNum);
// work out how many input channels this device supports.
PaDeviceIndex soundCard1InDeviceNum = PortAudioWrap::getDeviceIndex(g_soundCard1InDeviceName);
deviceInfo1 = Pa_GetDeviceInfo(soundCard1InDeviceNum);
if (deviceInfo1 == NULL) {
wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card 1"), wxT("Error"), wxOK);
delete m_rxInPa;
if(two_rx)
delete m_rxOutPa;
delete m_rxOutPa;
m_RxRunning = false;
return;
}
Expand All @@ -2903,14 +2949,17 @@ void MainFrame::startRxStream()
else
inputChannels1 = 2;

PaDeviceIndex soundCard1OutDeviceNum = PortAudioWrap::getDeviceIndex(g_soundCard1OutDeviceName);

if(two_rx) {
initPortAudioDevice(m_rxInPa, g_soundCard1InDeviceNum, paNoDevice, 1,
initPortAudioDevice(m_rxInPa, soundCard1InDeviceNum, paNoDevice, 1,
g_soundCard1SampleRate, inputChannels1);
initPortAudioDevice(m_rxOutPa, paNoDevice, g_soundCard1OutDeviceNum, 1,

initPortAudioDevice(m_rxOutPa, paNoDevice, soundCard1OutDeviceNum, 1,
g_soundCard1SampleRate, inputChannels1);
}
else
initPortAudioDevice(m_rxInPa, g_soundCard1InDeviceNum, g_soundCard1OutDeviceNum, 1,
initPortAudioDevice(m_rxInPa, soundCard1InDeviceNum, soundCard1OutDeviceNum, 1,
g_soundCard1SampleRate, inputChannels1);

// Init Sound Card 2 ------------------------------------------------
Expand All @@ -2926,11 +2975,11 @@ void MainFrame::startRxStream()
// sanity check on sound card device numbers

//printf("m_txInPa->getDeviceCount(): %d\n", m_txInPa->getDeviceCount());
//printf("g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
//printf("g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
//wxPrintf("g_soundCard2InDeviceName: %s\n", g_soundCard2InDeviceName);
//wxPrintf("g_soundCard2OutDeviceName: %s\n", g_soundCard2OutDeviceName);

if ((m_txInPa->getDeviceCount() <= g_soundCard2InDeviceNum) ||
(m_txOutPa->getDeviceCount() <= g_soundCard2OutDeviceNum)) {
if( !PortAudioWrap::isSoundCardNameValid(g_soundCard2InDeviceName)
|| !PortAudioWrap::isSoundCardNameValid(g_soundCard2OutDeviceName)) {
wxMessageBox(wxT("Sound Card 2 not present"), wxT("Error"), wxOK);
delete m_rxInPa;
if(two_rx)
Expand All @@ -2942,15 +2991,16 @@ void MainFrame::startRxStream()
return;
}

deviceInfo2 = Pa_GetDeviceInfo(g_soundCard2InDeviceNum);
PaDeviceIndex soundCard2InDeviceNum = PortAudioWrap::getDeviceIndex(g_soundCard2InDeviceName);
deviceInfo2 = Pa_GetDeviceInfo(soundCard2InDeviceNum);
if (deviceInfo2 == NULL) {
wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card 1"), wxT("Error"), wxOK);
delete m_rxInPa;
if(two_rx)
delete m_rxOutPa;
delete m_rxOutPa;
delete m_txInPa;
if(two_tx)
delete m_txOutPa;
delete m_txOutPa;
m_RxRunning = false;
return;
}
Expand All @@ -2959,15 +3009,17 @@ void MainFrame::startRxStream()
else
inputChannels2 = 2;

PaDeviceIndex soundCard2OutDeviceNum = PortAudioWrap::getDeviceIndex(g_soundCard2OutDeviceName);

if(two_tx) {
initPortAudioDevice(m_txInPa, g_soundCard2InDeviceNum, paNoDevice, 2,
g_soundCard2SampleRate, inputChannels2);
initPortAudioDevice(m_txOutPa, paNoDevice, g_soundCard2OutDeviceNum, 2,
g_soundCard2SampleRate, inputChannels2);
}
else
initPortAudioDevice(m_txInPa, g_soundCard2InDeviceNum, g_soundCard2OutDeviceNum, 2,
g_soundCard2SampleRate, inputChannels2);
initPortAudioDevice(m_txInPa, soundCard2InDeviceNum, paNoDevice, 2,
g_soundCard2SampleRate, inputChannels2);
initPortAudioDevice(m_txOutPa, paNoDevice, soundCard2OutDeviceNum, 2,
g_soundCard2SampleRate, inputChannels2);
}
else
initPortAudioDevice(m_txInPa, soundCard2InDeviceNum, soundCard2OutDeviceNum, 2,
g_soundCard2SampleRate, inputChannels2);
}

// Init call back data structure ----------------------------------------------
Expand Down
8 changes: 7 additions & 1 deletion src/fdmdv2_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <wx/textdlg.h>
#include <wx/regex.h>
#include <wx/socket.h>
#include <wx/string.h>

#include <samplerate.h>

Expand Down Expand Up @@ -116,7 +117,12 @@ extern int g_soundCard2InDeviceNum;
extern int g_soundCard2OutDeviceNum;
extern int g_soundCard2SampleRate;

// Voice Keyer Constants
extern std::string g_soundCard1InDeviceName;
extern std::string g_soundCard1OutDeviceName;
extern std::string g_soundCard2InDeviceName;
extern std::string g_soundCard2OutDeviceName;

// Voice Keyer Constants

#define VK_SYNC_WAIT_TIME 5.0

Expand Down
58 changes: 55 additions & 3 deletions src/fdmdv2_pa_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,58 @@ PaError PortAudioWrap::setOutputDevice(PaDeviceIndex index)
PaError PortAudioWrap::setCallback(PaStreamCallback *callback)
{
m_pStreamCallback = callback;
return paNoError;
}

return paNoError;
}

//----------------------------------------------------------------
// isSoundCardNameValid()
//----------------------------------------------------------------
bool PortAudioWrap::isSoundCardNameValid(const wxString & soundCardName)
{
// If getDeviceIndex returns anything but paNoDevice, then the name is a
// valid sound card name
return (getDeviceIndex(soundCardName) != paNoDevice);
}

//----------------------------------------------------------------
// getDeviceIndex()
//----------------------------------------------------------------
PaDeviceIndex PortAudioWrap::getDeviceIndex(const wxString & soundCardName)
{
PaDeviceIndex index = paNoDevice;
const PaDeviceInfo * deviceInfo;

int numDevices = Pa_GetDeviceCount();

for (int devNum = 0; devNum < numDevices; devNum++) {
deviceInfo = Pa_GetDeviceInfo(devNum);
if (deviceInfo == NULL) {
//printf("PortAudioWrap::getDeviceIndex, call to Pa_GetDeviceInfo(%d) failed!\n", devNum);
continue;
}
else if (wxString::FromAscii(deviceInfo->name) == soundCardName) {
index = (PaDeviceIndex)devNum;
break;
}
}

return index;
}

//----------------------------------------------------------------
// getDeviceNameStr()
//----------------------------------------------------------------
wxString PortAudioWrap::getDeviceNameStr(PaDeviceIndex devNum)
{
const PaDeviceInfo * deviceInfo;
wxString devName = wxT("");

deviceInfo = Pa_GetDeviceInfo(devNum);
if (deviceInfo == NULL) {
wxPrintf("PortAudioWrap::getDeviceNameStr, call to Pa_GetDeviceInfo(%d) failed!\n", devNum);
}
else
devName = wxString::FromAscii(deviceInfo->name);

return devName;
}
Loading

0 comments on commit b178f4f

Please sign in to comment.