diff --git a/windows/JackNetWinSocket.cpp b/windows/JackNetWinSocket.cpp index b42b6230..c154ea65 100644 --- a/windows/JackNetWinSocket.cpp +++ b/windows/JackNetWinSocket.cpp @@ -33,11 +33,7 @@ namespace Jack return 0; } - struct - { - int code; - char* msg; - } NetErrorList[] = + win_net_error_t NetErrorList[] = { E ( 0, "No error" ), E ( WSAEINTR, "Interrupted system call" ), diff --git a/windows/JackNetWinSocket.h b/windows/JackNetWinSocket.h index a6b44dc2..aad36bf6 100644 --- a/windows/JackNetWinSocket.h +++ b/windows/JackNetWinSocket.h @@ -35,6 +35,13 @@ namespace Jack typedef uint32_t uint; 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 ); diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index 0e43cf4c..70e5c3e0 100644 Binary files a/windows/Setup/JackRouter.dll and b/windows/Setup/JackRouter.dll differ diff --git a/windows/Setup/README b/windows/Setup/README index 7264b6e0..85e0c2ba 100644 --- a/windows/Setup/README +++ b/windows/Setup/README @@ -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. +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'. 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. \ No newline at end of file diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index b6f2e2f8..7db52879 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -34,7 +34,7 @@ 1 1 deffast - 1 + 0 over diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 0897d380..9d30aa09 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -1,11 +1,11 @@ - + - + diff --git a/windows/portaudio/JackPortAudioDevices.cpp b/windows/portaudio/JackPortAudioDevices.cpp index 4d94d4f8..37640ad0 100644 --- a/windows/portaudio/JackPortAudioDevices.cpp +++ b/windows/portaudio/JackPortAudioDevices.cpp @@ -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; - 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(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(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; +}