Browse Source

New JackRouter.dll : remove useless log files - cleanup

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3015 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.90
moret 17 years ago
parent
commit
f5b6fd7575
7 changed files with 303 additions and 298 deletions
  1. +1
    -5
      windows/JackNetWinSocket.cpp
  2. +7
    -0
      windows/JackNetWinSocket.h
  3. BIN
      windows/Setup/JackRouter.dll
  4. +3
    -0
      windows/Setup/README
  5. +1
    -1
      windows/Setup/jack.ci
  6. +2
    -2
      windows/jackd.workspace
  7. +289
    -290
      windows/portaudio/JackPortAudioDevices.cpp

+ 1
- 5
windows/JackNetWinSocket.cpp View File

@@ -33,11 +33,7 @@ namespace Jack
return 0; return 0;
} }


struct
{
int code;
char* msg;
} NetErrorList[] =
win_net_error_t NetErrorList[] =
{ {
E ( 0, "No error" ), E ( 0, "No error" ),
E ( WSAEINTR, "Interrupted system call" ), E ( WSAEINTR, "Interrupted system call" ),


+ 7
- 0
windows/JackNetWinSocket.h View File

@@ -35,6 +35,13 @@ namespace Jack


typedef uint32_t uint; typedef uint32_t uint;
typedef int SOCKLEN; typedef int SOCKLEN;
typedef struct _win_net_error win_net_error_t;

struct _win_net_error
{
int code;
char* msg;
};


SERVER_EXPORT const char* PrintError ( int error ); SERVER_EXPORT const char* PrintError ( int error );




BIN
windows/Setup/JackRouter.dll View File


+ 3
- 0
windows/Setup/README View File

@@ -3,6 +3,9 @@ It uses 'CreateInstall Free'(http://www.createinstall.com), a little software al
You can use the 'jack.ci' script to make the installer. For that, you need to build the Code::Blocks workspace in order to have '.exe' and libraries. You also need 'qjackctl' binaries and libraries ('qjackctl.exe', 'mingwm10.dll', 'QtCore4.dll', 'QtGui.dll' and 'QtXml4.dll'). You can recompile qjackctl with qt4 or directly get the binaries. The five files are expected in the 'qjackctl' folder. You can use the 'jack.ci' script to make the installer. For that, you need to build the Code::Blocks workspace in order to have '.exe' and libraries. You also need 'qjackctl' binaries and libraries ('qjackctl.exe', 'mingwm10.dll', 'QtCore4.dll', 'QtGui.dll' and 'QtXml4.dll'). You can recompile qjackctl with qt4 or directly get the binaries. The five files are expected in the 'qjackctl' folder.
If you need libjack.lib and libjackserver.lib to link with in MS Visual Studio, you can use the MS Tool lib.exe to create the .lib file from de .def.
Just use : 'lib /DEF:libjackserver.def /OUT:libjackserver.lib' and 'lib /DEF:libjack.def /OUT:libjack.lib' to create the lib file.
Once all binaries available, just execute the script in 'CreateInstall' to make 'setup.exe'. Once all binaries available, just execute the script in 'CreateInstall' to make 'setup.exe'.
The setup will copy all binaries to a specified folder, register the JackRouter (in order to have it in the ASIO drivers list) and create some shortcuts in the start menu. The setup will copy all binaries to a specified folder, register the JackRouter (in order to have it in the ASIO drivers list) and create some shortcuts in the start menu.
It's a good and proper way to get jack installed on windows. It's a good and proper way to get jack installed on windows.

+ 1
- 1
windows/Setup/jack.ci View File

@@ -34,7 +34,7 @@
<dlgautoprog> 1</> <dlgautoprog> 1</>
<dlgfinish> 1</> <dlgfinish> 1</>
<comptype> deffast</> <comptype> deffast</>
<solid> 1</>
<solid> 0</>
<srcfolder> </> <srcfolder> </>
<ifexist> over</> <ifexist> over</>
<runafter> </> <runafter> </>


+ 2
- 2
windows/jackd.workspace View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_workspace_file> <CodeBlocks_workspace_file>
<Workspace title="jack"> <Workspace title="jack">
<Project filename="libjackserver.cbp" />
<Project filename="libjackserver.cbp" active="1" />
<Project filename="jackd.cbp"> <Project filename="jackd.cbp">
<Depends filename="libjackserver.cbp" /> <Depends filename="libjackserver.cbp" />
</Project> </Project>
<Project filename="jack_portaudio.cbp" active="1">
<Project filename="jack_portaudio.cbp">
<Depends filename="libjackserver.cbp" /> <Depends filename="libjackserver.cbp" />
</Project> </Project>
<Project filename="jack_netdriver.cbp"> <Project filename="jack_netdriver.cbp">


+ 289
- 290
windows/portaudio/JackPortAudioDevices.cpp View File

@@ -1,291 +1,290 @@
/*
Copyright (C) 2008 Romain Moret at Grame
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "JackPortAudioDevices.h"
#include "JackError.h"
using namespace std;
PortAudioDevices::PortAudioDevices()
{
PaError err;
/*
Copyright (C) 2008 Romain Moret at Grame
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "JackPortAudioDevices.h"
#include "JackError.h"
using namespace std;
PortAudioDevices::PortAudioDevices()
{
PaError err;
PaDeviceIndex id; PaDeviceIndex id;
jack_log("Initializing PortAudio...");
if ( ( err = Pa_Initialize() ) == paNoError )
{
fNumHostApi = Pa_GetHostApiCount();
fNumDevice = Pa_GetDeviceCount();
fDeviceInfo = new PaDeviceInfo*[fNumDevice];
for ( id = 0; id < fNumDevice; id++ )
fDeviceInfo[id] = const_cast<PaDeviceInfo*>(Pa_GetDeviceInfo(id));
fHostName = new string[fNumHostApi];
for ( id = 0; id < fNumHostApi; id++ )
fHostName[id] = string ( Pa_GetHostApiInfo(id)->name );
}
else
jack_error("JackPortAudioDriver::Pa_Initialize error = %s", Pa_GetErrorText(err));
}
PortAudioDevices::~PortAudioDevices()
{
Pa_Terminate();
delete[] fDeviceInfo;
delete[] fHostName;
}
PaDeviceIndex PortAudioDevices::GetNumDevice()
{
return fNumDevice;
}
PaDeviceInfo* PortAudioDevices::GetDeviceInfo ( PaDeviceIndex id )
{
return fDeviceInfo[id];
}
string PortAudioDevices::GetDeviceName ( PaDeviceIndex id )
{
return string ( fDeviceInfo[id]->name );
}
string PortAudioDevices::GetHostFromDevice ( PaDeviceInfo* device )
{
return fHostName[device->hostApi];
}
string PortAudioDevices::GetHostFromDevice ( PaDeviceIndex id )
{
return fHostName[fDeviceInfo[id]->hostApi];
}
string PortAudioDevices::GetFullName ( PaDeviceIndex id )
{
string hostname = GetHostFromDevice ( id );
string devicename = GetDeviceName ( id );
//some hostname are quite long...use shortcuts
if ( hostname.compare ( "Windows DirectSound" ) == 0 )
hostname = string ( "DirectSound" );
return ( hostname + "::" + devicename );
}
string PortAudioDevices::GetFullName ( std::string hostname, std::string devicename )
{
//some hostname are quite long...use shortcuts
if ( hostname.compare ( "Windows DirectSound" ) == 0 )
hostname = string ( "DirectSound" );
return ( hostname + "::" + devicename );
}
PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName ( string fullname, PaDeviceIndex& id, bool isInput )
{
PaDeviceInfo* ret = NULL;
//no driver to find
if ( fullname.size() == 0 )
return NULL;
//first get host and device names from fullname
string::size_type separator = fullname.find ( "::", 0 );
if ( separator == 0 )
return NULL;
char* hostname = (char*)malloc(separator + 9);
fill_n ( hostname, separator + 9, 0 );
fullname.copy ( hostname, separator );
//we need the entire hostname, replace shortcuts
if ( strcmp ( hostname, "DirectSound" ) == 0 )
strcpy ( hostname, "Windows DirectSound" );
string devicename = fullname.substr ( separator + 2 );
//then find the corresponding device
for ( PaDeviceIndex dev_id = 0; dev_id < fNumDevice; dev_id++ )
{
bool flag = (isInput) ? (fDeviceInfo[dev_id]->maxInputChannels > 0) : (fDeviceInfo[dev_id]->maxOutputChannels > 0);
if ( ( GetHostFromDevice(dev_id).compare(hostname) == 0 )
&& ( GetDeviceName(dev_id).compare(devicename) == 0 )
&& flag )
{
id = dev_id;
ret = fDeviceInfo[dev_id];
}
}
free(hostname);
return ret;
}
void PortAudioDevices::PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters)
{
static double standardSampleRates[] =
{
8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1 /* negative terminated list */
};
int i, printCount;
PaError err;
printCount = 0;
for (i = 0; standardSampleRates[i] > 0; i++)
{
err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]);
if (err == paFormatIsSupported)
{
if (printCount == 0)
{
jack_info("\t%8.2f", standardSampleRates[i]);
printCount = 1;
}
else if (printCount == 4)
{
jack_info(",\n\t%8.2f", standardSampleRates[i]);
printCount = 1;
}
else
{
jack_info(", %8.2f", standardSampleRates[i]);
++printCount;
}
}
}
if (!printCount) {
jack_info("None");
} else {
jack_info("\n");
}
}
int PortAudioDevices::GetInputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_input)
{
string fullname = string ( devicename );
PaDeviceInfo* device = GetDeviceFromFullName ( fullname, id, true );
if ( device )
max_input = device->maxInputChannels;
else
{
id = Pa_GetDefaultInputDevice();
if ( fullname.size() )
jack_error("Can't open %s, PortAudio will use default input device.", devicename);
if ( id == paNoDevice )
return -1;
max_input = GetDeviceInfo(id)->maxInputChannels;
}
return id;
}
int PortAudioDevices::GetOutputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_output)
{
string fullname = string ( devicename );
PaDeviceInfo* device = GetDeviceFromFullName ( fullname, id, false );
if ( device )
max_output = device->maxOutputChannels;
else
{
id = Pa_GetDefaultOutputDevice();
if ( fullname.size() )
jack_error("Can't open %s, PortAudio will use default output device.", devicename);
if ( id == paNoDevice )
return -1;
max_output = GetDeviceInfo(id)->maxOutputChannels;
}
return id;
}
void PortAudioDevices::DisplayDevicesNames()
{
int def_display;
PaDeviceIndex id;
PaStreamParameters inputParameters, outputParameters;
jack_info ( "********************** Devices list, %d detected **********************", fNumDevice );
for ( id = 0; id < fNumDevice; id++ )
{
jack_info ( "-------- device #%d ------------------------------------------------", id );
if ( id == Pa_GetDefaultInputDevice() )
{
jack_info("[ Default Input ]");
}
else if ( id == Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi)->defaultInputDevice )
{
const PaHostApiInfo *host_info = Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi );
jack_info ( "[ Default %s Input ]", host_info->name );
}
if ( id == Pa_GetDefaultOutputDevice() )
{
jack_info ( "[ Default Output ]" );
}
else if ( id == Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi )->defaultOutputDevice )
{
const PaHostApiInfo *host_info = Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi );
jack_info ( "[ Default %s Output ]", host_info->name );
}
/* print device info fields */
jack_info ( "Name = %s", GetFullName ( id ).c_str() );
jack_info ( "Max inputs = %d", fDeviceInfo[id]->maxInputChannels );
jack_info ( "Max outputs = %d", fDeviceInfo[id]->maxOutputChannels );
#ifdef WIN32
/* ASIO specific latency information */
if ( Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO )
{
long minLatency, maxLatency, preferredLatency, granularity;
PaAsio_GetAvailableLatencyValues ( id, &minLatency, &maxLatency, &preferredLatency, &granularity );
jack_info ( "ASIO minimum buffer size = %ld", minLatency );
jack_info ( "ASIO maximum buffer size = %ld", maxLatency );
jack_info ( "ASIO preferred buffer size = %ld", preferredLatency );
if ( granularity == -1 )
jack_info ( "ASIO buffer granularity = power of 2" );
else
jack_info ( "ASIO buffer granularity = %ld", granularity );
}
#endif
jack_info ( "Default sample rate = %8.2f", fDeviceInfo[id]->defaultSampleRate );
/* poll for standard sample rates */
inputParameters.device = id;
inputParameters.channelCount = fDeviceInfo[id]->maxInputChannels;
inputParameters.sampleFormat = paInt16;
inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = id;
outputParameters.channelCount = fDeviceInfo[id]->maxOutputChannels;
outputParameters.sampleFormat = paInt16;
outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
outputParameters.hostApiSpecificStreamInfo = NULL;
}
jack_info ( "**************************** End of list ****************************" );
}
bool PortAudioDevices::IsDuplex ( PaDeviceIndex id )
{
//does the device has in and out facilities
if ( fDeviceInfo[id]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels )
return true;
//else is another complementary device ? (search in devices with the same name)
for ( PaDeviceIndex i = 0; i < fNumDevice; i++ )
if ( ( i != id ) && ( GetDeviceName ( i ) == GetDeviceName ( id ) ) )
if ( ( fDeviceInfo[i]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels )
|| ( fDeviceInfo[i]->maxOutputChannels && fDeviceInfo[id]->maxInputChannels ) )
return true;
//then the device isn't full duplex
return false;
}
jack_log("Initializing PortAudio...");
if ( ( err = Pa_Initialize() ) == paNoError )
{
fNumHostApi = Pa_GetHostApiCount();
fNumDevice = Pa_GetDeviceCount();
fDeviceInfo = new PaDeviceInfo*[fNumDevice];
for ( id = 0; id < fNumDevice; id++ )
fDeviceInfo[id] = const_cast<PaDeviceInfo*>(Pa_GetDeviceInfo(id));
fHostName = new string[fNumHostApi];
for ( id = 0; id < fNumHostApi; id++ )
fHostName[id] = string ( Pa_GetHostApiInfo(id)->name );
}
else
jack_error("JackPortAudioDriver::Pa_Initialize error = %s", Pa_GetErrorText(err));
}

