- removed ALSA support, - added accessibility plugin

This commit is contained in:
Volker Fischer 2009-11-29 12:05:19 +00:00
parent 682c2e5877
commit cb951c92c2
7 changed files with 38 additions and 453 deletions

View file

@ -1,6 +1,6 @@
3.0.3 3.0.3
- accessibility improvements - accessibility improvements
- show number of connected clients in window title (and therefore in OS task - show number of connected clients in window title (and therefore in OS task
bar) bar)
@ -10,11 +10,14 @@
- server logging history grid lines of weekend days are now plotted with - server logging history grid lines of weekend days are now plotted with
different line width different line width
- bug fix: fix for disconnect issue at the server - bug fix: fix for disconnect issue at the server
- added "Whats this" help text to the GUI controls in the general settings - added "Whats this" help text to the GUI controls in the general settings
dialog dialog
- removed ALSA support since the ALSA interface implementation in llcon was
buggy and will not be maintained in the future
3.0.2 3.0.2

View file

@ -19,14 +19,10 @@ AC_PROG_MAKE_SET
dnl Configuration Arguments dnl Configuration Arguments
AC_ARG_ENABLE( sound,[ --enable-sound generic sound support], enable_sound=$enableval, enable_sound=yes) 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 Check for Jack
dnl checks for ALSA audio if test "$enable_sound" = "yes"; then
AC_CHECK_HEADER(sys/asoundlib.h, , enable_sound=no)
AC_CHECK_LIB(asound, snd_pcm_open, , enable_sound=no)
else
dnl checks for JACK audio dnl checks for JACK audio
AC_CHECK_HEADER([jack/jack.h], have_jack=yes, have_jack=no, [ AC_CHECK_HEADER([jack/jack.h], have_jack=yes, have_jack=no, [
]) ])
@ -36,14 +32,10 @@ else
JACK_LIB="-ljack" JACK_LIB="-ljack"
AC_DEFINE(USE_JACK, 1,[Define to enable JACK input module]) AC_DEFINE(USE_JACK, 1,[Define to enable JACK input module])
fi fi
fi
if test "$enable_sound" = "yes"; then
AC_DEFINE(WITH_SOUND, 1, [Define if you want to use sound]) AC_DEFINE(WITH_SOUND, 1, [Define if you want to use sound])
fi fi
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_LANG_CPLUSPLUS AC_LANG_CPLUSPLUS

View file

