committed serial ulaw patch, provided by Clyde Stubbs, re #13

This commit is contained in:
darkeye 2007-02-25 17:04:17 +00:00
parent f44ac6d410
commit 2b6725d452
10 changed files with 626 additions and 8 deletions

View File

@ -28,4 +28,5 @@ with contributions by:
Alexander Vlasov <zulu@galaradio.com>
Mariusz Mazur <mmazur@kernel.pl>
dsk <derrick@csociety.org>
Clyde Stubbs <clyde@htsoft.com>

View File

@ -1,5 +1,7 @@
DarkIce next release
o added serial ulaw input device support, thanks to
Clyde Stubbs <clyde@htsoft.com>
o improvements on reconnecting:
added TCP connection keep-alive to TCP sockets
added graceful sleep when trying to reconnect

View File

@ -12,7 +12,7 @@ dnl contain the full pathname or the empty string
dnl PATH is space-separated list of directories.
dnl by Florian Bomers
dnl-----------------------------------------------------------------------------
AC_DEFUN(LA_SEARCH_FILE,[
AC_DEFUN([LA_SEARCH_FILE],[
$1=
dnl hack: eliminate line feeds in $2
for FILE in $2; do
@ -41,7 +41,7 @@ dnl TODO: assert function call to verify lib
dnl
dnl by Florian Bomers
dnl-----------------------------------------------------------------------------
AC_DEFUN(LA_SEARCH_LIB,[
AC_DEFUN([LA_SEARCH_LIB],[
dnl look for lib
LA_SEARCH_FILE($1, $3, $5 $5/lib64 $5/lib )
dnl look for header.

View File

@ -13,7 +13,7 @@ dnl AC_STDC_HEADERS
AC_HAVE_HEADERS(errno.h fcntl.h stdio.h stdlib.h string.h unistd.h limits.h)
AC_HAVE_HEADERS(signal.h time.h sys/time.h sys/types.h sys/wait.h math.h)
AC_HAVE_HEADERS(netdb.h netinet/in.h sys/ioctl.h sys/socket.h sys/stat.h)
AC_HAVE_HEADERS(sched.h pthread.h)
AC_HAVE_HEADERS(sched.h pthread.h termios.h)
AC_HAVE_HEADERS(sys/soundcard.h sys/audio.h sys/audioio.h)
AC_HEADER_SYS_WAIT()
@ -55,7 +55,7 @@ AC_ARG_WITH(lame-prefix,
if test "x${USE_LAME}" = "xyes" ; then
AC_MSG_CHECKING( [for lame library at ${CONFIG_LAME_PREFIX}] )
LA_SEARCH_LIB( LAME_LIB_LOC, LAME_INC_LOC, libmp3lame.a, lame/lame.h,
LA_SEARCH_LIB( LAME_LIB_LOC, LAME_INC_LOC, libmp3lame.a libmp3lame.so, lame/lame.h,
${CONFIG_LAME_PREFIX})
if test "x${LAME_LIB_LOC}" != "x" ; then
AC_DEFINE( HAVE_LAME_LIB, 1, [build with lame library] )
@ -132,7 +132,7 @@ AC_ARG_WITH(faac-prefix,
if test "x${USE_FAAC}" = "xyes" ; then
AC_MSG_CHECKING( [for faac library at ${CONFIG_FAAC_PREFIX}] )
LA_SEARCH_LIB( FAAC_LIB_LOC, FAAC_INC_LOC, libfaac.a, faac.h,
LA_SEARCH_LIB( FAAC_LIB_LOC, FAAC_INC_LOC, libfaac.a libfaac.so, faac.h,
${CONFIG_FAAC_PREFIX})
if test "x${FAAC_LIB_LOC}" != "x" ; then
AC_DEFINE( HAVE_FAAC_LIB, 1, [build with faac library] )
@ -166,7 +166,7 @@ AC_ARG_WITH(twolame-prefix,
if test "x${USE_TWOLAME}" = "xyes" ; then
AC_MSG_CHECKING( [for twolame library at ${CONFIG_TWOLAME_PREFIX}] )
LA_SEARCH_LIB( TWOLAME_LIB_LOC, TWOLAME_INC_LOC, libtwolame.a, twolame.h,
LA_SEARCH_LIB( TWOLAME_LIB_LOC, TWOLAME_INC_LOC, libtwolame.a libtwolame.so, twolame.h,
${CONFIG_TWOLAME_PREFIX})
if test "x${TWOLAME_LIB_LOC}" != "x" ; then
AC_DEFINE( HAVE_TWOLAME_LIB, 1, [build with twolame library] )

View File

@ -102,6 +102,7 @@ Developed with contributions by
Alexander Vlasov <zulu@galaradio.com>
Mariusz Mazur <mmazur@kernel.pl>
dsk <derrick@csociety.org>
Clyde Stubbs <clyde@htsoft.com>
.SH LINKS
Project homepage:

View File

@ -66,7 +66,20 @@ AudioSource :: createDspSource( const char * deviceName,
throw ( Exception )
{
if ( Util::strEq( deviceName, "/dev", 4) ) {
if ( Util::strEq( deviceName, "/dev/tty", 8) ) {
#if defined( SUPPORT_SERIAL_ULAW )
Reporter::reportEvent( 1, "Using Serial Ulaw input device:",
deviceName);
return new SerialUlaw( deviceName,
sampleRate,
bitsPerSample,
channel);
#else
throw Exception( __FILE__, __LINE__,
"trying to open Serial ULaw device "
"without support compiled", deviceName);
#endif
} else if ( Util::strEq( deviceName, "/dev", 4) ) {
#if defined( SUPPORT_OSS_DSP )
Reporter::reportEvent( 1, "Using OSS DSP input device:", deviceName);
return new OssDspSource( deviceName,

View File

@ -71,10 +71,15 @@
#define SUPPORT_JACK_DSP 1
#endif
#if defined ( HAVE_TERMIOS_H )
#define SUPPORT_SERIAL_ULAW 1
#endif
#if !defined( SUPPORT_ALSA_DSP ) \
&& !defined( SUPPORT_OSS_DSP ) \
&& !defined( SUPPORT_JACK_DSP ) \
&& !defined( SUPPORT_SOLARIS_DSP )
&& !defined( SUPPORT_SOLARIS_DSP ) \
&& !defined( SUPPORT_SERIAL_ULAW)
// there was no DSP audio system found
#error No DSP audio input device found on system
#endif
@ -295,6 +300,11 @@ class AudioSource : public Source, public virtual Reporter
#include "JackDspSource.h"
#endif
#if defined ( SUPPORT_SERIAL_ULAW )
#include "SerialUlaw.h"
#endif
/* ====================================================== function prototypes */

View File

@ -46,6 +46,8 @@ darkice_SOURCES = AudioEncoder.h\
aflibConverterSmallFilter.h\
OssDspSource.cpp\
OssDspSource.h\
SerialUlaw.cpp\
SerialUlaw.h\
SolarisDspSource.cpp\
SolarisDspSource.h\
Ref.h\

View File

@ -0,0 +1,334 @@
/*------------------------------------------------------------------------------
Copyright (c) 2000 Tyrell Corporation.
Copyright (c) 2006 Clyde Stubbs.
Tyrell DarkIce
File : SerialUlaw.cpp
Version : $Revision: 1.13 $
Author : $Author: darkeye $
Location : $Source: /cvsroot/darkice/darkice/src/SerialUlaw.cpp,v $
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 "SerialUlaw.h"
#ifdef SUPPORT_SERIAL_ULAW
// only compile this code if there's 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_SYS_STAT_H
#include <sys/stat.h>
#else
#error need sys/stat.h
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#else
#error need fcntl.h
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#error need sys/time.h
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#else
#error need sys/ioctl.h
#endif
#ifdef HAVE_SYS_SOUNDCARD_H
#include <sys/soundcard.h>
#else
#error need sys/soundcard.h
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#else
#error need termios.h
#endif
#include "Util.h"
#include "Exception.h"
#include "SerialUlaw.h"
/* =================================================== local data structures */
/* ================================================ local constants & macros */
/*------------------------------------------------------------------------------
* File identity
*----------------------------------------------------------------------------*/
static const char fileid[] = "$Id$";
/*------------------------------------------------------------------------------
* Ulaw decode table
*----------------------------------------------------------------------------*/
static unsigned int ulawdecode[256] =
{
0x8284,0x8684,0x8a84,0x8e84,0x9284,0x9684,0x9a84,0x9e84,
0xa284,0xa684,0xaa84,0xae84,0xb284,0xb684,0xba84,0xbe84,
0xc184,0xc384,0xc584,0xc784,0xc984,0xcb84,0xcd84,0xcf84,
0xd184,0xd384,0xd584,0xd784,0xd984,0xdb84,0xdd84,0xdf84,
0xe104,0xe204,0xe304,0xe404,0xe504,0xe604,0xe704,0xe804,
0xe904,0xea04,0xeb04,0xec04,0xed04,0xee04,0xef04,0xf004,
0xf0c4,0xf144,0xf1c4,0xf244,0xf2c4,0xf344,0xf3c4,0xf444,
0xf4c4,0xf544,0xf5c4,0xf644,0xf6c4,0xf744,0xf7c4,0xf844,
0xf8a4,0xf8e4,0xf924,0xf964,0xf9a4,0xf9e4,0xfa24,0xfa64,
0xfaa4,0xfae4,0xfb24,0xfb64,0xfba4,0xfbe4,0xfc24,0xfc64,
0xfc94,0xfcb4,0xfcd4,0xfcf4,0xfd14,0xfd34,0xfd54,0xfd74,
0xfd94,0xfdb4,0xfdd4,0xfdf4,0xfe14,0xfe34,0xfe54,0xfe74,
0xfe8c,0xfe9c,0xfeac,0xfebc,0xfecc,0xfedc,0xfeec,0xfefc,
0xff0c,0xff1c,0xff2c,0xff3c,0xff4c,0xff5c,0xff6c,0xff7c,
0xff88,0xff90,0xff98,0xffa0,0xffa8,0xffb0,0xffb8,0xffc0,
0xffc8,0xffd0,0xffd8,0xffe0,0xffe8,0xfff0,0xfff8,0x0000,
0x7d7c,0x797c,0x757c,0x717c,0x6d7c,0x697c,0x657c,0x617c,
0x5d7c,0x597c,0x557c,0x517c,0x4d7c,0x497c,0x457c,0x417c,
0x3e7c,0x3c7c,0x3a7c,0x387c,0x367c,0x347c,0x327c,0x307c,
0x2e7c,0x2c7c,0x2a7c,0x287c,0x267c,0x247c,0x227c,0x207c,
0x1efc,0x1dfc,0x1cfc,0x1bfc,0x1afc,0x19fc,0x18fc,0x17fc,
0x16fc,0x15fc,0x14fc,0x13fc,0x12fc,0x11fc,0x10fc,0x0ffc,
0x0f3c,0x0ebc,0x0e3c,0x0dbc,0x0d3c,0x0cbc,0x0c3c,0x0bbc,
0x0b3c,0x0abc,0x0a3c,0x09bc,0x093c,0x08bc,0x083c,0x07bc,
0x075c,0x071c,0x06dc,0x069c,0x065c,0x061c,0x05dc,0x059c,
0x055c,0x051c,0x04dc,0x049c,0x045c,0x041c,0x03dc,0x039c,
0x036c,0x034c,0x032c,0x030c,0x02ec,0x02cc,0x02ac,0x028c,
0x026c,0x024c,0x022c,0x020c,0x01ec,0x01cc,0x01ac,0x018c,
0x0174,0x0164,0x0154,0x0144,0x0134,0x0124,0x0114,0x0104,
0x00f4,0x00e4,0x00d4,0x00c4,0x00b4,0x00a4,0x0094,0x0084,
0x0078,0x0070,0x0068,0x0060,0x0058,0x0050,0x0048,0x0040,
0x0038,0x0030,0x0028,0x0020,0x0018,0x0010,0x0008,0x0000,
};
/* =============================================== local function prototypes */
/* ============================================================= module code */
/*------------------------------------------------------------------------------
* Tell if source id big endian
*----------------------------------------------------------------------------*/
bool
SerialUlaw :: isBigEndian ( void ) const throw ()
{
return false;
}
/*------------------------------------------------------------------------------
* Initialize the object
*----------------------------------------------------------------------------*/
void
SerialUlaw :: init ( const char * name ) throw ( Exception )
{
fileName = Util::strDup( name);
fileDescriptor = 0;
running = false;
}
/*------------------------------------------------------------------------------
* De-initialize the object
*----------------------------------------------------------------------------*/
void
SerialUlaw :: strip ( void ) throw ( Exception )
{
if ( isOpen() ) {
close();
}
delete[] fileName;
}
/*------------------------------------------------------------------------------
* Open the audio source
*----------------------------------------------------------------------------*/
bool
SerialUlaw :: open ( void ) throw ( Exception )
{
struct termios ts;
if ( isOpen() ) {
return false;
}
switch ( getBitsPerSample() ) {
case 16:
break;
default:
return false;
}
if (getChannel() != 1) {
reportEvent(3, "Only mono input supported for Serial ULaw");
return false;
}
if (getSampleRate() != 8000) {
reportEvent(3, "Only 8000 Hz sample rate supported for Serial ULaw");
return false;
}
if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) {
fileDescriptor = 0;
return false;
}
if(tcgetattr(fileDescriptor, &ts) < 0) {
close();
throw Exception( __FILE__, __LINE__, "can't get tty settings");
}
cfsetispeed(&ts, B115200);
cfmakeraw(&ts);
ts.c_cflag |= CLOCAL;
if(tcsetattr(fileDescriptor, TCSANOW, &ts) < 0) {
close();
throw Exception( __FILE__, __LINE__, "can't set tty settings");
}
tcflush(fileDescriptor, TCIFLUSH);
return true;
}
/*------------------------------------------------------------------------------
* Check whether read() would return anything
*----------------------------------------------------------------------------*/
bool
SerialUlaw :: canRead ( unsigned int sec,
unsigned int usec ) throw ( Exception )
{
fd_set fdset;
struct timeval tv;
int ret;
if ( !isOpen() ) {
return false;
}
FD_ZERO( &fdset);
FD_SET( fileDescriptor, &fdset);
tv.tv_sec = sec;
tv.tv_usec = usec;
ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv);
if ( ret == -1 ) {
throw Exception( __FILE__, __LINE__, "select error");
}
return ret > 0;
}
/*------------------------------------------------------------------------------
* Read from the audio source
*----------------------------------------------------------------------------*/
unsigned int
SerialUlaw :: read ( void * buf,
unsigned int len ) throw ( Exception )
{
ssize_t ret;
unsigned char ubuf[256], * ptr;
int i, plen;
if ( !isOpen() ) {
return 0;
}
ret = 0;
ptr = (unsigned char *)buf;
while(len > 1) {
plen = sizeof(ubuf);
if (plen > (int)len/2) {
plen = len/2;
}
plen = ::read( fileDescriptor, ubuf, plen);
if(plen < 0) {
perror("read");
throw Exception( __FILE__, __LINE__, "read error");
}
for(i = 0 ; i != plen ; i++) {
*ptr++ = ulawdecode[ubuf[i]] & 0xFF;
*ptr++ = ulawdecode[ubuf[i]] >> 8;
}
len -= plen*2;
ret += plen*2;
}
running = true;
return ret;
}
/*------------------------------------------------------------------------------
* Close the audio source
*----------------------------------------------------------------------------*/
void
SerialUlaw :: close ( void ) throw ( Exception )
{
if ( !isOpen() ) {
return;
}
::close( fileDescriptor);
fileDescriptor = 0;
running = false;
}
#endif // SUPPORT_SERIAL_ULAW

View File

@ -0,0 +1,255 @@
/*------------------------------------------------------------------------------
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
Copyright (c) 2007 Clyde Stubbs
Tyrell DarkIce
File : SerialUlaw.h
Version : $Revision$
Author : $Author$
Location : $HeadURL$
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 SERIAL_ULAW_SOURCE_H
#define SERIAL_ULAW_SOURCE_H
#ifndef __cplusplus
#error This is a C++ include file
#endif
/* ============================================================ include files */
#include "Reporter.h"
#include "AudioSource.h"
/* ================================================================ constants */
/* =================================================================== macros */
/* =============================================================== data types */
/**
* An audio input based on /dev/dsp-like raw devices
*
* @author $Author: darkeye $
* @version $Revision: 1.7 $
*/
class SerialUlaw : public AudioSource, public virtual Reporter
{
private:
/**
* The file name of the OSS DSP device (e.g. /dev/dsp or /dev/dsp0).
*/
char * fileName;
/**
* The low-level file descriptor of the OSS DSP device.
*/
int fileDescriptor;
/**
* Indicates wether the low-level OSS DSP device is in a recording
* state.
*/
bool running;
protected:
/**
* Default constructor. Always throws an Exception.
*
* @exception Exception
*/
inline
SerialUlaw ( void ) throw ( Exception )
{
throw Exception( __FILE__, __LINE__);
}
/**
* Initialize the object
*
* @param name the file name of the OSS DSP device.
* @exception Exception
*/
void
init ( const char * name ) throw ( Exception );
/**
* De-iitialize the object
*
* @exception Exception
*/
void
strip ( void ) throw ( Exception );
public:
/**
* Constructor.
*
* @param name the file name of the OSS DSP device
* (e.g. /dev/dsp or /dev/dsp0).
* @param sampleRate samples per second (e.g. 44100 for 44.1kHz).
* @param bitsPerSample bits per sample (e.g. 16 bits).
* @param channel number of channels of the audio source
* (e.g. 1 for mono, 2 for stereo, etc.).
* @exception Exception
*/
inline
SerialUlaw ( const char * name,
int sampleRate = 44100,
int bitsPerSample = 16,
int channel = 2 )
throw ( Exception )
: AudioSource( sampleRate, bitsPerSample, channel)
{
init( name);
}
/**
* Copy Constructor.
*
* @param ods the object to copy.
* @exception Exception
*/
inline
SerialUlaw ( const SerialUlaw & ods ) throw ( Exception )
: AudioSource( ods )
{
init( ods.fileName);
}
/**
* Destructor.
*
* @exception Exception
*/
inline virtual
~SerialUlaw ( 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 SerialUlaw &
operator= ( const SerialUlaw & ds ) throw ( Exception )
{
if ( this != &ds ) {
strip();
AudioSource::operator=( ds);
init( ds.fileName);
}
return *this;
}
/**
* Tell if the data from this source comes in big or little endian.
*
* @return true if the source is big endian, false otherwise
*/
virtual bool
isBigEndian ( void ) const throw ();
/**
* Open the SerialUlaw.
* This does not put the OSS 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 SerialUlaw is open.
*
* @return true if the SerialUlaw is open, false otherwise.
*/
inline virtual bool
isOpen ( void ) const throw ()
{
return fileDescriptor != 0;
}
/**
* Check if the SerialUlaw can be read from.
* Blocks until the specified time for data to be available.
* Puts the OSS 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 SerialUlaw is ready to be read from,
* false otherwise.
* @exception Exception
*/
virtual bool
canRead ( unsigned int sec,
unsigned int usec ) throw ( Exception );
/**
* Read from the SerialUlaw.
* Puts the OSS 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 SerialUlaw.
*
* @exception Exception
*/
virtual void
close ( void ) throw ( Exception );
};
/* ================================================= external data structures */
/* ====================================================== function prototypes */
#endif /* SERIAL_ULAW_SOURCE_H */