PortAudioDevices::~PortAudioDevices()
{
Pa_Terminate();
delete[] fDeviceInfo;
delete[] fHostName;
}

PaDeviceIndex PortAudioDevices::GetNumDevice()
{
return fNumDevice;
}

PaDeviceInfo* PortAudioDevices::GetDeviceInfo ( PaDeviceIndex id )
{
return fDeviceInfo[id];
}

string PortAudioDevices::GetDeviceName ( PaDeviceIndex id )
{
return string ( fDeviceInfo[id]->name );
}

string PortAudioDevices::GetHostFromDevice ( PaDeviceInfo* device )
{
return fHostName[device->hostApi];
}

string PortAudioDevices::GetHostFromDevice ( PaDeviceIndex id )
{
return fHostName[fDeviceInfo[id]->hostApi];
}

string PortAudioDevices::GetFullName ( PaDeviceIndex id )
{
string hostname = GetHostFromDevice ( id );
string devicename = GetDeviceName ( id );
//some hostname are quite long...use shortcuts
if ( hostname.compare ( "Windows DirectSound" ) == 0 )
hostname = string ( "DirectSound" );
return ( hostname + "::" + devicename );
}

string PortAudioDevices::GetFullName ( std::string hostname, std::string devicename )
{
//some hostname are quite long...use shortcuts
if ( hostname.compare ( "Windows DirectSound" ) == 0 )
hostname = string ( "DirectSound" );
return ( hostname + "::" + devicename );
}

PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName ( string fullname, PaDeviceIndex& id, bool isInput )
{
PaDeviceInfo* ret = NULL;
//no driver to find
if ( fullname.size() == 0 )
return NULL;
//first get host and device names from fullname
string::size_type separator = fullname.find ( "::", 0 );
if ( separator == 0 )
return NULL;
char* hostname = (char*)malloc(separator + 9);
fill_n ( hostname, separator + 9, 0 );
fullname.copy ( hostname, separator );

//we need the entire hostname, replace shortcuts
if ( strcmp ( hostname, "DirectSound" ) == 0 )
strcpy ( hostname, "Windows DirectSound" );
string devicename = fullname.substr ( separator + 2 );
//then find the corresponding device
for ( PaDeviceIndex dev_id = 0; dev_id < fNumDevice; dev_id++ )
{
bool flag = (isInput) ? (fDeviceInfo[dev_id]->maxInputChannels > 0) : (fDeviceInfo[dev_id]->maxOutputChannels > 0);
if ( ( GetHostFromDevice(dev_id).compare(hostname) == 0 )
&& ( GetDeviceName(dev_id).compare(devicename) == 0 )
&& flag )
{
id = dev_id;
ret = fDeviceInfo[dev_id];
}
}
free(hostname);
return ret;
}

