From 9d186e8e96543ad960f5763102baab5fb970cf49 Mon Sep 17 00:00:00 2001 From: darkeye Date: Sun, 15 Feb 2004 12:06:30 +0000 Subject: [PATCH] added ALSA support, thanks to Christian Forster --- darkice/trunk/AUTHORS | 1 + darkice/trunk/ChangeLog | 5 + darkice/trunk/configure.in | 38 +++- darkice/trunk/man/darkice.cfg.5 | 5 +- darkice/trunk/rpm/darkice.spec | 5 +- darkice/trunk/src/AlsaDspSource.cpp | 299 +++++++++++++++++++++++++++ darkice/trunk/src/AlsaDspSource.h | 309 ++++++++++++++++++++++++++++ darkice/trunk/src/AudioSource.cpp | 112 ++++++++++ darkice/trunk/src/AudioSource.h | 71 +++++-- darkice/trunk/src/DarkIce.cpp | 11 +- darkice/trunk/src/Makefile.am | 7 +- darkice/trunk/src/Reporter.h | 21 +- darkice/trunk/src/Util.cpp | 8 +- darkice/trunk/src/Util.h | 8 +- darkice/trunk/src/main.cpp | 5 +- 15 files changed, 866 insertions(+), 39 deletions(-) create mode 100644 darkice/trunk/src/AlsaDspSource.cpp create mode 100644 darkice/trunk/src/AlsaDspSource.h create mode 100644 darkice/trunk/src/AudioSource.cpp diff --git a/darkice/trunk/AUTHORS b/darkice/trunk/AUTHORS index e556910..993179a 100644 --- a/darkice/trunk/AUTHORS +++ b/darkice/trunk/AUTHORS @@ -17,4 +17,5 @@ with contributions by: Atsuhiko Yamanaka Ricardo Galli John Hay + Christian Forster diff --git a/darkice/trunk/ChangeLog b/darkice/trunk/ChangeLog index d9b6ce7..b4fe178 100644 --- a/darkice/trunk/ChangeLog +++ b/darkice/trunk/ChangeLog @@ -1,3 +1,8 @@ +DarkIce next release + + o added ALSA support, thanks to Christian Forster + + 07-01-2004: DarkIce 0.13.2 released o bug fix: two bugs fixed that caused core dump when encoding into diff --git a/darkice/trunk/configure.in b/darkice/trunk/configure.in index 2684cff..ec1e4e5 100644 --- a/darkice/trunk/configure.in +++ b/darkice/trunk/configure.in @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(src/DarkIce.cpp) -AM_INIT_AUTOMAKE(darkice, 0.13.2) +AM_INIT_AUTOMAKE(darkice, 0.14beta) AM_CONFIG_HEADER(config.h) @@ -119,6 +119,42 @@ if test "x${LAME_LDFLAGS}" = "x" -a "x${VORBIS_LDFLAGS}" = "x" ; then fi +dnl----------------------------------------------------------------------------- +dnl link ALSA sound system if requested +dnl----------------------------------------------------------------------------- +AC_SUBST( ALSA_INCFLAGS) +AC_SUBST( ALSA_LDFLAGS) + +AC_ARG_WITH( alsa, +[ --with-alsa use ALSA sound system [yes] ], + USE_ALSA=${withval}, USE_ALSA="yes" ) +AC_ARG_WITH( alsa-prefix, +[ --with-alsa-prefix=DIR alternate location for ALSA [/usr] + look for libraries in ALSA-PREFIX/lib, + for headers in ALSA-PREFIX/include], + CONFIG_ALSA_PREFIX="${withval}", CONFIG_ALSA_PREFIX="/usr") + +if test "x${USE_ALSA}" = "xyes" ; then + AC_MSG_CHECKING( [for alsa libraries at ${CONFIG_ALSA_PREFIX}] ) + LA_SEARCH_LIB( ALSA_LIB_LOC, ALSA_INC_LOC, libasound.so, alsa/asoundlib.h, + ${CONFIG_ALSA_PREFIX}) + + if test "x${ALSA_LIB_LOC}" != "x" ; then + + AC_DEFINE( HAVE_ALSA_LIB, 1, [build with ALSA sound system] ) + if test "x${ALSA_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then + ALSA_INCFLAGS="-I${ALSA_INC_LOC}" + fi + ALSA_LDFLAGS="-L${ALSA_LIB_LOC} -lasound" + AC_MSG_RESULT( [found at ${CONFIG_ALSA_PREFIX}] ) + else + AC_MSG_WARN( [not found, building without ALSA support]) + fi +else + AC_MSG_RESULT( [building without ALSA support] ) +fi + + dnl----------------------------------------------------------------------------- dnl check for MSG_NOSIGNAL for the send() function in libsocket dnl----------------------------------------------------------------------------- diff --git a/darkice/trunk/man/darkice.cfg.5 b/darkice/trunk/man/darkice.cfg.5 index 56f400f..736305a 100644 --- a/darkice/trunk/man/darkice.cfg.5 +++ b/darkice/trunk/man/darkice.cfg.5 @@ -1,4 +1,4 @@ -.TH darkice.cfg 5 "February 9, 2003" "DarkIce" "DarkIce live audio streamer" +.TH darkice.cfg 5 "February 15, 2004" "DarkIce" "DarkIce live audio streamer" .SH NAME darkice.cfg \- configuration file for darkice .SH DESCRIPTION @@ -60,7 +60,8 @@ Required values: .TP .I device -OSS DSP audio device to record from (e.g. /dev/dsp) +OSS DSP audio device to record from (e.g. /dev/dsp) or ALSA DSP device name +(e.g. hwplug:0,0) .TP .I sampleRate The sample rate to record with, samples per second diff --git a/darkice/trunk/rpm/darkice.spec b/darkice/trunk/rpm/darkice.spec index 23d9366..0b56606 100644 --- a/darkice/trunk/rpm/darkice.spec +++ b/darkice/trunk/rpm/darkice.spec @@ -36,7 +36,7 @@ Summary : DarkIce live IceCast / ShoutCast streamer Name: darkice Vendor: Tyrell Hungary Packager: Akos Maroy -Version: 0.13.2 +Version: 0.14beta Release: 1 Copyright: GPL Group: Applications/Multimedia @@ -97,6 +97,9 @@ make clean # =================================================================== change log # # $Log$ +# Revision 1.22 2004/02/15 12:06:29 darkeye +# added ALSA support, thanks to Christian Forster +# # Revision 1.21 2004/01/07 22:14:44 darkeye # for release 0.13.2 # diff --git a/darkice/trunk/src/AlsaDspSource.cpp b/darkice/trunk/src/AlsaDspSource.cpp new file mode 100644 index 0000000..fa70b6a --- /dev/null +++ b/darkice/trunk/src/AlsaDspSource.cpp @@ -0,0 +1,299 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 + LS Informationstechnik (LIKE) + University of Erlangen Nuremberg + All rights reserved. + + Tyrell DarkIce + + File : AlsaDspSource.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 "AlsaDspSource.h" + +// compile only if configured for ALSA +#ifdef SUPPORT_ALSA_DSP + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Util.h" +#include "Exception.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Tell if source id big endian + *----------------------------------------------------------------------------*/ +bool +AlsaDspSource :: isBigEndian ( void ) const throw () +{ + return SND_PCM_FORMAT_S16 == SND_PCM_FORMAT_S16_BE; +} + + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +AlsaDspSource :: init ( const char * name ) throw ( Exception ) +{ + pcmName = Util::strDup( name); + captureHandle = 0; + bufferTime = 1000000; // Do 1s buffering + running = false; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +AlsaDspSource :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] pcmName; +} + + +/*------------------------------------------------------------------------------ + * Open the audio source + *----------------------------------------------------------------------------*/ +bool +AlsaDspSource :: open ( void ) throw ( Exception ) +{ + unsigned int u; + snd_pcm_format_t format; + snd_pcm_hw_params_t *hwParams; + + if ( isOpen() ) { + return false; + } + + switch ( getBitsPerSample() ) { + case 8: + format = SND_PCM_FORMAT_S8; + break; + + case 16: + format = SND_PCM_FORMAT_S16; + break; + + default: + return false; + } + + if (snd_pcm_open(&captureHandle, pcmName, SND_PCM_STREAM_CAPTURE, 0) < 0) { + captureHandle = 0; + return false; + } + + if (snd_pcm_hw_params_malloc(&hwParams) < 0) { + close(); + throw Exception( __FILE__, __LINE__, "can't alloc hardware "\ + "parameter structure"); + } + + if (snd_pcm_hw_params_any(captureHandle, hwParams) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't initialize hardware "\ + "parameter structure"); + } + + if (snd_pcm_hw_params_set_access(captureHandle, hwParams, + SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set access type"); + } + + if (snd_pcm_hw_params_set_format(captureHandle, hwParams, format) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set sample format"); + } + + u = getSampleRate(); + if (snd_pcm_hw_params_set_rate_near(captureHandle, hwParams, &u, 0) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set sample rate", u); + } + + u = getChannel(); + if (snd_pcm_hw_params_set_channels(captureHandle, hwParams, u) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set channels", u); + } + + u = getBufferTime() / 4; + if (snd_pcm_hw_params_set_period_time_near(captureHandle, hwParams, &u, 0) + < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set interrupt frequency"); + } + + u = getBufferTime(); + if (snd_pcm_hw_params_set_buffer_time_near(captureHandle, hwParams, &u, 0) + < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set buffer size"); + } + + if (snd_pcm_hw_params(captureHandle, hwParams) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set hardware parameters"); + } + + snd_pcm_hw_params_free(hwParams); + + if (snd_pcm_prepare(captureHandle) < 0) { + close(); + throw Exception( __FILE__, __LINE__, "can't prepare audio interface "\ + "for use"); + } + + bytesPerFrame = getChannel() * getBitsPerSample() / 8; + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +AlsaDspSource :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + if ( !isOpen() ) { + return false; + } + + if ( !running ) { + snd_pcm_start(captureHandle); + running = true; + } + + /* + * FIXME How to check for available frames? It + * seems like snd_pcm_wait stops working when + * it comes to ALSA plugins... :-( + * + * int milliDelay = sec * 1000 + usec/1000; + * return snd_pcm_wait(captureHandle, milliDelay)!=0; + */ + return true; // bad!! +} + + +/*------------------------------------------------------------------------------ + * Read from the audio source + *----------------------------------------------------------------------------*/ +unsigned int +AlsaDspSource :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + snd_pcm_sframes_t ret; + + if ( !isOpen() ) { + return 0; + } + + do { + ret = snd_pcm_readi(captureHandle, buf, len/bytesPerFrame); + + // Check for buffer underrun + if (ret == -EPIPE) { + reportEvent(1, "Buffer overrun!"); + snd_pcm_prepare(captureHandle); + ret = -EAGAIN; + } + } while (ret == -EAGAIN); + + if ( ret < 0 ) { + throw new Exception(__FILE__, __LINE__, snd_strerror(ret)); + } + + running = true; + return ret * bytesPerFrame; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +AlsaDspSource :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + snd_pcm_close(captureHandle); + + captureHandle = 0; + running = false; +} + +#endif // HAVE_ALSA_LIB + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2004/02/15 12:06:29 darkeye + added ALSA support, thanks to Christian Forster + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/trunk/src/AlsaDspSource.h b/darkice/trunk/src/AlsaDspSource.h new file mode 100644 index 0000000..03c119b --- /dev/null +++ b/darkice/trunk/src/AlsaDspSource.h @@ -0,0 +1,309 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 + LS Informationstechnik (LIKE) + University of Erlangen Nuremberg + All rights reserved. + + Tyrell DarkIce + + File : AlsaDspSource.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 ALSA_SOURCE_H +#define ALSA_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Reporter.h" +#include "AudioSource.h" + +#ifdef HAVE_ALSA_LIB +#include +#else +#error configure for ALSA +#endif + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An audio input based on the ALSA sound system + * + * @author $Author$ + * @version $Revision$ + */ +class AlsaDspSource : public AudioSource, public virtual Reporter +{ + private: + + /** + * Name of the capture PCM stream. + */ + char *pcmName; + + /** + * Handle to access PCM stream data. + */ + snd_pcm_t *captureHandle; + + /** + * Stores number of bytes per frame. One frame + * contains all samples per time instance. + */ + int bytesPerFrame; + + /** + * Is the stream running? + */ + bool running; + + /** + * Number of useconds to do buffering in the audio device. + */ + unsigned int bufferTime; + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + AlsaDspSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Initialize the object + * + * @param name the PCM to open. + * @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 PCM (e.g. "hwplug:0,0"). + * @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 + AlsaDspSource ( const char * name, + int sampleRate = 44100, + int bitsPerSample = 16, + int channel = 2 ) + throw ( Exception ) + : AudioSource( sampleRate, bitsPerSample, channel) + { + init( name); + } + + /** + * Copy Constructor. + * + * @param source the object to copy. + * @exception Exception + */ + inline + AlsaDspSource ( const AlsaDspSource & ds ) throw ( Exception ) + : AudioSource( ds ) + { + init( ds.pcmName); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~AlsaDspSource ( 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 AlsaDspSource & + operator= ( const AlsaDspSource & ds ) throw ( Exception ) + { + if ( this != &ds ) { + strip(); + AudioSource::operator=( ds); + init( ds.pcmName); + } + 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 AlsaDspSource. + * This does not put Alsa 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 AlsaDspSource is open. + * + * @return true if the AlsaDspSource is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return captureHandle != 0; + } + + /** + * Check if the AlsaDspSource can be read from. + * Blocks until the specified time for data to be available. + * Puts the PCM into recording mode. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the AlsaDspSource is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the AlsaDspSource. + * Puts the PCM 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 AlsaDspSource. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); + + /** + * Returns the buffer size in useconds. + * + * @return the number of useconds audio will be buffered in ALSA + */ + inline virtual unsigned int + getBufferTime( void ) const + { + return bufferTime; + } + + /** + * Sets the number of useconds to buffer audio in ALSA + * + * @param time buffer time + */ + inline virtual void + setBufferTime( unsigned int time ) { + bufferTime = time; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* ALSA_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2004/02/15 12:06:29 darkeye + added ALSA support, thanks to Christian Forster + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/trunk/src/AudioSource.cpp b/darkice/trunk/src/AudioSource.cpp new file mode 100644 index 0000000..e9b8d2e --- /dev/null +++ b/darkice/trunk/src/AudioSource.cpp @@ -0,0 +1,112 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : AudioSource.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 */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "AudioSource.h" +#include "Util.h" +#include "Exception.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Return an audio source based on the compiled DSP supports and the + * supplied device name parameter. + *----------------------------------------------------------------------------*/ +AudioSource * +AudioSource :: createDspSource( const char * deviceName, + int sampleRate, + int bitsPerSample, + int channel) + throw ( Exception ) +{ + if ( Util::strEq( deviceName, "/dev", 4) ) { +#if defined( SUPPORT_OSS_DSP ) + Reporter::reportEvent( 1, "using OSS DSP input device:", deviceName); + return new OssDspSource( deviceName, + sampleRate, + bitsPerSample, + channel); +#elif defined( SUPPORT_SOLARIS_DSP ) + Reporter::reportEvent( 1, "using Solaris DSP input device:",deviceName); + return new SolarisDspSource( deviceName, + sampleRate, + bitsPerSample, + channel); +#else + throw new Exception( __FILE__, __LINE__, + "trying to open OSS or Solaris DSP device " + "without support compiled", deviceName); +#endif + } else { +#if defined( SUPPORT_ALSA_DSP ) + Reporter::reportEvent( 1, "using ALSA DSP input device:", deviceName); + return new AlsaDspSource( deviceName, + sampleRate, + bitsPerSample, + channel); +#else + throw new Exception( __FILE__, __LINE__, + "trying to open ALSA DSP device without " + "support compiled", deviceName); +#endif + } +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2004/02/15 12:06:29 darkeye + added ALSA support, thanks to Christian Forster + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/trunk/src/AudioSource.h b/darkice/trunk/src/AudioSource.h index a08f631..2a9c1a9 100644 --- a/darkice/trunk/src/AudioSource.h +++ b/darkice/trunk/src/AudioSource.h @@ -37,6 +37,7 @@ /* ============================================================ include files */ #include "Source.h" +#include "Reporter.h" /* ================================================================ constants */ @@ -44,6 +45,31 @@ /* =================================================================== macros */ +/*------------------------------------------------------------------------------ + * Determine the kind of audio device based on the system + *----------------------------------------------------------------------------*/ +#if defined( HAVE_ALSA_LIB ) +// we have an ALSA sound system available +#define SUPPORT_ALSA_DSP +#endif + +#if defined( HAVE_SYS_SOUNDCARD_H ) +// we have an OSS DSP sound source device available +#define SUPPORT_OSS_DSP +#endif + +#if defined( HAVE_SYS_AUDIO_H ) +// we have a Solaris DSP sound device available +#define SUPPORT_SOLARIS_DSP +#endif + +#if !defined( SUPPORT_ALSA_DSP ) \ + && !defined( SUPPORT_OSS_DSP ) \ + && !defined( SUPPORT_SOLARIS_DSP ) +// there was no DSP audio system found +#error No DSP audio input device found on system +#endif + /* =============================================================== data types */ @@ -53,7 +79,7 @@ * @author $Author$ * @version $Revision$ */ -class AudioSource : public Source +class AudioSource : public Source, public virtual Reporter { private: @@ -210,6 +236,25 @@ class AudioSource : public Source { return bitsPerSample; } + + /** + * Factory method for creating an AudioSource object of the + * appropriate type, based on the compiled DSP support and + * the supplied DSP name parameter. + * + * @param name the audio device (/dev/dspX, hwplug:0,0, etc) + * @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 + */ + static AudioSource * + createDspSource( const char * deviceName, + int sampleRate = 44100, + int bitsPerSample = 16, + int channel = 2) throw ( Exception ); + }; @@ -218,25 +263,16 @@ class AudioSource : public Source /*------------------------------------------------------------------------------ * Determine the kind of audio device based on the system *----------------------------------------------------------------------------*/ -#if defined( HAVE_SYS_SOUNDCARD_H ) +#if defined( SUPPORT_ALSA_DSP ) +#include "AlsaDspSource.h" +#endif -// we have an OSS DSP sound source device available -#define SUPPORT_OSS_DSP +#if defined( SUPPORT_OSS_DSP ) #include "OssDspSource.h" -typedef class OssDspSource DspSource; +#endif -#elif defined( HAVE_SYS_AUDIO_H ) - -// we have a Solaris DSP sound device available -#define SUPPORT_SOLARIS_DSP +#if defined( SUPPORT_SOLARIS_DSP ) #include "SolarisDspSource.h" -typedef class SolarisDspSource DspSource; - -#else - -// there was no DSP audio system found -#error No DSP audio input device found on system - #endif @@ -252,6 +288,9 @@ typedef class SolarisDspSource DspSource; $Source$ $Log$ + Revision 1.6 2004/02/15 12:06:29 darkeye + added ALSA support, thanks to Christian Forster + Revision 1.5 2001/09/18 14:57:19 darkeye finalized Solaris port diff --git a/darkice/trunk/src/DarkIce.cpp b/darkice/trunk/src/DarkIce.cpp index a5f0cbf..d9a71f0 100644 --- a/darkice/trunk/src/DarkIce.cpp +++ b/darkice/trunk/src/DarkIce.cpp @@ -154,10 +154,10 @@ DarkIce :: init ( const Config & config ) throw ( Exception ) channel = Util::strToL( str); device = cs->getForSure( "device", " missing in section [input]"); - dsp = new DspSource( device, - sampleRate, - bitsPerSample, - channel ); + dsp = AudioSource::createDspSource( device, + sampleRate, + bitsPerSample, + channel ); encConnector = new MultiThreadedConnector( dsp.get()); noAudioOuts = 0; @@ -996,6 +996,9 @@ DarkIce :: run ( void ) throw ( Exception ) $Source$ $Log$ + Revision 1.36 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + Revision 1.35 2003/02/09 13:15:57 darkeye added feature for setting the TITLE comment field for vorbis streams diff --git a/darkice/trunk/src/Makefile.am b/darkice/trunk/src/Makefile.am index cebd010..3add294 100644 --- a/darkice/trunk/src/Makefile.am +++ b/darkice/trunk/src/Makefile.am @@ -1,10 +1,11 @@ bin_PROGRAMS = darkice CXXFLAGS = -O2 -pedantic -Wall @DEBUG_CXXFLAGS@ @PTHREAD_CFLAGS@ -INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ -LDADD = @PTHREAD_LIBS@ @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ +INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ @ALSA_INCFLAGS@ +LDADD = @PTHREAD_LIBS@ @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ @ALSA_LDFLAGS@ darkice_SOURCES = AudioEncoder.h\ AudioSource.h\ + AudioSource.cpp\ BufferedSink.cpp\ BufferedSink.h\ CastSink.cpp\ @@ -55,5 +56,7 @@ darkice_SOURCES = AudioEncoder.h\ Config.cpp\ Reporter.h\ Reporter.cpp\ + AlsaDspSource.h\ + AlsaDspSource.cpp\ main.cpp diff --git a/darkice/trunk/src/Reporter.h b/darkice/trunk/src/Reporter.h index c5fd248..16ee44c 100644 --- a/darkice/trunk/src/Reporter.h +++ b/darkice/trunk/src/Reporter.h @@ -104,7 +104,7 @@ class Reporter /** * Print a prefix to each report. */ - void + static void printPrefix( void ) throw () { if ( verbosity > prefixVerbosity ) { @@ -140,7 +140,7 @@ class Reporter * * @param verbosity the new verbosity level. */ - inline void + static inline void setReportVerbosity ( unsigned int verbosity ) throw () { Reporter::verbosity = verbosity; @@ -151,7 +151,7 @@ class Reporter * * @return the current verbosity level. */ - inline unsigned int + static inline unsigned int getReportVerbosity ( void ) throw () { return Reporter::verbosity; @@ -163,7 +163,7 @@ class Reporter * * @param os the output stream */ - inline void + static inline void setReportOutputStream ( std::ostream & os ) throw () { Reporter::os = &os; @@ -174,7 +174,7 @@ class Reporter * * @return the output stream */ - inline std::ostream & + static inline std::ostream & getReportOutputStream ( void ) throw () { return *(Reporter::os); @@ -190,7 +190,7 @@ class Reporter * operator overload. */ template - inline void + static inline void reportEvent ( unsigned int verbosity, const T t ) throw () { @@ -214,7 +214,7 @@ class Reporter */ template inline void - reportEvent ( unsigned int verbosity, + static reportEvent ( unsigned int verbosity, const T t, const U u ) throw () { @@ -241,7 +241,7 @@ class Reporter * operator overload. */ template - inline void + static inline void reportEvent ( unsigned int verbosity, const T t, const U u, @@ -274,7 +274,7 @@ class Reporter * operator overload. */ template - inline void + static inline void reportEvent ( unsigned int verbosity, const T t, const U u, @@ -309,6 +309,9 @@ class Reporter $Source$ $Log$ + Revision 1.7 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + Revision 1.6 2002/05/28 12:35:41 darkeye code cleanup: compiles under gcc-c++ 3.1, using -pedantic option diff --git a/darkice/trunk/src/Util.cpp b/darkice/trunk/src/Util.cpp index 0822754..2072869 100644 --- a/darkice/trunk/src/Util.cpp +++ b/darkice/trunk/src/Util.cpp @@ -212,13 +212,14 @@ Util :: base64Encode( const char * str ) throw ( Exception ) *----------------------------------------------------------------------------*/ bool Util :: strEq( const char * str1, - const char * str2 ) throw ( Exception ) + const char * str2, + unsigned int len ) throw ( Exception ) { if ( !str1 || !str2 ) { throw Exception( __FILE__, __LINE__, "no str1 or no str2"); } - return !strcmp( str1, str2); + return len == 0 ? !strcmp( str1, str2) : !strncmp( str1, str2, len); } @@ -493,6 +494,9 @@ Util :: conv16 ( unsigned char * pcmBuffer, $Source$ $Log$ + Revision 1.13 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + Revision 1.12 2003/02/09 12:57:36 darkeye cosmetic changes to the fileAddDate option diff --git a/darkice/trunk/src/Util.h b/darkice/trunk/src/Util.h index 1c758bb..ca96e52 100644 --- a/darkice/trunk/src/Util.h +++ b/darkice/trunk/src/Util.h @@ -173,12 +173,15 @@ class Util * * @param str1 one of the strings. * @param str2 the other string. + * @param len check the first most len characters. if 0, check + * the whole string * @return true if the two strings are equal, false othersize. * @exception Exception */ static bool strEq ( const char * str1, - const char * str2 ) throw ( Exception ); + const char * str2, + unsigned int len = 0 ) throw ( Exception ); /** * Convert a string to long. @@ -319,6 +322,9 @@ class Util $Source$ $Log$ + Revision 1.10 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + Revision 1.9 2003/02/09 12:57:36 darkeye cosmetic changes to the fileAddDate option diff --git a/darkice/trunk/src/main.cpp b/darkice/trunk/src/main.cpp index e96fa88..7e69dce 100644 --- a/darkice/trunk/src/main.cpp +++ b/darkice/trunk/src/main.cpp @@ -87,7 +87,7 @@ main ( std::cout << "DarkIce " << VERSION << " live audio streamer, http://darkice.sourceforge.net" << std::endl - << "Copyright (c) 2000-2003, Tyrell Hungary, http://tyrell.hu" + << "Copyright (c) 2000-2004, Tyrell Hungary, http://tyrell.hu" << std::endl << std::endl; try { @@ -166,6 +166,9 @@ showUsage ( std::ostream & os ) $Source$ $Log$ + Revision 1.13 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + Revision 1.12 2003/02/09 15:09:41 darkeye for version 0.13