@ -2,18 +2,14 @@
* Copyright (c) 2004-2009 * Copyright (c) 2004-2009
* *
* Author(s): * Author(s):
* Volker Fischer, Alexander Kurpiers * Volker Fischer
*
* 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.
* *
* This code is based on the simple_client example of the Jack audio interface.
\******************************************************************************/ \******************************************************************************/
#include "sound.h" #include "sound.h"
#ifdef WITH_SOUND #ifdef WITH_SOUND
# if USE_JACK
void CSound::OpenJack() void CSound::OpenJack()
{ {
jack_status_t JackStatus; jack_status_t JackStatus;
@ -244,360 +240,4 @@ void CSound::shutdownCallback ( void *arg )
// error message // error message
throw CGenErr ( "Jack server was shut down" ); 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<short>& 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<short>& 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 #endif // WITH_SOUND

View file

@ -2,11 +2,7 @@
* Copyright (c) 2004-2009 * Copyright (c) 2004-2009
* *
* Author(s): * Author(s):
* Volker Fischer, Alexander Kurpiers * Volker Fischer
*
* This code is based on the Open-Source sound interface implementation of
* the Dream DRM Receiver project.
*
\******************************************************************************/ \******************************************************************************/
#if !defined(_SOUND_H__9518A621345F78_3634567_8C0D_EEBF182CF549__INCLUDED_) #if !defined(_SOUND_H__9518A621345F78_3634567_8C0D_EEBF182CF549__INCLUDED_)
@ -25,13 +21,7 @@
#include "global.h" #include "global.h"
#if WITH_SOUND #if WITH_SOUND
# if USE_JACK # include <jack/jack.h>
# include <jack/jack.h>
# else
# define ALSA_PCM_NEW_HW_PARAMS_API
# define ALSA_PCM_NEW_SW_PARAMS_API
# include <alsa/asoundlib.h>
# endif
#endif #endif
@ -48,7 +38,6 @@
/* Classes ********************************************************************/ /* Classes ********************************************************************/
#if WITH_SOUND #if WITH_SOUND
# if USE_JACK
class CSound : public CSoundBase class CSound : public CSoundBase
{ {
public: public:
@ -82,64 +71,11 @@ protected:
void CloseJack(); void CloseJack();
// callbacks // callbacks
static int process ( jack_nframes_t nframes, void* arg ); static int process ( jack_nframes_t nframes, void* arg );
static int bufferSizeCallback ( jack_nframes_t nframes, void *arg ); static int bufferSizeCallback ( jack_nframes_t nframes, void *arg );
static void shutdownCallback ( void *arg ); static void shutdownCallback ( void *arg );
jack_client_t* pJackClient; jack_client_t* pJackClient;
}; };
# else
class CSound : public CSoundBase
{
public:
CSound ( void (*fpNewProcessCallback) ( CVector<short>& 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<short>& psData );
virtual bool Write ( CVector<short>& 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 #else
// no sound -> dummy class definition // no sound -> dummy class definition
class CSound : public CSoundBase class CSound : public CSoundBase

View file

@ -24,6 +24,7 @@
#include <qapplication.h> #include <qapplication.h>
#include <qmessagebox.h> #include <qmessagebox.h>
#include <qdir.h>
#include <iostream> #include <iostream>
#include "global.h" #include "global.h"
#include "llconclientdlg.h" #include "llconclientdlg.h"
@ -166,13 +167,19 @@ int main ( int argc, char** argv )
exit ( 1 ); exit ( 1 );
} }
// Application object
QApplication app ( argc, argv, bUseGUI );
#ifdef _WIN32 #ifdef _WIN32
// Set application priority class -> high priority // Set application priority class -> high priority
SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS ); SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS );
#endif
// Application object // For accessible support we need to add a plugin to qt. The plugin has to
QApplication app ( argc, argv, bUseGUI ); // 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 // init resources
extern int qInitResources(); extern int qInitResources();

View file

@ -4,8 +4,8 @@
!define APP_EXE "llcon.exe" !define APP_EXE "llcon.exe"
!define UNINSTALL_EXE "Uninstall.exe" !define UNINSTALL_EXE "Uninstall.exe"
!define INSTALLER_NAME "llconinstaller.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:\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:\Programme\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86\"
!define VS_REDIST_EXE "vcredist_x86.exe" !define VS_REDIST_EXE "vcredist_x86.exe"
!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" !define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
@ -62,6 +62,10 @@ Section
; cleanup: remove temporary Microsoft Visual Studio redistributable executable ; cleanup: remove temporary Microsoft Visual Studio redistributable executable
Delete $INSTDIR\${VS_REDIST_EXE} Delete $INSTDIR\${VS_REDIST_EXE}
; accessible qt plugin
SetOutPath $INSTDIR\accessible
File "$%QTDIR%\plugins\accessible\qtaccessiblewidgets4.dll"
SectionEnd SectionEnd
@ -82,6 +86,8 @@ Delete $INSTDIR\QtGui4.dll
Delete $INSTDIR\QtNetwork4.dll Delete $INSTDIR\QtNetwork4.dll
Delete $INSTDIR\QtXml4.dll Delete $INSTDIR\QtXml4.dll
Delete $INSTDIR\COPYING Delete $INSTDIR\COPYING
Delete $INSTDIR\accessible\qtaccessiblewidgets4.dll
RMDir $INSTDIR\accessible
RMDir $INSTDIR RMDir $INSTDIR
SectionEnd SectionEnd

View file

@ -70,10 +70,11 @@ public:
std::string SetDev ( const int iNewDev ); std::string SetDev ( const int iNewDev );
int GetDev() { return lCurDev; } int GetDev() { return lCurDev; }
int GetActualBufferSize ( const int iDesiredBufferSizeMono );
protected: protected:
bool LoadAndInitializeFirstValidDriver(); bool LoadAndInitializeFirstValidDriver();
std::string LoadAndInitializeDriver ( int iIdx ); std::string LoadAndInitializeDriver ( int iIdx );
int GetActualBufferSize ( const int iDesiredBufferSizeMono );
std::string CheckDeviceCapabilities(); std::string CheckDeviceCapabilities();
// audio hardware buffer info // audio hardware buffer info