void PortAudioDevices::PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters)
{
static double standardSampleRates[] =
{
8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1 /* negative terminated list */
};
int i, printCount;
PaError err;

printCount = 0;
for (i = 0; standardSampleRates[i] > 0; i++)
{
err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]);
if (err == paFormatIsSupported)
{
if (printCount == 0)
{
jack_info("\t%8.2f", standardSampleRates[i]);
printCount = 1;
}
else if (printCount == 4)
{
jack_info(",\n\t%8.2f", standardSampleRates[i]);
printCount = 1;
}
else
{
jack_info(", %8.2f", standardSampleRates[i]);
++printCount;
}
}
}
if (!printCount) {
jack_info("None");
} else {
jack_info("\n");
}
}

int PortAudioDevices::GetInputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_input)
{
string fullname = string ( devicename );
PaDeviceInfo* device = GetDeviceFromFullName ( fullname, id, true );
if ( device )
max_input = device->maxInputChannels;
else
{
id = Pa_GetDefaultInputDevice();
if ( fullname.size() )
jack_error("Can't open %s, PortAudio will use default input device.", devicename);
if ( id == paNoDevice )
return -1;
max_input = GetDeviceInfo(id)->maxInputChannels;
}
return id;
}

int PortAudioDevices::GetOutputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_output)
{
string fullname = string ( devicename );
PaDeviceInfo* device = GetDeviceFromFullName ( fullname, id, false );
if ( device )
max_output = device->maxOutputChannels;
else
{
id = Pa_GetDefaultOutputDevice();
if ( fullname.size() )
jack_error("Can't open %s, PortAudio will use default output device.", devicename);
if ( id == paNoDevice )
return -1;
max_output = GetDeviceInfo(id)->maxOutputChannels;
}
return id;
}

