From cb951c92c2bcf65ef0c42ba1bedda646b33041b6 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Sun, 29 Nov 2009 12:05:19 +0000 Subject: [PATCH] - removed ALSA support, - added accessibility plugin --- ChangeLog | 13 +- configure.in | 12 +- linux/sound.cpp | 364 +----------------------------------------- linux/sound.h | 76 +-------- src/main.cpp | 13 +- windows/installer.nsi | 10 +- windows/sound.h | 3 +- 7 files changed, 38 insertions(+), 453 deletions(-) diff --git a/ChangeLog b/ChangeLog index 219d28d8..baa8503a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ 3.0.3 - -- accessibility improvements + +- accessibility improvements - show number of connected clients in window title (and therefore in OS task bar) @@ -10,11 +10,14 @@ - server logging history grid lines of weekend days are now plotted with different line width -- bug fix: fix for disconnect issue at the server - -- added "Whats this" help text to the GUI controls in the general settings +- bug fix: fix for disconnect issue at the server + +- added "Whats this" help text to the GUI controls in the general settings dialog +- removed ALSA support since the ALSA interface implementation in llcon was + buggy and will not be maintained in the future + 3.0.2 diff --git a/configure.in b/configure.in index 2b1d353e..4e51c1cc 100755 --- a/configure.in +++ b/configure.in @@ -19,14 +19,10 @@ AC_PROG_MAKE_SET dnl Configuration Arguments AC_ARG_ENABLE( sound,[ --enable-sound generic sound support], enable_sound=$enableval, enable_sound=yes) -AC_ARG_ENABLE( alsa,[ --enable-alsa use ALSA interface], enable_alsa=$enableval, enable_alsa=no) -if test "$enable_alsa" = "yes"; then - dnl checks for ALSA audio - AC_CHECK_HEADER(sys/asoundlib.h, , enable_sound=no) - AC_CHECK_LIB(asound, snd_pcm_open, , enable_sound=no) -else +dnl Check for Jack +if test "$enable_sound" = "yes"; then dnl checks for JACK audio AC_CHECK_HEADER([jack/jack.h], have_jack=yes, have_jack=no, [ ]) @@ -36,14 +32,10 @@ else JACK_LIB="-ljack" AC_DEFINE(USE_JACK, 1,[Define to enable JACK input module]) fi -fi -if test "$enable_sound" = "yes"; then AC_DEFINE(WITH_SOUND, 1, [Define if you want to use sound]) fi - - dnl Checks for header files. AC_HEADER_STDC AC_LANG_CPLUSPLUS diff --git a/linux/sound.cpp b/linux/sound.cpp index b8a7dc74..6a01135b 100755 --- a/linux/sound.cpp +++ b/linux/sound.cpp @@ -2,18 +2,14 @@ * Copyright (c) 2004-2009 * * Author(s): - * Volker Fischer, Alexander Kurpiers - * - * This code is based on the Open-Source sound interface implementation of - * the Dream DRM Receiver project and on the simple_client example of the - * Jack audio interface. + * Volker Fischer * + * This code is based on the simple_client example of the Jack audio interface. \******************************************************************************/ #include "sound.h" #ifdef WITH_SOUND -# if USE_JACK void CSound::OpenJack() { jack_status_t JackStatus; @@ -244,360 +240,4 @@ void CSound::shutdownCallback ( void *arg ) // error message throw CGenErr ( "Jack server was shut down" ); } -# else -// Wave in ********************************************************************* -void CSound::InitRecording() -{ - int err; - - // if recording device was already open, close it first - if ( rhandle != NULL ) - { - snd_pcm_close ( rhandle ); - } - - /* record device: The most important ALSA interfaces to the PCM devices are - the "plughw" and the "hw" interface. If you use the "plughw" interface, - you need not care much about the sound hardware. If your soundcard does - not support the sample rate or sample format you specify, your data will - be automatically converted. This also applies to the access type and the - number of channels. With the "hw" interface, you have to check whether - your hardware supports the configuration you would like to use */ - // either "hw:0,0" or "plughw:0,0" - if ( err = snd_pcm_open ( &rhandle, "hw:0,0", SND_PCM_STREAM_CAPTURE, 0 ) != 0 ) - { - qDebug ( "open error: %s", snd_strerror ( err ) ); - } - - // recording should be blocking - if ( err = snd_pcm_nonblock ( rhandle, FALSE ) != 0 ) - { - qDebug ( "cannot set blocking: %s", snd_strerror ( err ) ); - } - - // set hardware parameters - SetHWParams ( rhandle, iBufferSizeIn, iCurPeriodSizeIn ); - - // start record - snd_pcm_reset ( rhandle ); - snd_pcm_start ( rhandle ); - - qDebug ( "alsa init record done" ); -} - -bool CSound::Read ( CVector& psData ) -{ - int ret; - - // check if device must be opened or reinitialized - if ( bChangParamIn == true ) - { - InitRecording(); - - // reset flag - bChangParamIn = false; - } - - ret = snd_pcm_readi ( rhandle, &psData[0], iBufferSizeIn ); - - if ( ret < 0 ) - { - if ( ret == -EPIPE ) - { - // under-run - qDebug ( "rprepare" ); - - ret = snd_pcm_prepare ( rhandle ); - - if ( ret < 0 ) - { - qDebug ( "Can't recover from underrun, prepare failed: %s", snd_strerror ( ret ) ); - } - - ret = snd_pcm_start ( rhandle ); - - if ( ret < 0 ) - { - qDebug ( "Can't recover from underrun, start failed: %s", snd_strerror ( ret ) ); - } - - return true; - - } - else if ( ret == -ESTRPIPE ) - { - qDebug ( "strpipe" ); - - // wait until the suspend flag is released - while ( ( ret = snd_pcm_resume ( rhandle ) ) == -EAGAIN ) - { - sleep ( 1 ); - } - - if ( ret < 0 ) - { - ret = snd_pcm_prepare ( rhandle ); - - if ( ret < 0 ) - { - qDebug ( "Can't recover from suspend, prepare failed: %s", snd_strerror ( ret ) ); - } - throw CGenErr ( "CSound:Read" ); - } - - return true; - } - else - { - qDebug ( "CSound::Read: %s", snd_strerror ( ret ) ); - throw CGenErr ( "CSound:Read" ); - } - } - else - { - return false; - } -} - - -// Wave out ******************************************************************** -void CSound::InitPlayback() -{ - int err; - - // if playback device was already open, close it first - if ( phandle != NULL ) - { - snd_pcm_close ( phandle ); - } - - // playback device (either "hw:0,0" or "plughw:0,0") - if ( err = snd_pcm_open ( &phandle, "hw:0,0", - SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) != 0 ) - { - qDebug ( "open error: %s", snd_strerror ( err ) ); - } - - // non-blocking playback - if ( err = snd_pcm_nonblock ( phandle, TRUE ) != 0 ) - { - qDebug ( "cannot set blocking: %s", snd_strerror ( err ) ); - } - - // set hardware parameters - SetHWParams ( phandle, iBufferSizeOut, iCurPeriodSizeOut ); - - // start playback - snd_pcm_start ( phandle ); - - qDebug ( "alsa init playback done" ); -} - -bool CSound::Write ( CVector& psData ) -{ - int size = iBufferSizeOut; - int start = 0; - int ret; - - // check if device must be opened or reinitialized - if ( bChangParamOut == true ) - { - InitPlayback(); - - // reset flag - bChangParamOut = false; - } - - while ( size ) - { - ret = snd_pcm_writei ( phandle, &psData[start], size ); - - if ( ret < 0 ) - { - if ( ret == -EPIPE ) - { - // under-run - qDebug ( "wunderrun" ); - - ret = snd_pcm_prepare ( phandle ); - - if ( ret < 0 ) - { - qDebug ( "Can't recover from underrun, prepare failed: %s", snd_strerror ( ret ) ); - } - continue; - } - else if ( ret == -EAGAIN ) - { - if ( ( ret = snd_pcm_wait ( phandle, 1000 ) ) < 0 ) - { - qDebug ( "poll failed (%s)", snd_strerror ( ret ) ); - break; - } - continue; - } - else if ( ret == -ESTRPIPE ) - { - qDebug ( "wstrpipe" ); - - // wait until the suspend flag is released - while ( ( ret = snd_pcm_resume ( phandle ) ) == -EAGAIN ) - { - sleep ( 1 ); - } - - if ( ret < 0 ) - { - ret = snd_pcm_prepare ( phandle ); - - if ( ret < 0 ) - { - qDebug ( "Can't recover from suspend, prepare failed: %s", snd_strerror ( ret ) ); - } - } - continue; - } - else - { - qDebug ( "Write error: %s", snd_strerror ( ret ) ); - } - break; // skip one period - } - - if ( ret > 0 ) - { - size -= ret; - start += ret; - } - } - - return false; -} - - -// Common *********************************************************************** -bool CSound::SetHWParams ( snd_pcm_t* handle, const int iDesiredBufferSize, - const int iNumPeriodBlocks ) -{ - int err; - snd_pcm_hw_params_t* hwparams; - - // allocate an invalid snd_pcm_hw_params_t using standard malloc - if ( err = snd_pcm_hw_params_malloc ( &hwparams ) < 0 ) - { - qDebug ( "cannot allocate hardware parameter structure (%s)\n", snd_strerror ( err ) ); - return true; - } - - // fill params with a full configuration space for a PCM - if ( err = snd_pcm_hw_params_any ( handle, hwparams ) < 0 ) - { - qDebug ( "cannot initialize hardware parameter structure (%s)\n", snd_strerror ( err ) ); - return true; - } - - // restrict a configuration space to contain only one access type: - // set the interleaved read/write format - if ( err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED ) < 0 ) - { - qDebug ( "Access type not available : %s", snd_strerror ( err ) ); - return true; - } - - // restrict a configuration space to contain only one format: - // set the sample format PCM, 16 bit - if ( err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_S16 ) < 0 ) - { - qDebug ( "Sample format not available : %s", snd_strerror ( err ) ); - return true; - } - - // restrict a configuration space to contain only one channels count: - // set the count of channels (usually stereo, 2 channels) - if ( err = snd_pcm_hw_params_set_channels ( handle, hwparams, NUM_IN_OUT_CHANNELS ) < 0 ) - { - qDebug ( "Channels count (%i) not available s: %s", NUM_IN_OUT_CHANNELS, snd_strerror ( err ) ); - return true; - } - - // restrict a configuration space to have rate nearest to a target: - // set the sample-rate - unsigned int rrate = SYSTEM_SAMPLE_RATE; - if ( err = snd_pcm_hw_params_set_rate_near ( handle, hwparams, &rrate, 0 ) < 0 ) - { - qDebug ( "Rate %iHz not available : %s", rrate, snd_strerror ( err ) ); - return true; - } - if ( rrate != SYSTEM_SAMPLE_RATE ) // check if rate is possible - { - qDebug ( "Rate doesn't match (requested %iHz, get %iHz)", rrate, err ); - return true; - } - - // set the period size - snd_pcm_uframes_t PeriodSize = iDesiredBufferSize; - if ( err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &PeriodSize, 0 ) < 0 ) - { - qDebug ( "cannot set period size (%s)\n", snd_strerror ( err ) ); - return true; - } - - // set the buffer size and period size - snd_pcm_uframes_t BufferFrames = iDesiredBufferSize * iNumPeriodBlocks; - if ( err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &BufferFrames ) < 0 ) - { - qDebug ( "cannot set buffer size (%s)\n", snd_strerror ( err ) ); - return true; - } - -// check period and buffer size -snd_pcm_uframes_t period_size; -err = snd_pcm_hw_params_get_period_size ( hwparams, &period_size, 0 ); -if ( err < 0 ) -{ - qDebug ( "Unable to get period size: %s\n", snd_strerror ( err ) ); -} -qDebug ( "frame size: %d (desired: %d)", (int) period_size, iDesiredBufferSize ); - -snd_pcm_uframes_t buffer_size; -if ( err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size ) < 0 ) -{ - qDebug ( "Unable to get buffer size: %s\n", snd_strerror ( err ) ); -} -qDebug ( "buffer size: %d (desired: %d)", (int) buffer_size, iDesiredBufferSize * iNumPeriodBlocks ); - - - - // write the parameters to device - if ( err = snd_pcm_hw_params ( handle, hwparams ) < 0 ) - { - qDebug("Unable to set hw params : %s", snd_strerror(err)); - return true; - } - - // clean-up - snd_pcm_hw_params_free ( hwparams ); - - return false; -} - -void CSound::Close() -{ - // read - if ( rhandle != NULL ) - { - snd_pcm_close ( rhandle ); - } - - rhandle = NULL; - - // playback - if ( phandle != NULL ) - { - snd_pcm_close ( phandle ); - } - - phandle = NULL; -} -# endif // USE_JACK #endif // WITH_SOUND diff --git a/linux/sound.h b/linux/sound.h index 93b635c4..02342da5 100755 --- a/linux/sound.h +++ b/linux/sound.h @@ -2,11 +2,7 @@ * Copyright (c) 2004-2009 * * Author(s): - * Volker Fischer, Alexander Kurpiers - * - * This code is based on the Open-Source sound interface implementation of - * the Dream DRM Receiver project. - * + * Volker Fischer \******************************************************************************/ #if !defined(_SOUND_H__9518A621345F78_3634567_8C0D_EEBF182CF549__INCLUDED_) @@ -25,13 +21,7 @@ #include "global.h" #if WITH_SOUND -# if USE_JACK -# include -# else -# define ALSA_PCM_NEW_HW_PARAMS_API -# define ALSA_PCM_NEW_SW_PARAMS_API -# include -# endif +# include #endif @@ -48,7 +38,6 @@ /* Classes ********************************************************************/ #if WITH_SOUND -# if USE_JACK class CSound : public CSoundBase { public: @@ -82,64 +71,11 @@ protected: void CloseJack(); // callbacks - static int process ( jack_nframes_t nframes, void* arg ); - static int bufferSizeCallback ( jack_nframes_t nframes, void *arg ); - static void shutdownCallback ( void *arg ); - jack_client_t* pJackClient; + static int process ( jack_nframes_t nframes, void* arg ); + static int bufferSizeCallback ( jack_nframes_t nframes, void *arg ); + static void shutdownCallback ( void *arg ); + jack_client_t* pJackClient; }; -# else -class CSound : public CSoundBase -{ -public: - CSound ( void (*fpNewProcessCallback) ( CVector& psData, void* pParg ), void* pParg ) : - CSoundBase ( false, fpNewProcessCallback, pParg ), rhandle ( NULL ), - phandle ( NULL ), iCurPeriodSizeIn ( NUM_PERIOD_BLOCKS_IN ), - iCurPeriodSizeOut ( NUM_PERIOD_BLOCKS_OUT ), bChangParamIn ( true ), - bChangParamOut ( true ) {} - virtual ~CSound() { Close(); } - - // not implemented yet, always return one device and default string - int GetNumDev() { return 1; } - std::string GetDeviceName ( const int iDiD ) { return "wave mapper"; } - std::string SetDev ( const int iNewDev ) { return ""; } // dummy - int GetDev() { return 0; } - - virtual int Init ( const int iNewPrefMonoBufferSize ) - { - // init base class - CSoundBase::Init ( iNewPrefMonoBufferSize ); - - // set internal buffer size for read and write - iBufferSizeIn = iNewPrefMonoBufferSize; - iBufferSizeOut = iNewPrefMonoBufferSize; - - InitRecording(); - InitPlayback(); - - return iNewPrefMonoBufferSize; - } - virtual bool Read ( CVector& psData ); - virtual bool Write ( CVector& psData ); - -protected: - void Close(); - void InitRecording(); - void InitPlayback(); - - snd_pcm_t* rhandle; - snd_pcm_t* phandle; - - bool SetHWParams ( snd_pcm_t* handle, const int iBufferSizeIn, - const int iNumPeriodBlocks ); - - int iBufferSizeOut; - int iBufferSizeIn; - bool bChangParamIn; - int iCurPeriodSizeIn; - bool bChangParamOut; - int iCurPeriodSizeOut; -}; -# endif // USE_JACK #else // no sound -> dummy class definition class CSound : public CSoundBase diff --git a/src/main.cpp b/src/main.cpp index 2d423fbd..ccb3031f 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include "global.h" #include "llconclientdlg.h" @@ -166,13 +167,19 @@ int main ( int argc, char** argv ) exit ( 1 ); } + // Application object + QApplication app ( argc, argv, bUseGUI ); + #ifdef _WIN32 // Set application priority class -> high priority SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS ); -#endif - // Application object - QApplication app ( argc, argv, bUseGUI ); + // For accessible support we need to add a plugin to qt. The plugin has to + // be located in the install directory of llcon by the installer. Here, we + // set the path to our application + QDir ApplDir ( QApplication::applicationDirPath() ); + app.addLibraryPath ( QString ( ApplDir.absolutePath() ) ); +#endif // init resources extern int qInitResources(); diff --git a/windows/installer.nsi b/windows/installer.nsi index 23624cd9..bbb8d886 100755 --- a/windows/installer.nsi +++ b/windows/installer.nsi @@ -4,8 +4,8 @@ !define APP_EXE "llcon.exe" !define UNINSTALL_EXE "Uninstall.exe" !define INSTALLER_NAME "llconinstaller.exe" -;!define VS_REDIST_PATH "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86\" -!define VS_REDIST_PATH "C:\Programme\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86\" +!define VS_REDIST_PATH "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86\" +;!define VS_REDIST_PATH "C:\Programme\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86\" !define VS_REDIST_EXE "vcredist_x86.exe" !define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" @@ -62,6 +62,10 @@ Section ; cleanup: remove temporary Microsoft Visual Studio redistributable executable Delete $INSTDIR\${VS_REDIST_EXE} + ; accessible qt plugin + SetOutPath $INSTDIR\accessible + File "$%QTDIR%\plugins\accessible\qtaccessiblewidgets4.dll" + SectionEnd @@ -82,6 +86,8 @@ Delete $INSTDIR\QtGui4.dll Delete $INSTDIR\QtNetwork4.dll Delete $INSTDIR\QtXml4.dll Delete $INSTDIR\COPYING +Delete $INSTDIR\accessible\qtaccessiblewidgets4.dll +RMDir $INSTDIR\accessible RMDir $INSTDIR SectionEnd diff --git a/windows/sound.h b/windows/sound.h index cc2feaa0..4448bdda 100755 --- a/windows/sound.h +++ b/windows/sound.h @@ -70,10 +70,11 @@ public: std::string SetDev ( const int iNewDev ); int GetDev() { return lCurDev; } + int GetActualBufferSize ( const int iDesiredBufferSizeMono ); + protected: bool LoadAndInitializeFirstValidDriver(); std::string LoadAndInitializeDriver ( int iIdx ); - int GetActualBufferSize ( const int iDesiredBufferSizeMono ); std::string CheckDeviceCapabilities(); // audio hardware buffer info