commited changes to enable Jack support
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
This commit is contained in:
parent
806550e495
commit
09e7e0ab53
|
@ -22,4 +22,5 @@ with contributions by:
|
||||||
Robert Lunnon <bobl@optushome.com.au>
|
Robert Lunnon <bobl@optushome.com.au>
|
||||||
Enrico Ardizzoni <craken@users.sourceforge.net>
|
Enrico Ardizzoni <craken@users.sourceforge.net>
|
||||||
Deti Fliegl <deti@fliegl.de>
|
Deti Fliegl <deti@fliegl.de>
|
||||||
|
Nicholas J. Humfrey <njh@ecs.soton.ac.uk>
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@ DarkIce next release
|
||||||
since it is not implemented in OpenBSD / NetBSD
|
since it is not implemented in OpenBSD / NetBSD
|
||||||
o added possibility to downsample from stereo to mono when encoding
|
o added possibility to downsample from stereo to mono when encoding
|
||||||
to Ogg Vorbis, thanks to Deti Fliegl, <deti@fliegl.de>
|
to Ogg Vorbis, thanks to Deti Fliegl, <deti@fliegl.de>
|
||||||
|
o added support for Jack inputs, enabling a lot of interesting usage,
|
||||||
|
including support for MacOS X.
|
||||||
|
Thanks to Nicholas J. Humfrey <njh@ecs.soton.ac.uk>
|
||||||
|
|
||||||
15-02-2004: DarkIce 0.14 released
|
15-02-2004: DarkIce 0.14 released
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
AC_INIT(src/DarkIce.cpp)
|
AC_INIT(darkice, 0.15beta)
|
||||||
AM_INIT_AUTOMAKE(darkice, 0.15beta)
|
AC_CONFIG_SRCDIR(src/DarkIce.cpp)
|
||||||
|
AM_CONFIG_HEADER(src/config.h)
|
||||||
|
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_INIT_AUTOMAKE
|
||||||
|
|
||||||
|
AC_PROG_CC
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
|
@ -155,6 +157,24 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl-----------------------------------------------------------------------------
|
||||||
|
dnl link JACK sound server if requested
|
||||||
|
dnl-----------------------------------------------------------------------------
|
||||||
|
AC_SUBST(JACK_CFLAGS)
|
||||||
|
AC_SUBST(JACK_LIBS)
|
||||||
|
AC_ARG_WITH( jack,
|
||||||
|
[ --with-jack use JACK audio server [yes] ],
|
||||||
|
USE_JACK=${withval}, USE_JACK="yes" )
|
||||||
|
|
||||||
|
if test "x${USE_JACK}" = "xyes" ; then
|
||||||
|
PKG_CHECK_MODULES(JACK, jack,
|
||||||
|
AC_DEFINE( HAVE_JACK_LIB, 1, [build with JACK audio server support] )
|
||||||
|
)
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT( [building without JACK support] )
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
dnl-----------------------------------------------------------------------------
|
||||||
dnl check for MSG_NOSIGNAL for the send() function in libsocket
|
dnl check for MSG_NOSIGNAL for the send() function in libsocket
|
||||||
dnl-----------------------------------------------------------------------------
|
dnl-----------------------------------------------------------------------------
|
||||||
|
@ -171,6 +191,12 @@ AC_TRY_COMPILE([#include <sys/socket.h>], [
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl-----------------------------------------------------------------------------
|
||||||
|
dnl check for POSIX real-time scheduling
|
||||||
|
dnl-----------------------------------------------------------------------------
|
||||||
|
AC_CHECK_FUNCS( sched_getscheduler sched_getparam )
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
dnl-----------------------------------------------------------------------------
|
||||||
dnl enable compilation with debug flags
|
dnl enable compilation with debug flags
|
||||||
dnl-----------------------------------------------------------------------------
|
dnl-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -90,6 +90,7 @@ Developed with contributions by
|
||||||
Robert Lunnon <bobl@optushome.com.au>
|
Robert Lunnon <bobl@optushome.com.au>
|
||||||
Enrico Ardizzoni <craken@users.sourceforge.net>
|
Enrico Ardizzoni <craken@users.sourceforge.net>
|
||||||
Deti Fliegl <deti@fliegl.de>
|
Deti Fliegl <deti@fliegl.de>
|
||||||
|
Nicholas J. Humfrey <njh@ecs.soton.ac.uk>
|
||||||
|
|
||||||
.SH LINKS
|
.SH LINKS
|
||||||
Project homepage:
|
Project homepage:
|
||||||
|
|
|
@ -60,8 +60,12 @@ Required values:
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.I device
|
.I device
|
||||||
OSS DSP audio device to record from (e.g. /dev/dsp) or ALSA DSP device name
|
Specify the device to record from, which can be an OSS DSP device,
|
||||||
(e.g. hwplug:0,0)
|
an ALSA source or you can use Jack audio.
|
||||||
|
- OSS DSP audio device to record from (e.g. /dev/dsp)
|
||||||
|
- ALSA DSP device name (e.g. hwplug:0,0)
|
||||||
|
- the string 'jack', to have an unconnected Jack port, or
|
||||||
|
'jack_auto' to automatically make Jack connect to the first source.
|
||||||
.TP
|
.TP
|
||||||
.I sampleRate
|
.I sampleRate
|
||||||
The sample rate to record with, samples per second
|
The sample rate to record with, samples per second
|
||||||
|
|
|
@ -260,7 +260,7 @@ AlsaDspSource :: read ( void * buf,
|
||||||
} while (ret == -EAGAIN);
|
} while (ret == -EAGAIN);
|
||||||
|
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
throw new Exception(__FILE__, __LINE__, snd_strerror(ret));
|
throw Exception(__FILE__, __LINE__, snd_strerror(ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
|
@ -292,6 +292,10 @@ AlsaDspSource :: close ( void ) throw ( Exception )
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.4 2005/04/04 08:36:16 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
Revision 1.3 2005/04/03 05:00:14 jbebel
|
Revision 1.3 2005/04/03 05:00:14 jbebel
|
||||||
Fixing code documentation of buffer overruns
|
Fixing code documentation of buffer overruns
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ AudioSource :: createDspSource( const char * deviceName,
|
||||||
int channel)
|
int channel)
|
||||||
throw ( Exception )
|
throw ( Exception )
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( Util::strEq( deviceName, "/dev", 4) ) {
|
if ( Util::strEq( deviceName, "/dev", 4) ) {
|
||||||
#if defined( SUPPORT_OSS_DSP )
|
#if defined( SUPPORT_OSS_DSP )
|
||||||
Reporter::reportEvent( 1, "Using OSS DSP input device:", deviceName);
|
Reporter::reportEvent( 1, "Using OSS DSP input device:", deviceName);
|
||||||
|
@ -79,9 +80,21 @@ AudioSource :: createDspSource( const char * deviceName,
|
||||||
bitsPerSample,
|
bitsPerSample,
|
||||||
channel);
|
channel);
|
||||||
#else
|
#else
|
||||||
throw new Exception( __FILE__, __LINE__,
|
throw Exception( __FILE__, __LINE__,
|
||||||
"trying to open OSS or Solaris DSP device "
|
"trying to open OSS or Solaris DSP device "
|
||||||
"without support compiled", deviceName);
|
"without support compiled", deviceName);
|
||||||
|
#endif
|
||||||
|
} else if ( Util::strEq( deviceName, "jack", 4) ) {
|
||||||
|
#if defined( SUPPORT_JACK_DSP )
|
||||||
|
Reporter::reportEvent( 1, "Using JACK audio server as input device.");
|
||||||
|
return new JackDspSource( deviceName,
|
||||||
|
sampleRate,
|
||||||
|
bitsPerSample,
|
||||||
|
channel);
|
||||||
|
#else
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"trying to open JACK device without "
|
||||||
|
"support compiled", deviceName);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if defined( SUPPORT_ALSA_DSP )
|
#if defined( SUPPORT_ALSA_DSP )
|
||||||
|
@ -91,7 +104,7 @@ AudioSource :: createDspSource( const char * deviceName,
|
||||||
bitsPerSample,
|
bitsPerSample,
|
||||||
channel);
|
channel);
|
||||||
#else
|
#else
|
||||||
throw new Exception( __FILE__, __LINE__,
|
throw Exception( __FILE__, __LINE__,
|
||||||
"trying to open ALSA DSP device without "
|
"trying to open ALSA DSP device without "
|
||||||
"support compiled", deviceName);
|
"support compiled", deviceName);
|
||||||
#endif
|
#endif
|
||||||
|
@ -104,6 +117,10 @@ AudioSource :: createDspSource( const char * deviceName,
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.3 2005/04/04 08:36:16 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
Revision 1.2 2004/02/15 22:26:16 darkeye
|
Revision 1.2 2004/02/15 22:26:16 darkeye
|
||||||
fixed typo, minimal cosmetic change
|
fixed typo, minimal cosmetic change
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
#error This is a C++ include file
|
#error This is a C++ include file
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ============================================================ include files */
|
/* ============================================================ include files */
|
||||||
|
|
||||||
|
@ -50,21 +53,27 @@
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined( HAVE_ALSA_LIB )
|
#if defined( HAVE_ALSA_LIB )
|
||||||
// we have an ALSA sound system available
|
// we have an ALSA sound system available
|
||||||
#define SUPPORT_ALSA_DSP
|
#define SUPPORT_ALSA_DSP 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined( HAVE_SYS_SOUNDCARD_H )
|
#if defined( HAVE_SYS_SOUNDCARD_H )
|
||||||
// we have an OSS DSP sound source device available
|
// we have an OSS DSP sound source device available
|
||||||
#define SUPPORT_OSS_DSP
|
#define SUPPORT_OSS_DSP 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined( HAVE_SYS_AUDIO_H ) || defined( HAVE_SYS_AUDIOIO_H )
|
#if defined( HAVE_SYS_AUDIO_H ) || defined( HAVE_SYS_AUDIOIO_H )
|
||||||
// we have a Solaris DSP sound device available (same for OpenBSD)
|
// we have a Solaris DSP sound device available (same for OpenBSD)
|
||||||
#define SUPPORT_SOLARIS_DSP
|
#define SUPPORT_SOLARIS_DSP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( HAVE_JACK_LIB )
|
||||||
|
// we have JACK audio server
|
||||||
|
#define SUPPORT_JACK_DSP 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined( SUPPORT_ALSA_DSP ) \
|
#if !defined( SUPPORT_ALSA_DSP ) \
|
||||||
&& !defined( SUPPORT_OSS_DSP ) \
|
&& !defined( SUPPORT_OSS_DSP ) \
|
||||||
|
&& !defined( SUPPORT_JACK_DSP ) \
|
||||||
&& !defined( SUPPORT_SOLARIS_DSP )
|
&& !defined( SUPPORT_SOLARIS_DSP )
|
||||||
// there was no DSP audio system found
|
// there was no DSP audio system found
|
||||||
#error No DSP audio input device found on system
|
#error No DSP audio input device found on system
|
||||||
|
@ -212,7 +221,14 @@ class AudioSource : public Source, public virtual Reporter
|
||||||
* @return true if the data is big endian, false if little endian
|
* @return true if the data is big endian, false if little endian
|
||||||
*/
|
*/
|
||||||
virtual bool
|
virtual bool
|
||||||
isBigEndian ( void ) const throw () = 0;
|
isBigEndian ( void ) const throw ()
|
||||||
|
{
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the sample rate per seconds for this AudioSource.
|
* Get the sample rate per seconds for this AudioSource.
|
||||||
|
@ -275,6 +291,9 @@ class AudioSource : public Source, public virtual Reporter
|
||||||
#include "SolarisDspSource.h"
|
#include "SolarisDspSource.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined( SUPPORT_JACK_DSP )
|
||||||
|
#include "JackDspSource.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
/* ====================================================== function prototypes */
|
||||||
|
|
||||||
|
@ -288,6 +307,10 @@ class AudioSource : public Source, public virtual Reporter
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.8 2005/04/04 08:36:16 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
Revision 1.7 2004/02/18 21:08:11 darkeye
|
Revision 1.7 2004/02/18 21:08:11 darkeye
|
||||||
ported to OpenBSD (real-time scheduling not yet supported)
|
ported to OpenBSD (real-time scheduling not yet supported)
|
||||||
|
|
||||||
|
|
|
@ -873,9 +873,8 @@ DarkIce :: configFileCast ( const Config & config )
|
||||||
void
|
void
|
||||||
DarkIce :: setRealTimeScheduling ( void ) throw ( Exception )
|
DarkIce :: setRealTimeScheduling ( void ) throw ( Exception )
|
||||||
{
|
{
|
||||||
// don't include the following on OpenBSD / NetBSD, as the scheduling
|
// Only if the OS has the POSIX real-time scheduling functions implemented.
|
||||||
// functions are not implemented.
|
#if defined( HAVE_SCHED_GETSCHEDULER ) && defined( HAVE_SCHED_GETPARAM )
|
||||||
#if !defined( __OpenBSD__ ) && !defined( __NetBSD__ )
|
|
||||||
uid_t euid;
|
uid_t euid;
|
||||||
|
|
||||||
euid = geteuid();
|
euid = geteuid();
|
||||||
|
@ -921,9 +920,9 @@ DarkIce :: setRealTimeScheduling ( void ) throw ( Exception )
|
||||||
"It is recommended that you run this program as super-user");
|
"It is recommended that you run this program as super-user");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
reportEvent( 1, "POSIX scheduling not supported on OpenBSD / NetBSD, "
|
reportEvent( 1, "POSIX scheduling not supported on this system, "
|
||||||
"this may cause recording skips");
|
"this may cause recording skips");
|
||||||
#endif // !__OpenBSD__ && !__NetBSD__
|
#endif // HAVE_SCHED_GETSCHEDULER && HAVE_SCHED_GETPARAM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -935,9 +934,8 @@ DarkIce :: setRealTimeScheduling ( void ) throw ( Exception )
|
||||||
void
|
void
|
||||||
DarkIce :: setOriginalScheduling ( void ) throw ( Exception )
|
DarkIce :: setOriginalScheduling ( void ) throw ( Exception )
|
||||||
{
|
{
|
||||||
// don't include the following on OpenBSD / NetBSD, as the scheduling
|
// Only if the OS has the POSIX real-time scheduling functions implemented.
|
||||||
// functions are not implemented.
|
#if defined( HAVE_SCHED_GETSCHEDULER ) && defined( HAVE_SCHED_GETPARAM )
|
||||||
#if !defined( __OpenBSD__ ) && !defined( __NetBSD__ )
|
|
||||||
uid_t euid;
|
uid_t euid;
|
||||||
|
|
||||||
euid = geteuid();
|
euid = geteuid();
|
||||||
|
@ -957,7 +955,7 @@ DarkIce :: setOriginalScheduling ( void ) throw ( Exception )
|
||||||
|
|
||||||
reportEvent( 5, "reverted to original scheduling");
|
reportEvent( 5, "reverted to original scheduling");
|
||||||
}
|
}
|
||||||
#endif // !__OpenBSD__ && !__NetBSD__
|
#endif // HAVE_SCHED_GETSCHEDULER && HAVE_SCHED_GETPARAM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1010,6 +1008,10 @@ DarkIce :: run ( void ) throw ( Exception )
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.42 2005/04/04 08:36:17 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
Revision 1.41 2005/04/03 05:12:20 jbebel
|
Revision 1.41 2005/04/03 05:12:20 jbebel
|
||||||
Changed mechanism for testing the presence of the quality value such that
|
Changed mechanism for testing the presence of the quality value such that
|
||||||
zero is a valid option.
|
zero is a valid option.
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
#include "AudioEncoder.h"
|
#include "AudioEncoder.h"
|
||||||
#include "TcpSocket.h"
|
#include "TcpSocket.h"
|
||||||
#include "CastSink.h"
|
#include "CastSink.h"
|
||||||
#include "Config.h"
|
#include "DarkIceConfig.h"
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
/* ================================================================ constants */
|
||||||
|
@ -309,6 +309,10 @@ class DarkIce : public virtual Referable, public virtual Reporter
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.15 2005/04/04 08:36:17 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
Revision 1.14 2002/05/28 12:35:41 darkeye
|
Revision 1.14 2002/05/28 12:35:41 darkeye
|
||||||
code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
|
code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
Tyrell Config
|
Tyrell Config
|
||||||
|
|
||||||
File : Config.cpp
|
File : DarkIceConfig.cpp
|
||||||
Version : $Revision$
|
Version : $Revision$
|
||||||
Author : $Author$
|
Author : $Author$
|
||||||
Location : $Source$
|
Location : $Source$
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "DarkIceConfig.h"
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
/* =================================================== local data structures */
|
||||||
|
@ -170,6 +170,10 @@ Config :: read ( std::istream & is ) throw ( Exception )
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.1 2005/04/04 08:36:17 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
Revision 1.7 2002/05/28 12:35:41 darkeye
|
Revision 1.7 2002/05/28 12:35:41 darkeye
|
||||||
code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
|
code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
Tyrell Config
|
Tyrell Config
|
||||||
|
|
||||||
File : Config.h
|
File : DarkIceConfig.h
|
||||||
Version : $Revision$
|
Version : $Revision$
|
||||||
Author : $Author$
|
Author : $Author$
|
||||||
Location : $Source$
|
Location : $Source$
|
||||||
|
@ -213,6 +213,10 @@ class Config : public virtual Referable
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.1 2005/04/04 08:36:17 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
Revision 1.5 2002/05/28 12:35:41 darkeye
|
Revision 1.5 2002/05/28 12:35:41 darkeye
|
||||||
code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
|
code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
|
||||||
|
|
|
@ -0,0 +1,454 @@
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2005 Nicholas Humfrey. All rights reserved.
|
||||||
|
|
||||||
|
Tyrell DarkIce
|
||||||
|
|
||||||
|
File : JackDspSource.cpp
|
||||||
|
Version : $Revision$
|
||||||
|
Author : $Author$
|
||||||
|
Location : $Source$
|
||||||
|
|
||||||
|
Copyright notice:
|
||||||
|
|
||||||
|
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ============================================================ include files */
|
||||||
|
|
||||||
|
#include "AudioSource.h"
|
||||||
|
|
||||||
|
#ifdef SUPPORT_JACK_DSP
|
||||||
|
// only compile this code if there is support for it
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#error need unistd.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#else
|
||||||
|
#error need string.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#else
|
||||||
|
#error need sys/types.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_MATH_H
|
||||||
|
#include <math.h>
|
||||||
|
#else
|
||||||
|
#error need math.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Util.h"
|
||||||
|
#include "Exception.h"
|
||||||
|
#include "JackDspSource.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* =================================================== local data structures */
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================ local constants & macros */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* File identity
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
static const char fileid[] = "$Id$";
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================== local function prototypes */
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================================================= module code */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Initialize the object
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
JackDspSource :: init ( const char* name ) throw ( Exception )
|
||||||
|
{
|
||||||
|
// Set defaults
|
||||||
|
ports[0] = NULL; // Left Port
|
||||||
|
ports[1] = NULL; // Right Port
|
||||||
|
rb[0] = NULL; // Left Ring Buffer
|
||||||
|
rb[1] = NULL; // Right Ring Buffer
|
||||||
|
client = NULL;
|
||||||
|
auto_connect = false; // Default is to not auto connect the JACK ports
|
||||||
|
tmp_buffer = NULL; // Buffer big enough for one 'read' of audio
|
||||||
|
|
||||||
|
// Auto connect the ports ?
|
||||||
|
if ( Util::strEq( name, "jack_auto", 9) ) {
|
||||||
|
auto_connect = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the sample size
|
||||||
|
if (getBitsPerSample() != 16) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"JackDspSource doesn't support non 16-bit samples");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* De-initialize the object
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
JackDspSource :: strip ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
if ( isOpen() ) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the temporary buffer
|
||||||
|
if (tmp_buffer) {
|
||||||
|
free(tmp_buffer);
|
||||||
|
tmp_buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Attempt to connect up the JACK ports automatically
|
||||||
|
* - Just connect left&right to the first two output ports we find
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
JackDspSource :: do_auto_connect ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
const char **all_ports;
|
||||||
|
unsigned int ch = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
Reporter::reportEvent( 10, "JackDspSource :: do_auto_connect");
|
||||||
|
|
||||||
|
// Get a list of all the jack ports
|
||||||
|
all_ports = jack_get_ports (client, NULL, NULL, JackPortIsOutput);
|
||||||
|
if (!ports) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "jack_get_ports() returned NULL.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step through each port name
|
||||||
|
for (i = 0; all_ports[i]; ++i) {
|
||||||
|
|
||||||
|
const char* in = all_ports[i];
|
||||||
|
const char* out = jack_port_name( ports[ch] );
|
||||||
|
|
||||||
|
Reporter::reportEvent( 2, "Connecting", in, "to", out);
|
||||||
|
|
||||||
|
if (jack_connect(client, in, out)) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"Failed to jack_connect() ports", in, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found enough ports ?
|
||||||
|
if (++ch >= getChannel()) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free( all_ports );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Open the audio source
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
bool
|
||||||
|
JackDspSource :: open ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
char client_name[255];
|
||||||
|
size_t rb_size;
|
||||||
|
unsigned int c;
|
||||||
|
|
||||||
|
if ( isOpen() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register client with Jack
|
||||||
|
snprintf(client_name, 255, "darkice-%d", getpid());
|
||||||
|
if ((client = jack_client_new(client_name)) == NULL) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "JACK server not running?");
|
||||||
|
}
|
||||||
|
Reporter::reportEvent( 1, "Registering as JACK client", client_name);
|
||||||
|
|
||||||
|
|
||||||
|
// Check the sample rate is correct
|
||||||
|
if (jack_get_sample_rate( client ) != (jack_nframes_t)getSampleRate()) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"JACK server sample rate is different than "
|
||||||
|
"sample rate in darkice config file");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Register ports with Jack
|
||||||
|
if (getChannel() == 1) {
|
||||||
|
if (!(ports[0] = jack_port_register(client,
|
||||||
|
"mono",
|
||||||
|
JACK_DEFAULT_AUDIO_TYPE,
|
||||||
|
JackPortIsInput,
|
||||||
|
0))) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"Cannot register input port", "mono");
|
||||||
|
}
|
||||||
|
} else if (getChannel() == 2) {
|
||||||
|
if (!(ports[0] = jack_port_register(client,
|
||||||
|
"left",
|
||||||
|
JACK_DEFAULT_AUDIO_TYPE,
|
||||||
|
JackPortIsInput,
|
||||||
|
0))) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"Cannot register input port", "left");
|
||||||
|
}
|
||||||
|
if (!(ports[1] = jack_port_register(client,
|
||||||
|
"right",
|
||||||
|
JACK_DEFAULT_AUDIO_TYPE,
|
||||||
|
JackPortIsInput, 0))) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"Cannot register input port", "right");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"Invalid number of channels", getChannel());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create a ring buffer for each channel
|
||||||
|
rb_size = 2
|
||||||
|
* jack_get_sample_rate(client)
|
||||||
|
* sizeof (jack_default_audio_sample_t);
|
||||||
|
for (c=0; c<getChannel(); c++) {
|
||||||
|
rb[c] = jack_ringbuffer_create(rb_size);
|
||||||
|
if (!rb[c]) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"Failed to create ringbuffer for", "channel", c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set the callbacks
|
||||||
|
jack_on_shutdown(client, JackDspSource::shutdown_callback, (void*)this);
|
||||||
|
if (jack_set_process_callback(client,
|
||||||
|
JackDspSource::process_callback,
|
||||||
|
(void*)this)) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "Failed to set process callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate client
|
||||||
|
if (jack_activate(client)) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "Can't activate client");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to automatically connect up our input ports to something ?
|
||||||
|
if (auto_connect) {
|
||||||
|
do_auto_connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Check wether read() would return anything
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
bool
|
||||||
|
JackDspSource :: canRead ( unsigned int sec,
|
||||||
|
unsigned int usec ) throw ( Exception )
|
||||||
|
{
|
||||||
|
size_t available=0;
|
||||||
|
|
||||||
|
if ( !isOpen() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// How many bytes available in ring buffer ?
|
||||||
|
available = jack_ringbuffer_read_space( rb[0] );
|
||||||
|
if (available) return true;
|
||||||
|
|
||||||
|
// Sleep and check again
|
||||||
|
// FIXME: should we really sleep the full duration ?
|
||||||
|
usleep( (sec*1000000) + usec );
|
||||||
|
|
||||||
|
available = jack_ringbuffer_read_space( rb[0] );
|
||||||
|
if (available) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Read from the audio source
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
unsigned int
|
||||||
|
JackDspSource :: read ( void * buf,
|
||||||
|
unsigned int len ) throw ( Exception )
|
||||||
|
{
|
||||||
|
jack_nframes_t samples = len / 2 / getChannel();
|
||||||
|
jack_nframes_t samples_read[2] = {0,0};
|
||||||
|
short * output = (short*)buf;
|
||||||
|
unsigned int c, n;
|
||||||
|
|
||||||
|
if ( !isOpen() ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Ensure the temporary buffer is big enough
|
||||||
|
tmp_buffer = (jack_default_audio_sample_t*)realloc(tmp_buffer,
|
||||||
|
samples * sizeof( jack_default_audio_sample_t ) );
|
||||||
|
if (!tmp_buffer) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "realloc on tmp_buffer failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (c=0; c<getChannel(); c++)
|
||||||
|
{
|
||||||
|
// Copy frames from ring buffer to temporary buffer
|
||||||
|
// and then convert samples to output buffer
|
||||||
|
int bytes_read = jack_ringbuffer_read(rb[c],
|
||||||
|
(char*)tmp_buffer,
|
||||||
|
samples * sizeof( jack_default_audio_sample_t ));
|
||||||
|
samples_read[c] = bytes_read / sizeof( jack_default_audio_sample_t );
|
||||||
|
|
||||||
|
|
||||||
|
// Convert samples from float to short and put in output buffer
|
||||||
|
for(n=0; n<samples_read[c]; n++) {
|
||||||
|
int tmp = lrintf(tmp_buffer[n] * 32768.0f);
|
||||||
|
if (tmp > SHRT_MAX) {
|
||||||
|
output[n*getChannel()+c] = SHRT_MAX;
|
||||||
|
} else if (tmp < SHRT_MIN) {
|
||||||
|
output[n*getChannel()+c] = SHRT_MIN;
|
||||||
|
} else {
|
||||||
|
output[n*getChannel()+c] = (short) tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Didn't get as many samples as we wanted ?
|
||||||
|
if (getChannel() == 2 && samples_read[0] != samples_read[1]) {
|
||||||
|
Reporter::reportEvent( 2,
|
||||||
|
"Warning: Read a different number of samples "
|
||||||
|
"for left and right channels");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the number of bytes put in the output buffer
|
||||||
|
return samples_read[0] * 2 * getChannel();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Close the audio source
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
JackDspSource :: close ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if ( !isOpen() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < getChannel(); i++) {
|
||||||
|
// Close the port for channel
|
||||||
|
if ( ports[i] ) {
|
||||||
|
jack_port_unregister( client, ports[i] );
|
||||||
|
ports[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free up the ring buffer for channel
|
||||||
|
if ( rb[i] ) {
|
||||||
|
jack_ringbuffer_free( rb[i] );
|
||||||
|
rb[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leave the jack graph */
|
||||||
|
if (client) {
|
||||||
|
jack_client_close(client);
|
||||||
|
client = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Callback called by JACK when audio is available
|
||||||
|
*
|
||||||
|
* Don't do anything too expensive here
|
||||||
|
* - just shove audio samples in ring buffer
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
JackDspSource :: process_callback( jack_nframes_t nframes, void *arg )
|
||||||
|
{
|
||||||
|
JackDspSource* self = (JackDspSource*)arg;
|
||||||
|
size_t to_write = sizeof (jack_default_audio_sample_t) * nframes;
|
||||||
|
unsigned int c;
|
||||||
|
|
||||||
|
// Wait until it is ready
|
||||||
|
if (self->client == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy data to ringbuffer; one per channel */
|
||||||
|
for (c=0; c < self->getChannel(); c++) {
|
||||||
|
char *buf = (char*)jack_port_get_buffer(self->ports[c], nframes);
|
||||||
|
size_t len = jack_ringbuffer_write(self->rb[c], buf, to_write);
|
||||||
|
if (len < to_write) {
|
||||||
|
Reporter::reportEvent( 1, "failed to write to ring ruffer");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Callback called when
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
JackDspSource :: shutdown_callback( void *arg )
|
||||||
|
{
|
||||||
|
//JackDspSource* self = (JackDspSource*)arg;
|
||||||
|
|
||||||
|
Reporter::reportEvent( 1, "JackDspSource :: shutdown_callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SUPPORT_JACK_DSP
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
$Source$
|
||||||
|
|
||||||
|
$Log$
|
||||||
|
Revision 1.1 2005/04/04 08:36:17 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -0,0 +1,289 @@
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2005 Nicholas Humfrey. All rights reserved.
|
||||||
|
|
||||||
|
Tyrell DarkIce
|
||||||
|
|
||||||
|
File : JackDspSource.h
|
||||||
|
Version : $Revision$
|
||||||
|
Author : $Author$
|
||||||
|
Location : $Source$
|
||||||
|
|
||||||
|
Copyright notice:
|
||||||
|
|
||||||
|
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
#ifndef JACK_DSP_SOURCE_H
|
||||||
|
#define JACK_DSP_SOURCE_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#error This is a C++ include file
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================================================ include files */
|
||||||
|
|
||||||
|
|
||||||
|
#include "Reporter.h"
|
||||||
|
#include "AudioSource.h"
|
||||||
|
|
||||||
|
#if defined( HAVE_JACK_LIB )
|
||||||
|
#include <jack/jack.h>
|
||||||
|
#include <jack/ringbuffer.h>
|
||||||
|
#else
|
||||||
|
#error configure for JACK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================================ constants */
|
||||||
|
|
||||||
|
|
||||||
|
/* =================================================================== macros */
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================== data types */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An audio input based on JACK
|
||||||
|
*
|
||||||
|
* @author $Author$
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class JackDspSource : public AudioSource, public virtual Reporter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The jack port
|
||||||
|
*/
|
||||||
|
jack_port_t * ports[2];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The jack ring buffer.
|
||||||
|
*/
|
||||||
|
jack_ringbuffer_t * rb[2];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The jack client.
|
||||||
|
*/
|
||||||
|
jack_client_t * client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The jack audio sample buffer.
|
||||||
|
*/
|
||||||
|
jack_default_audio_sample_t * tmp_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically connect the jack ports ? (default is to not)
|
||||||
|
*/
|
||||||
|
bool auto_connect;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor. Always throws an Exception.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
JackDspSource ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
throw Exception( __FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the object
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init ( const char* name ) throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De-initialize the object
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
strip ( void ) throw ( Exception );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to connect up the JACK ports automatically
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
do_auto_connect( ) throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback called by JACK when audio is available
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
process_callback( jack_nframes_t nframes, void *arg );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback called by JACK when jackd is shutting down
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
shutdown_callback( void *arg );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param name the name of the jack device
|
||||||
|
* @param sampleRate samples per second (e.g. 44100 for 44.1kHz).
|
||||||
|
* @param bitsPerSample bits per sample (e.g. 16 bits).
|
||||||
|
* @param channels number of channels of the audio source
|
||||||
|
* (e.g. 1 for mono, 2 for stereo, etc.).
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
JackDspSource ( const char * name,
|
||||||
|
int sampleRate = 44100,
|
||||||
|
int bitsPerSample = 16,
|
||||||
|
int channels = 2 )
|
||||||
|
throw ( Exception )
|
||||||
|
|
||||||
|
: AudioSource( sampleRate, bitsPerSample, channels )
|
||||||
|
{
|
||||||
|
init( name );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy Constructor.
|
||||||
|
*
|
||||||
|
* @param source the object to copy.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
JackDspSource ( const JackDspSource & ds ) throw ( Exception )
|
||||||
|
: AudioSource( ds )
|
||||||
|
{
|
||||||
|
throw Exception( __FILE__, __LINE__, "JackDspSource doesn't copy");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline virtual
|
||||||
|
~JackDspSource ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
strip();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assignment operator.
|
||||||
|
*
|
||||||
|
* @param ds the object to assign to this one.
|
||||||
|
* @return a reference to this object.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline virtual JackDspSource &
|
||||||
|
operator= ( const JackDspSource & ds ) throw ( Exception )
|
||||||
|
{
|
||||||
|
throw Exception( __FILE__, __LINE__, "JackDspSource doesn't assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the JackDspSource.
|
||||||
|
* This does not put the Jack DSP device into recording mode.
|
||||||
|
* To start getting samples, call either canRead() or read().
|
||||||
|
*
|
||||||
|
* @return true if opening was successful, false otherwise
|
||||||
|
* @exception Exception
|
||||||
|
*
|
||||||
|
* @see #canRead
|
||||||
|
* @see #read
|
||||||
|
*/
|
||||||
|
virtual bool
|
||||||
|
open ( void ) throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the JackDspSource is registered
|
||||||
|
*
|
||||||
|
* @return true if Jack client is setup
|
||||||
|
*/
|
||||||
|
inline virtual bool
|
||||||
|
isOpen ( void ) const throw ()
|
||||||
|
{
|
||||||
|
return client != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the JackDspSource can be read from.
|
||||||
|
* Blocks until the specified time for data to be available.
|
||||||
|
* Puts the Jack DSP device into recording mode.
|
||||||
|
*
|
||||||
|
* @param sec the maximum seconds to block.
|
||||||
|
* @param usec micro seconds to block after the full seconds.
|
||||||
|
* @return true if the JackDspSource is ready to be read from,
|
||||||
|
* false otherwise.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
virtual bool
|
||||||
|
canRead ( unsigned int sec,
|
||||||
|
unsigned int usec ) throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from the JackDspSource.
|
||||||
|
* Puts the Jack DSP device into recording mode.
|
||||||
|
*
|
||||||
|
* @param buf the buffer to read into.
|
||||||
|
* @param len the number of bytes to read into buf
|
||||||
|
* @return the number of bytes read (may be less than len).
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
virtual unsigned int
|
||||||
|
read ( void * buf,
|
||||||
|
unsigned int len ) throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the JackDspSource.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
virtual void
|
||||||
|
close ( void ) throw ( Exception );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================= external data structures */
|
||||||
|
|
||||||
|
|
||||||
|
/* ====================================================== function prototypes */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* JACK_DSP_SOURCE_H */
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
$Source$
|
||||||
|
|
||||||
|
$Log$
|
||||||
|
Revision 1.1 2005/04/04 08:36:17 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
bin_PROGRAMS = darkice
|
bin_PROGRAMS = darkice
|
||||||
CXXFLAGS = -O2 -pedantic -Wall @DEBUG_CXXFLAGS@ @PTHREAD_CFLAGS@
|
AM_CXXFLAGS = -O2 -pedantic -Wall @DEBUG_CXXFLAGS@ @PTHREAD_CFLAGS@ @JACK_CFLAGS@
|
||||||
INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ @ALSA_INCFLAGS@
|
INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ @ALSA_INCFLAGS@
|
||||||
LDADD = @PTHREAD_LIBS@ @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ @ALSA_LDFLAGS@
|
LDADD = @PTHREAD_LIBS@ @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ @ALSA_LDFLAGS@ @JACK_LIBS@
|
||||||
|
|
||||||
darkice_SOURCES = AudioEncoder.h\
|
darkice_SOURCES = AudioEncoder.h\
|
||||||
AudioSource.h\
|
AudioSource.h\
|
||||||
|
@ -52,11 +52,13 @@ darkice_SOURCES = AudioEncoder.h\
|
||||||
Util.h\
|
Util.h\
|
||||||
ConfigSection.h\
|
ConfigSection.h\
|
||||||
ConfigSection.cpp\
|
ConfigSection.cpp\
|
||||||
Config.h\
|
DarkIceConfig.h\
|
||||||
Config.cpp\
|
DarkIceConfig.cpp\
|
||||||
Reporter.h\
|
Reporter.h\
|
||||||
Reporter.cpp\
|
Reporter.cpp\
|
||||||
AlsaDspSource.h\
|
AlsaDspSource.h\
|
||||||
AlsaDspSource.cpp\
|
AlsaDspSource.cpp\
|
||||||
|
JackDspSource.h\
|
||||||
|
JackDspSource.cpp\
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#else
|
#else
|
||||||
#error need unistdt.h
|
#error need unistd.h
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TIME_H
|
#ifdef HAVE_TIME_H
|
||||||
|
@ -309,6 +309,10 @@ class Reporter
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.9 2005/04/04 08:36:17 darkeye
|
||||||
|
commited changes to enable Jack support
|
||||||
|
thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk
|
||||||
|
|
||||||
Revision 1.8 2005/04/03 05:14:07 jbebel
|
Revision 1.8 2005/04/03 05:14:07 jbebel
|
||||||
Changed timestamp on reported events to include date in addition to time.
|
Changed timestamp on reported events to include date in addition to time.
|
||||||
|
|
||||||
|
|
|
@ -123,8 +123,8 @@ aflibConverter::aflibConverter(
|
||||||
largeFilter = high_quality;
|
largeFilter = high_quality;
|
||||||
linearInterp = linear_interpolation;
|
linearInterp = linear_interpolation;
|
||||||
|
|
||||||
_I = NULL;
|
_II = NULL;
|
||||||
_J = NULL;
|
_JJ = NULL;
|
||||||
_vol = 1.0;
|
_vol = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,19 +140,19 @@ aflibConverter::deleteMemory()
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Delete memory for the input and output arrays
|
// Delete memory for the input and output arrays
|
||||||
if (_I != NULL)
|
if (_II != NULL)
|
||||||
{
|
{
|
||||||
for (i = 0; i < _nChans; i++)
|
for (i = 0; i < _nChans; i++)
|
||||||
{
|
{
|
||||||
delete [] _I[i];
|
delete [] _II[i];
|
||||||
_I[i] = NULL;
|
_II[i] = NULL;
|
||||||
delete [] _J[i];
|
delete [] _JJ[i];
|
||||||
_J[i] = NULL;
|
_JJ[i] = NULL;
|
||||||
}
|
}
|
||||||
delete [] _I;
|
delete [] _II;
|
||||||
_I = NULL;
|
_II = NULL;
|
||||||
delete [] _J;
|
delete [] _JJ;
|
||||||
_J = NULL;
|
_JJ = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,15 +180,15 @@ aflibConverter::initialize(
|
||||||
_vol = volume;
|
_vol = volume;
|
||||||
|
|
||||||
// Allocate all new memory
|
// Allocate all new memory
|
||||||
_I = new short * [_nChans];
|
_II = new short * [_nChans];
|
||||||
_J = new short * [_nChans];
|
_JJ = new short * [_nChans];
|
||||||
|
|
||||||
for (i = 0; i < _nChans; i++)
|
for (i = 0; i < _nChans; i++)
|
||||||
{
|
{
|
||||||
// Add extra to allow of offset of input data (Xoff in main routine)
|
// Add extra to allow of offset of input data (Xoff in main routine)
|
||||||
_I[i] = new short[IBUFFSIZE + 256];
|
_II[i] = new short[IBUFFSIZE + 256];
|
||||||
_J[i] = new short[(int)(((double)IBUFFSIZE)*_factor)];
|
_JJ[i] = new short[(int)(((double)IBUFFSIZE)*_factor)];
|
||||||
memset(_I[i], 0, sizeof(short) * (IBUFFSIZE + 256));
|
memset(_II[i], 0, sizeof(short) * (IBUFFSIZE + 256));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ aflibConverter::resampleFast( /* number of output samples returned */
|
||||||
do {
|
do {
|
||||||
if (!last) /* If haven't read last sample yet */
|
if (!last) /* If haven't read last sample yet */
|
||||||
{
|
{
|
||||||
last = readData(inCount, inArray, _I,
|
last = readData(inCount, inArray, _II,
|
||||||
IBUFFSIZE, (int)Xread,first_pass);
|
IBUFFSIZE, (int)Xread,first_pass);
|
||||||
first_pass = FALSE;
|
first_pass = FALSE;
|
||||||
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
||||||
|
@ -487,7 +487,7 @@ aflibConverter::resampleFast( /* number of output samples returned */
|
||||||
orig_Nx = Nx;
|
orig_Nx = Nx;
|
||||||
Time2 = _Time;
|
Time2 = _Time;
|
||||||
/* Resample stuff in input buffer */
|
/* Resample stuff in input buffer */
|
||||||
Nout=SrcLinear(_I[c],_J[c],_factor,&Time2,orig_Nx,maxOutput);
|
Nout=SrcLinear(_II[c],_JJ[c],_factor,&Time2,orig_Nx,maxOutput);
|
||||||
}
|
}
|
||||||
Nx = orig_Nx;
|
Nx = orig_Nx;
|
||||||
_Time = Time2;
|
_Time = Time2;
|
||||||
|
@ -504,7 +504,7 @@ aflibConverter::resampleFast( /* number of output samples returned */
|
||||||
for (c = 0; c < _nChans; c++)
|
for (c = 0; c < _nChans; c++)
|
||||||
{
|
{
|
||||||
for (i=0; i<IBUFFSIZE-Xp+Xoff; i++) { /* Copy part of input signal */
|
for (i=0; i<IBUFFSIZE-Xp+Xoff; i++) { /* Copy part of input signal */
|
||||||
_I[c][i] = _I[c][i+Xp-Xoff]; /* that must be re-used */
|
_II[c][i] = _II[c][i+Xp-Xoff]; /* that must be re-used */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (last) { /* If near end of sample... */
|
if (last) { /* If near end of sample... */
|
||||||
|
@ -526,7 +526,7 @@ aflibConverter::resampleFast( /* number of output samples returned */
|
||||||
|
|
||||||
for (c = 0; c < _nChans; c++)
|
for (c = 0; c < _nChans; c++)
|
||||||
for (i = 0; i < Nout; i++)
|
for (i = 0; i < Nout; i++)
|
||||||
outArray[c * outCount + i + Ycount - Nout] = _J[c][i];
|
outArray[c * outCount + i + Ycount - Nout] = _JJ[c][i];
|
||||||
|
|
||||||
total_inCount += Nx;
|
total_inCount += Nx;
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ aflibConverter::resampleWithFilter( /* number of output samples returned */
|
||||||
do {
|
do {
|
||||||
if (!last) /* If haven't read last sample yet */
|
if (!last) /* If haven't read last sample yet */
|
||||||
{
|
{
|
||||||
last = readData(inCount, inArray, _I,
|
last = readData(inCount, inArray, _II,
|
||||||
IBUFFSIZE, (int)Xread,first_pass);
|
IBUFFSIZE, (int)Xread,first_pass);
|
||||||
first_pass = FALSE;
|
first_pass = FALSE;
|
||||||
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
||||||
|
@ -604,11 +604,11 @@ aflibConverter::resampleWithFilter( /* number of output samples returned */
|
||||||
Time2 = _Time;
|
Time2 = _Time;
|
||||||
/* Resample stuff in input buffer */
|
/* Resample stuff in input buffer */
|
||||||
if (_factor >= 1) { /* SrcUp() is faster if we can use it */
|
if (_factor >= 1) { /* SrcUp() is faster if we can use it */
|
||||||
Nout=SrcUp(_I[c],_J[c],_factor,
|
Nout=SrcUp(_II[c],_JJ[c],_factor,
|
||||||
&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Nout=SrcUD(_I[c],_J[c],_factor,
|
Nout=SrcUD(_II[c],_JJ[c],_factor,
|
||||||
&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -642,7 +642,7 @@ aflibConverter::resampleWithFilter( /* number of output samples returned */
|
||||||
{
|
{
|
||||||
for (i = 0; i < Nout; i++)
|
for (i = 0; i < Nout; i++)
|
||||||
{
|
{
|
||||||
outArray[c * outCount + i + Ycount - Nout] = _J[c][i];
|
outArray[c * outCount + i + Ycount - Nout] = _JJ[c][i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,7 +651,7 @@ aflibConverter::resampleWithFilter( /* number of output samples returned */
|
||||||
for (c = 0; c < _nChans; c++)
|
for (c = 0; c < _nChans; c++)
|
||||||
{
|
{
|
||||||
for (i=0; i<IBUFFSIZE-act_incount+Xoff; i++) { /* Copy part of input signal */
|
for (i=0; i<IBUFFSIZE-act_incount+Xoff; i++) { /* Copy part of input signal */
|
||||||
_I[c][i] = _I[c][i+act_incount]; /* that must be re-used */
|
_II[c][i] = _II[c][i+act_incount]; /* that must be re-used */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Xread = IBUFFSIZE - Nx; /* Pos in input buff to read new data into */
|
Xread = IBUFFSIZE - Nx; /* Pos in input buff to read new data into */
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#define _AFLIBCONVERTER_H_
|
#define _AFLIBCONVERTER_H_
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
|
@ -222,8 +222,8 @@ static short LARGE_FILTER_IMP[];
|
||||||
bool interpFilt;
|
bool interpFilt;
|
||||||
bool largeFilter;
|
bool largeFilter;
|
||||||
bool linearInterp;
|
bool linearInterp;
|
||||||
short ** _I;
|
short ** _II;
|
||||||
short ** _J;
|
short ** _JJ;
|
||||||
unsigned int _Time;
|
unsigned int _Time;
|
||||||
double _factor;
|
double _factor;
|
||||||
int _nChans;
|
int _nChans;
|
||||||
|
|
Loading…
Reference in New Issue