void PortAudioDevices::DisplayDevicesNames()
{
PaDeviceIndex id;
PaStreamParameters inputParameters, outputParameters;
jack_info ( "********************** Devices list, %d detected **********************", fNumDevice );

for ( id = 0; id < fNumDevice; id++ )
{
jack_info ( "-------- device #%d ------------------------------------------------", id );

if ( id == Pa_GetDefaultInputDevice() )
{
jack_info("[ Default Input ]");
}
else if ( id == Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi)->defaultInputDevice )
{
const PaHostApiInfo *host_info = Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi );
jack_info ( "[ Default %s Input ]", host_info->name );
}

if ( id == Pa_GetDefaultOutputDevice() )
{
jack_info ( "[ Default Output ]" );
}
else if ( id == Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi )->defaultOutputDevice )
{
const PaHostApiInfo *host_info = Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi );
jack_info ( "[ Default %s Output ]", host_info->name );
}

/* print device info fields */
jack_info ( "Name = %s", GetFullName ( id ).c_str() );
jack_info ( "Max inputs = %d", fDeviceInfo[id]->maxInputChannels );
jack_info ( "Max outputs = %d", fDeviceInfo[id]->maxOutputChannels );

#ifdef WIN32
/* ASIO specific latency information */
if ( Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO )
{
long minLatency, maxLatency, preferredLatency, granularity;

PaAsio_GetAvailableLatencyValues ( id, &minLatency, &maxLatency, &preferredLatency, &granularity );

jack_info ( "ASIO minimum buffer size = %ld", minLatency );
jack_info ( "ASIO maximum buffer size = %ld", maxLatency );
jack_info ( "ASIO preferred buffer size = %ld", preferredLatency );

if ( granularity == -1 )
jack_info ( "ASIO buffer granularity = power of 2" );
else
jack_info ( "ASIO buffer granularity = %ld", granularity );
}
#endif

jack_info ( "Default sample rate = %8.2f", fDeviceInfo[id]->defaultSampleRate );

/* poll for standard sample rates */
inputParameters.device = id;
inputParameters.channelCount = fDeviceInfo[id]->maxInputChannels;
inputParameters.sampleFormat = paInt16;
inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
inputParameters.hostApiSpecificStreamInfo = NULL;

outputParameters.device = id;
outputParameters.channelCount = fDeviceInfo[id]->maxOutputChannels;
outputParameters.sampleFormat = paInt16;
outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
outputParameters.hostApiSpecificStreamInfo = NULL;
}
jack_info ( "**************************** End of list ****************************" );
}

bool PortAudioDevices::IsDuplex ( PaDeviceIndex id )
{
//does the device has in and out facilities
if ( fDeviceInfo[id]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels )
return true;
//else is another complementary device ? (search in devices with the same name)
for ( PaDeviceIndex i = 0; i < fNumDevice; i++ )
if ( ( i != id ) && ( GetDeviceName ( i ) == GetDeviceName ( id ) ) )
if ( ( fDeviceInfo[i]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels )
|| ( fDeviceInfo[i]->maxOutputChannels && fDeviceInfo[id]->maxInputChannels ) )
return true;
//then the device isn't full duplex
return false;
}

Loading…
Cancel
Save