added IceCast2 / vorbis support
This commit is contained in:
parent
c6a5820052
commit
3cde98dcaa
|
@ -9,7 +9,7 @@ AC_PROG_INSTALL
|
||||||
|
|
||||||
dnl AC_STDC_HEADERS
|
dnl AC_STDC_HEADERS
|
||||||
AC_HAVE_HEADERS(errno.h fcntl.h stdio.h stdlib.h string.h unistd.h limits.h)
|
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)
|
AC_HAVE_HEADERS(signal.h time.h sys/time.h sys/types.h sys/wait.h)
|
||||||
AC_HAVE_HEADERS(netdb.h netinet/in.h sys/ioctl.h sys/socket.h sys/stat.h)
|
AC_HAVE_HEADERS(netdb.h netinet/in.h sys/ioctl.h sys/socket.h sys/stat.h)
|
||||||
AC_HAVE_HEADERS(sched.h)
|
AC_HAVE_HEADERS(sched.h)
|
||||||
AC_HAVE_HEADERS(sys/soundcard.h sys/audio.h)
|
AC_HAVE_HEADERS(sys/soundcard.h sys/audio.h)
|
||||||
|
@ -25,6 +25,8 @@ AC_SUBST(LINK_STATIC)
|
||||||
AC_CHECK_LIB( socket, socket)
|
AC_CHECK_LIB( socket, socket)
|
||||||
AC_CHECK_LIB( nsl, gethostbyname)
|
AC_CHECK_LIB( nsl, gethostbyname)
|
||||||
AC_CHECK_LIB( rt, sched_getscheduler)
|
AC_CHECK_LIB( rt, sched_getscheduler)
|
||||||
|
AC_CHECK_LIB( vorbis, vorbis_info_init)
|
||||||
|
AC_CHECK_LIB( vorbisenc, vorbis_encode_init)
|
||||||
|
|
||||||
dnl checkin for lame library
|
dnl checkin for lame library
|
||||||
AC_MSG_CHECKING(lame library)
|
AC_MSG_CHECKING(lame library)
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
/* ============================================================ include files */
|
/* ============================================================ include files */
|
||||||
|
|
||||||
#include "Referable.h"
|
#include "Referable.h"
|
||||||
|
#include "Sink.h"
|
||||||
#include "AudioSource.h"
|
#include "AudioSource.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@
|
||||||
* @author $Author$
|
* @author $Author$
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
class AudioEncoder : public virtual Referable
|
class AudioEncoder : public Sink, public virtual Referable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -359,6 +360,9 @@ class AudioEncoder : public virtual Referable
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.3 2001/09/14 19:31:06 darkeye
|
||||||
|
added IceCast2 / vorbis support
|
||||||
|
|
||||||
Revision 1.2 2000/11/12 14:54:50 darkeye
|
Revision 1.2 2000/11/12 14:54:50 darkeye
|
||||||
added kdoc-style documentation comments
|
added kdoc-style documentation comments
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,10 @@
|
||||||
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "IceCast.h"
|
#include "IceCast.h"
|
||||||
|
#include "IceCast2.h"
|
||||||
#include "ShoutCast.h"
|
#include "ShoutCast.h"
|
||||||
|
#include "LameLibEncoder.h"
|
||||||
|
#include "VorbisLibEncoder.h"
|
||||||
#include "DarkIce.h"
|
#include "DarkIce.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,7 +151,9 @@ DarkIce :: init ( const Config & config ) throw ( Exception )
|
||||||
channel );
|
channel );
|
||||||
encConnector = new Connector( dsp.get());
|
encConnector = new Connector( dsp.get());
|
||||||
|
|
||||||
|
noAudioOuts = 0;
|
||||||
configIceCast( config, bufferSecs);
|
configIceCast( config, bufferSecs);
|
||||||
|
configIceCast2( config, bufferSecs);
|
||||||
configShoutCast( config, bufferSecs);
|
configShoutCast( config, bufferSecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,30 +228,116 @@ DarkIce :: configIceCast ( const Config & config,
|
||||||
reportEvent( 6, "using buffer size", bs);
|
reportEvent( 6, "using buffer size", bs);
|
||||||
|
|
||||||
// streaming related stuff
|
// streaming related stuff
|
||||||
lameLibOuts[u].socket = new TcpSocket( server, port);
|
audioOuts[u].socket = new TcpSocket( server, port);
|
||||||
lameLibOuts[u].server = new IceCast( lameLibOuts[u].socket.get(),
|
audioOuts[u].server = new IceCast( audioOuts[u].socket.get(),
|
||||||
password,
|
password,
|
||||||
mountPoint,
|
mountPoint,
|
||||||
bitrate,
|
bitrate,
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
url,
|
url,
|
||||||
genre,
|
genre,
|
||||||
isPublic,
|
isPublic,
|
||||||
remoteDumpFile );
|
remoteDumpFile );
|
||||||
|
|
||||||
lameLibOuts[u].encoder = new LameLibEncoder(lameLibOuts[u].server.get(),
|
audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(),
|
||||||
dsp.get(),
|
dsp.get(),
|
||||||
bitrate,
|
bitrate,
|
||||||
dsp->getSampleRate(),
|
dsp->getSampleRate(),
|
||||||
dsp->getChannel(),
|
dsp->getChannel(),
|
||||||
lowpass,
|
lowpass,
|
||||||
highpass );
|
highpass );
|
||||||
|
|
||||||
encConnector->attach( lameLibOuts[u].encoder.get());
|
encConnector->attach( audioOuts[u].encoder.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
noLameLibOuts = u;
|
noAudioOuts += u;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Look for the IceCast2 stream outputs in the config file
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
DarkIce :: configIceCast2 ( const Config & config,
|
||||||
|
unsigned int bufferSecs )
|
||||||
|
throw ( Exception )
|
||||||
|
{
|
||||||
|
// look for IceCast2 encoder output streams,
|
||||||
|
// sections [icecast2-0], [icecast2-1], ...
|
||||||
|
char stream[] = "icecast2- ";
|
||||||
|
size_t streamLen = Util::strLen( stream);
|
||||||
|
unsigned int u;
|
||||||
|
|
||||||
|
for ( u = 0; u < maxOutput; ++u ) {
|
||||||
|
const ConfigSection * cs;
|
||||||
|
const char * str;
|
||||||
|
|
||||||
|
// ugly hack to change the section name to "stream0", "stream1", etc.
|
||||||
|
stream[streamLen-1] = '0' + u;
|
||||||
|
|
||||||
|
if ( !(cs = config.get( stream)) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int bitrate = 0;
|
||||||
|
const char * server = 0;
|
||||||
|
unsigned int port = 0;
|
||||||
|
const char * password = 0;
|
||||||
|
const char * mountPoint = 0;
|
||||||
|
const char * name = 0;
|
||||||
|
const char * description = 0;
|
||||||
|
const char * url = 0;
|
||||||
|
const char * genre = 0;
|
||||||
|
bool isPublic = false;
|
||||||
|
|
||||||
|
str = cs->getForSure("bitrate", " missing in section ", stream);
|
||||||
|
bitrate = Util::strToL( str);
|
||||||
|
server = cs->getForSure( "server", " missing in section ", stream);
|
||||||
|
str = cs->getForSure( "port", " missing in section ", stream);
|
||||||
|
port = Util::strToL( str);
|
||||||
|
password = cs->getForSure("password"," missing in section ",stream);
|
||||||
|
mountPoint = cs->getForSure( "mountPoint",
|
||||||
|
" missing in section ",
|
||||||
|
stream);
|
||||||
|
name = cs->get( "name");
|
||||||
|
description = cs->get("description");
|
||||||
|
url = cs->get( "url");
|
||||||
|
genre = cs->get( "genre");
|
||||||
|
str = cs->get( "public");
|
||||||
|
isPublic = str ? (Util::strEq( str, "yes") ? true : false) : false;
|
||||||
|
|
||||||
|
// go on and create the things
|
||||||
|
|
||||||
|
// encoder related stuff
|
||||||
|
unsigned int bs = bufferSecs *
|
||||||
|
(dsp->getBitsPerSample() / 8) *
|
||||||
|
dsp->getChannel() *
|
||||||
|
dsp->getSampleRate();
|
||||||
|
reportEvent( 6, "using buffer size", bs);
|
||||||
|
|
||||||
|
// streaming related stuff
|
||||||
|
audioOuts[u].socket = new TcpSocket( server, port);
|
||||||
|
audioOuts[u].server = new IceCast2( audioOuts[u].socket.get(),
|
||||||
|
password,
|
||||||
|
mountPoint,
|
||||||
|
bitrate,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
url,
|
||||||
|
genre,
|
||||||
|
isPublic );
|
||||||
|
|
||||||
|
audioOuts[u].encoder = new VorbisLibEncoder( audioOuts[u].server.get(),
|
||||||
|
dsp.get(),
|
||||||
|
bitrate,
|
||||||
|
dsp->getSampleRate(),
|
||||||
|
dsp->getChannel() );
|
||||||
|
|
||||||
|
encConnector->attach( audioOuts[u].encoder.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
noAudioOuts += u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -318,30 +409,30 @@ DarkIce :: configShoutCast ( const Config & config,
|
||||||
reportEvent( 6, "using buffer size", bs);
|
reportEvent( 6, "using buffer size", bs);
|
||||||
|
|
||||||
// streaming related stuff
|
// streaming related stuff
|
||||||
lameLibOuts[u].socket = new TcpSocket( server, port);
|
audioOuts[u].socket = new TcpSocket( server, port);
|
||||||
lameLibOuts[u].server = new ShoutCast( lameLibOuts[u].socket.get(),
|
audioOuts[u].server = new ShoutCast( audioOuts[u].socket.get(),
|
||||||
password,
|
password,
|
||||||
bitrate,
|
bitrate,
|
||||||
name,
|
name,
|
||||||
url,
|
url,
|
||||||
genre,
|
genre,
|
||||||
isPublic,
|
isPublic,
|
||||||
irc,
|
irc,
|
||||||
aim,
|
aim,
|
||||||
icq );
|
icq );
|
||||||
|
|
||||||
lameLibOuts[u].encoder = new LameLibEncoder(lameLibOuts[u].server.get(),
|
audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(),
|
||||||
dsp.get(),
|
dsp.get(),
|
||||||
bitrate,
|
bitrate,
|
||||||
dsp->getSampleRate(),
|
dsp->getSampleRate(),
|
||||||
dsp->getChannel(),
|
dsp->getChannel(),
|
||||||
lowpass,
|
lowpass,
|
||||||
highpass );
|
highpass );
|
||||||
|
|
||||||
encConnector->attach( lameLibOuts[u].encoder.get());
|
encConnector->attach( audioOuts[u].encoder.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
noLameLibOuts = u;
|
noAudioOuts += u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -477,6 +568,9 @@ DarkIce :: run ( void ) throw ( Exception )
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.19 2001/09/14 19:31:06 darkeye
|
||||||
|
added IceCast2 / vorbis support
|
||||||
|
|
||||||
Revision 1.18 2001/09/11 15:05:21 darkeye
|
Revision 1.18 2001/09/11 15:05:21 darkeye
|
||||||
added Solaris support
|
added Solaris support
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
#include "AudioSource.h"
|
#include "AudioSource.h"
|
||||||
#include "BufferedSink.h"
|
#include "BufferedSink.h"
|
||||||
#include "Connector.h"
|
#include "Connector.h"
|
||||||
#include "LameLibEncoder.h"
|
#include "AudioEncoder.h"
|
||||||
#include "TcpSocket.h"
|
#include "TcpSocket.h"
|
||||||
#include "CastSink.h"
|
#include "CastSink.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
@ -82,26 +82,26 @@ class DarkIce : public virtual Referable, public virtual Reporter
|
||||||
/**
|
/**
|
||||||
* The maximum number of supported outputs.
|
* The maximum number of supported outputs.
|
||||||
*/
|
*/
|
||||||
static const unsigned int maxOutput = 8;
|
static const unsigned int maxOutput = 24;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type describing each lame library output.
|
* Type describing each lame library output.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Ref<LameLibEncoder> encoder;
|
Ref<AudioEncoder> encoder;
|
||||||
Ref<TcpSocket> socket;
|
Ref<TcpSocket> socket;
|
||||||
Ref<CastSink> server;
|
Ref<CastSink> server;
|
||||||
} LameLibOutput;
|
} Output;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The lame library outputs.
|
* The outputs.
|
||||||
*/
|
*/
|
||||||
LameLibOutput lameLibOuts[maxOutput];
|
Output audioOuts[maxOutput];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of lame library outputs.
|
* Number of lame library outputs.
|
||||||
*/
|
*/
|
||||||
unsigned int noLameLibOuts;
|
unsigned int noAudioOuts;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duration of playing, in seconds.
|
* Duration of playing, in seconds.
|
||||||
|
@ -150,6 +150,18 @@ class DarkIce : public virtual Referable, public virtual Reporter
|
||||||
configIceCast ( const Config & config,
|
configIceCast ( const Config & config,
|
||||||
unsigned int bufferSecs ) throw ( Exception );
|
unsigned int bufferSecs ) throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for the icecast2 stream outputs from the config file.
|
||||||
|
* Called from init()
|
||||||
|
*
|
||||||
|
* @param config the config Object to read initialization
|
||||||
|
* information from.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
configIceCast2 ( const Config & config,
|
||||||
|
unsigned int bufferSecs ) throw ( Exception );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look for the shoutcast stream outputs from the config file.
|
* Look for the shoutcast stream outputs from the config file.
|
||||||
* Called from init()
|
* Called from init()
|
||||||
|
@ -281,6 +293,9 @@ class DarkIce : public virtual Referable, public virtual Reporter
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.12 2001/09/14 19:31:06 darkeye
|
||||||
|
added IceCast2 / vorbis support
|
||||||
|
|
||||||
Revision 1.11 2001/09/11 15:05:21 darkeye
|
Revision 1.11 2001/09/11 15:05:21 darkeye
|
||||||
added Solaris support
|
added Solaris support
|
||||||
|
|
||||||
|
|
|
@ -1,334 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : FileSink.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 "configure.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STDLIB_H
|
|
||||||
#include <stdlib.h>
|
|
||||||
#else
|
|
||||||
#error need stdlib.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#error need sys/types.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_ERRNO_H
|
|
||||||
#include <errno.h>
|
|
||||||
#else
|
|
||||||
#error need errno.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_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Util.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "FileSink.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FileSink :: init ( const char * name ) throw ( Exception )
|
|
||||||
{
|
|
||||||
fileName = Util::strDup( name);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FileSink :: strip ( void) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Copy Constructor
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
FileSink :: FileSink ( const FileSink & fs ) throw ( Exception )
|
|
||||||
: Sink( fs )
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
init( fs.fileName);
|
|
||||||
|
|
||||||
if ( (fd = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0) == -1 ) {
|
|
||||||
strip();
|
|
||||||
throw Exception( __FILE__, __LINE__, "dup failure");
|
|
||||||
}
|
|
||||||
|
|
||||||
fileDescriptor = fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Assignment operator
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
FileSink &
|
|
||||||
FileSink :: operator= ( const FileSink & fs ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &fs ) {
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
/* first strip */
|
|
||||||
strip();
|
|
||||||
|
|
||||||
|
|
||||||
/* then build up */
|
|
||||||
Sink::operator=( fs );
|
|
||||||
|
|
||||||
init( fs.fileName);
|
|
||||||
|
|
||||||
if ( (fd = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0) == -1 ) {
|
|
||||||
strip();
|
|
||||||
throw Exception( __FILE__, __LINE__, "dup failure");
|
|
||||||
}
|
|
||||||
|
|
||||||
fileDescriptor = fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check wether a file exists
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
FileSink :: exists ( void ) const throw ()
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if ( stat( (const char*)fileName, &st) == -1 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Create a file, truncate if already exists
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
FileSink :: create ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if ( isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (fd = ::creat( fileName, S_IRUSR | S_IWUSR)) == -1 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "creat error", errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
::close( fd);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open the file
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
FileSink :: open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (fileDescriptor = ::open( fileName, O_WRONLY | O_TRUNC, 0)) == -1 ) {
|
|
||||||
fileDescriptor = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check wether read() would return anything
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
FileSink :: canWrite ( 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, NULL, &fdset, NULL, &tv);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "select error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Read from the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
FileSink :: write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ::write( fileDescriptor, buf, len);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
if ( errno == EAGAIN ) {
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
throw Exception( __FILE__, __LINE__, "write error", errno);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FileSink :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
flush();
|
|
||||||
::close( fileDescriptor);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
$Source$
|
|
||||||
|
|
||||||
$Log$
|
|
||||||
Revision 1.5 2001/09/11 15:05:21 darkeye
|
|
||||||
added Solaris support
|
|
||||||
|
|
||||||
Revision 1.4 2001/08/26 20:44:30 darkeye
|
|
||||||
removed external command-line encoder support
|
|
||||||
replaced it with a shared-object support for lame with the possibility
|
|
||||||
of static linkage
|
|
||||||
|
|
||||||
Revision 1.3 2000/11/11 12:33:13 darkeye
|
|
||||||
added kdoc-style documentation
|
|
||||||
|
|
||||||
Revision 1.2 2000/11/05 14:08:27 darkeye
|
|
||||||
changed builting to an automake / autoconf environment
|
|
||||||
|
|
||||||
Revision 1.1.1.1 2000/11/05 10:05:51 darkeye
|
|
||||||
initial version
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
|
|
|
@ -135,12 +135,22 @@ IceCast :: sendLogin ( void ) throw ( Exception )
|
||||||
sink->write( str, strlen( str));
|
sink->write( str, strlen( str));
|
||||||
str = getMountPoint();
|
str = getMountPoint();
|
||||||
sink->write( str, strlen( str));
|
sink->write( str, strlen( str));
|
||||||
str = "\n";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
|
|
||||||
/* send the x-audiocast headers */
|
/* send the x-audiocast headers */
|
||||||
|
str = "\nx-audiocast-bitrate: ";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
if ( snprintf( resp, STRBUF_SIZE, "%d", getBitRate()) == -1 ) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "snprintf overflow");
|
||||||
|
}
|
||||||
|
sink->write( resp, strlen( resp));
|
||||||
|
|
||||||
|
str = "\nx-audiocast-public: ";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
str = getIsPublic() ? "yes" : "no";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
|
||||||
if ( getName() ) {
|
if ( getName() ) {
|
||||||
str = "x-audiocast-name: ";
|
str = "\nx-audiocast-name: ";
|
||||||
sink->write( str, strlen( str));
|
sink->write( str, strlen( str));
|
||||||
str = getName();
|
str = getName();
|
||||||
sink->write( str, strlen( str));
|
sink->write( str, strlen( str));
|
||||||
|
@ -167,18 +177,6 @@ IceCast :: sendLogin ( void ) throw ( Exception )
|
||||||
sink->write( str, strlen( str));
|
sink->write( str, strlen( str));
|
||||||
}
|
}
|
||||||
|
|
||||||
str = "\nx-audiocast-bitrate: ";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
if ( snprintf( resp, STRBUF_SIZE, "%d", getBitRate()) == -1 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "snprintf overflow");
|
|
||||||
}
|
|
||||||
sink->write( resp, strlen( resp));
|
|
||||||
|
|
||||||
str = "\nx-audiocast-public: ";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
str = getIsPublic() ? "yes" : "no";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
|
|
||||||
if ( getRemoteDumpFile() ) {
|
if ( getRemoteDumpFile() ) {
|
||||||
str = "\nx-audiocast-dumpfile: ";
|
str = "\nx-audiocast-dumpfile: ";
|
||||||
sink->write( str, strlen( str));
|
sink->write( str, strlen( str));
|
||||||
|
@ -213,6 +211,9 @@ IceCast :: sendLogin ( void ) throw ( Exception )
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.8 2001/09/14 19:31:06 darkeye
|
||||||
|
added IceCast2 / vorbis support
|
||||||
|
|
||||||
Revision 1.7 2001/09/09 11:27:31 darkeye
|
Revision 1.7 2001/09/09 11:27:31 darkeye
|
||||||
added support for ShoutCast servers
|
added support for ShoutCast servers
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2000 Tyrell Corporation. All rights reserved.
|
||||||
|
|
||||||
|
Tyrell DarkIce
|
||||||
|
|
||||||
|
File : IceCast2.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
|
||||||
|
|
||||||
|
#ifdef HAVE_STDIO_H
|
||||||
|
#include <stdio.h>
|
||||||
|
#else
|
||||||
|
#error need stdio.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#else
|
||||||
|
#error need string.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "Exception.h"
|
||||||
|
#include "Source.h"
|
||||||
|
#include "Sink.h"
|
||||||
|
#include "Util.h"
|
||||||
|
#include "IceCast2.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* =================================================== local data structures */
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================ local constants & macros */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* File identity
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
static const char fileid[] = "$Id$";
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Size of string conversion buffer
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#define STRBUF_SIZE 32
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================== local function prototypes */
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================================================= module code */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Initialize the object
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
IceCast2 :: init ( const char * mountPoint,
|
||||||
|
const char * description )
|
||||||
|
throw ( Exception )
|
||||||
|
{
|
||||||
|
this->mountPoint = Util::strDup( mountPoint);
|
||||||
|
this->description = description ? Util::strDup( description) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* De-initialize the object
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
IceCast2 :: strip ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
delete[] mountPoint;
|
||||||
|
if ( description ) {
|
||||||
|
delete[] description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Log in to the IceCast2 server
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
bool
|
||||||
|
IceCast2 :: sendLogin ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
Sink * sink = getSink();
|
||||||
|
Source * source = getSocket();
|
||||||
|
const char * str;
|
||||||
|
char resp[STRBUF_SIZE];
|
||||||
|
|
||||||
|
if ( !source->isOpen() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( !sink->isOpen() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send the request, a string like:
|
||||||
|
* "SOURCE <mountpoint> ICE/1.0" */
|
||||||
|
str = "SOURCE /";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
str = getMountPoint();
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
str = " ICE/1.0";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
|
||||||
|
/* send the ice- headers */
|
||||||
|
str = "\nice-password: ";
|
||||||
|
sink->write( str, strlen(str));
|
||||||
|
str = getPassword();
|
||||||
|
sink->write( str, strlen(str));
|
||||||
|
|
||||||
|
str = "\nice-bitrate: ";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
if ( snprintf( resp, STRBUF_SIZE, "%d", getBitRate()) == -1 ) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "snprintf overflow");
|
||||||
|
}
|
||||||
|
sink->write( resp, strlen( resp));
|
||||||
|
|
||||||
|
str = "\nice-public: ";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
str = getIsPublic() ? "yes" : "no";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
|
||||||
|
if ( getName() ) {
|
||||||
|
str = "\nice-name: ";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
str = getName();
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( getDescription() ) {
|
||||||
|
str = "\nice-description: ";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
str = getDescription();
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( getUrl() ) {
|
||||||
|
str = "\nice-url: ";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
str = getUrl();
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( getGenre() ) {
|
||||||
|
str = "\nice-genre: ";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
str = getGenre();
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
}
|
||||||
|
|
||||||
|
str = "\n\n";
|
||||||
|
sink->write( str, strlen( str));
|
||||||
|
sink->flush();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
$Source$
|
||||||
|
|
||||||
|
$Log$
|
||||||
|
Revision 1.1 2001/09/14 19:31:06 darkeye
|
||||||
|
added IceCast2 / vorbis support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2000 Tyrell Corporation. All rights reserved.
|
||||||
|
|
||||||
|
Tyrell DarkIce
|
||||||
|
|
||||||
|
File : IceCast2.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 ICE_CAST2_H
|
||||||
|
#define ICE_CAST2_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#error This is a C++ include file
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================================================ include files */
|
||||||
|
|
||||||
|
#include "Sink.h"
|
||||||
|
#include "TcpSocket.h"
|
||||||
|
#include "CastSink.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================================ constants */
|
||||||
|
|
||||||
|
|
||||||
|
/* =================================================================== macros */
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================== data types */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing output to an IceCast2 server with
|
||||||
|
* ice login
|
||||||
|
*
|
||||||
|
* @author $Author$
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class IceCast2 : public CastSink
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mount point of the stream on the server.
|
||||||
|
*/
|
||||||
|
char * mountPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the stream.
|
||||||
|
*/
|
||||||
|
char * description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initalize the object.
|
||||||
|
*
|
||||||
|
* @param mountPoint mount point of the stream on the server.
|
||||||
|
* @param remoteDumpFile remote dump file (may be NULL).
|
||||||
|
* @param description description of the stream.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init ( const char * mountPoint,
|
||||||
|
const char * description )
|
||||||
|
throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De-initalize the object.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
strip ( void ) throw ( Exception );
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor. Always throws an Exception.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
IceCast2 ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
throw Exception( __FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log in to the server using the socket avialable.
|
||||||
|
*
|
||||||
|
* @return true if login was successful, false otherwise.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
virtual bool
|
||||||
|
sendLogin ( void ) throw ( Exception );
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param socket socket connection to the server.
|
||||||
|
* @param password password to the server.
|
||||||
|
* @param mountPoint mount point of the stream on the server.
|
||||||
|
* @param name name of the stream.
|
||||||
|
* @param description description of the stream.
|
||||||
|
* @param url URL associated with the stream.
|
||||||
|
* @param genre genre of the stream.
|
||||||
|
* @param bitRate bitrate of the stream (e.g. mp3 bitrate).
|
||||||
|
* @param isPublic is the stream public?
|
||||||
|
* @param bufferDuration duration of the BufferedSink buffer
|
||||||
|
* in seconds.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
IceCast2 ( TcpSocket * socket,
|
||||||
|
const char * password,
|
||||||
|
const char * mountPoint,
|
||||||
|
unsigned int bitRate,
|
||||||
|
const char * name = 0,
|
||||||
|
const char * description = 0,
|
||||||
|
const char * url = 0,
|
||||||
|
const char * genre = 0,
|
||||||
|
bool isPublic = false,
|
||||||
|
unsigned int bufferDuration = 10 )
|
||||||
|
throw ( Exception )
|
||||||
|
: CastSink( socket,
|
||||||
|
password,
|
||||||
|
bitRate,
|
||||||
|
name,
|
||||||
|
url,
|
||||||
|
genre,
|
||||||
|
isPublic,
|
||||||
|
bufferDuration )
|
||||||
|
{
|
||||||
|
init( mountPoint, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*
|
||||||
|
* @param cs the IceCast2 to copy.
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
IceCast2( const IceCast2 & cs ) throw ( Exception )
|
||||||
|
: CastSink( cs )
|
||||||
|
{
|
||||||
|
init( cs.getMountPoint(),
|
||||||
|
cs.getDescription() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline virtual
|
||||||
|
~IceCast2( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
strip();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assignment operator.
|
||||||
|
*
|
||||||
|
* @param cs the IceCast2 to assign this to.
|
||||||
|
* @return a reference to this IceCast2.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline virtual IceCast2 &
|
||||||
|
operator= ( const IceCast2 & cs ) throw ( Exception )
|
||||||
|
{
|
||||||
|
if ( this != &cs ) {
|
||||||
|
strip();
|
||||||
|
CastSink::operator=( cs );
|
||||||
|
init( cs.getMountPoint(),
|
||||||
|
cs.getDescription() );
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mount point of the stream on the server.
|
||||||
|
*
|
||||||
|
* @return the mount point of the stream on the server.
|
||||||
|
*/
|
||||||
|
inline const char *
|
||||||
|
getMountPoint ( void ) const throw ()
|
||||||
|
{
|
||||||
|
return mountPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the description of the stream.
|
||||||
|
*
|
||||||
|
* @return the description of the stream.
|
||||||
|
*/
|
||||||
|
inline const char *
|
||||||
|
getDescription ( void ) const throw ()
|
||||||
|
{
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================= external data structures */
|
||||||
|
|
||||||
|
|
||||||
|
/* ====================================================== function prototypes */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ICE_CAST2_H */
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
$Source$
|
||||||
|
|
||||||
|
$Log$
|
||||||
|
Revision 1.1 2001/09/14 19:31:06 darkeye
|
||||||
|
added IceCast2 / vorbis support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -69,8 +69,7 @@
|
||||||
* @author $Author$
|
* @author $Author$
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
class LameLibEncoder : public AudioEncoder, public virtual Reporter,
|
class LameLibEncoder : public AudioEncoder, public virtual Reporter
|
||||||
public Sink
|
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -463,6 +462,9 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter,
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.6 2001/09/14 19:31:06 darkeye
|
||||||
|
added IceCast2 / vorbis support
|
||||||
|
|
||||||
Revision 1.5 2001/09/02 09:54:12 darkeye
|
Revision 1.5 2001/09/02 09:54:12 darkeye
|
||||||
fixed typos in CVS substition keywords
|
fixed typos in CVS substition keywords
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,14 @@ darkice_SOURCES = AudioEncoder.h\
|
||||||
Exception.h\
|
Exception.h\
|
||||||
IceCast.cpp\
|
IceCast.cpp\
|
||||||
IceCast.h\
|
IceCast.h\
|
||||||
|
IceCast2.cpp\
|
||||||
|
IceCast2.h\
|
||||||
ShoutCast.cpp\
|
ShoutCast.cpp\
|
||||||
ShoutCast.h\
|
ShoutCast.h\
|
||||||
LameLibEncoder.cpp\
|
LameLibEncoder.cpp\
|
||||||
LameLibEncoder.h\
|
LameLibEncoder.h\
|
||||||
|
VorbisLibEncoder.cpp\
|
||||||
|
VorbisLibEncoder.h\
|
||||||
OssDspSource.cpp\
|
OssDspSource.cpp\
|
||||||
OssDspSource.h\
|
OssDspSource.h\
|
||||||
SolarisDspSource.cpp\
|
SolarisDspSource.cpp\
|
||||||
|
|
|
@ -0,0 +1,340 @@
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2000 Tyrell Corporation. All rights reserved.
|
||||||
|
|
||||||
|
Tyrell DarkIce
|
||||||
|
|
||||||
|
File : VorbisLibEncoder.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
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#else
|
||||||
|
#error need string.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "Exception.h"
|
||||||
|
#include "Util.h"
|
||||||
|
#include "VorbisLibEncoder.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* =================================================== local data structures */
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================ local constants & macros */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* File identity
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
static const char fileid[] = "$Id$";
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================== local function prototypes */
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================================================= module code */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Open an encoding session
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
bool
|
||||||
|
VorbisLibEncoder :: open ( void )
|
||||||
|
throw ( Exception )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ( isOpen() ) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
vorbis_info_init( &vorbisInfo);
|
||||||
|
if ( (ret = vorbis_encode_init( &vorbisInfo,
|
||||||
|
getInChannel(),
|
||||||
|
getInSampleRate(),
|
||||||
|
getOutBitrate(),
|
||||||
|
getOutBitrate(),
|
||||||
|
getOutBitrate() )) ) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "vorbis encode init error", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ret = vorbis_analysis_init( &vorbisDspState, &vorbisInfo)) ) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "vorbis analysis init error", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ret = vorbis_block_init( &vorbisDspState, &vorbisBlock)) ) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "vorbis block init error", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ret = ogg_stream_init( &oggStreamState, 0)) ) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "ogg stream init error", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// open the underlying sink
|
||||||
|
if ( !sink->open() ) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"vorbis lib opening underlying sink error");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an empty vorbis_comment structure
|
||||||
|
vorbis_comment vorbisComment;
|
||||||
|
|
||||||
|
vorbis_comment_init( &vorbisComment);
|
||||||
|
|
||||||
|
// create the vorbis stream headers and send them to the underlying sink
|
||||||
|
ogg_packet header;
|
||||||
|
ogg_packet commentHeader;
|
||||||
|
ogg_packet codeHeader;
|
||||||
|
|
||||||
|
if ( (ret = vorbis_analysis_headerout( &vorbisDspState,
|
||||||
|
&vorbisComment,
|
||||||
|
&header,
|
||||||
|
&commentHeader,
|
||||||
|
&codeHeader )) ) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "vorbis header init error", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
vorbis_comment_clear( &vorbisComment );
|
||||||
|
|
||||||
|
ogg_stream_packetin( &oggStreamState, &header);
|
||||||
|
ogg_stream_packetin( &oggStreamState, &commentHeader);
|
||||||
|
ogg_stream_packetin( &oggStreamState, &codeHeader);
|
||||||
|
|
||||||
|
ogg_page oggPage;
|
||||||
|
while ( ogg_stream_flush( &oggStreamState, &oggPage) ) {
|
||||||
|
sink->write( oggPage.header, oggPage.header_len);
|
||||||
|
sink->write( oggPage.body, oggPage.body_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
encoderOpen = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Convert an unsigned char buffer holding 8 bit PCM values with channels
|
||||||
|
* interleaved to two float buffers (one for each channel)
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
VorbisLibEncoder :: conv8 ( unsigned char * pcmBuffer,
|
||||||
|
unsigned int lenPcmBuffer,
|
||||||
|
float * leftBuffer,
|
||||||
|
float * rightBuffer,
|
||||||
|
unsigned int channels )
|
||||||
|
{
|
||||||
|
if ( channels == 1 ) {
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
||||||
|
short int value;
|
||||||
|
|
||||||
|
value = pcmBuffer[i++];
|
||||||
|
leftBuffer[j] = ((float) value) / 32768.f;
|
||||||
|
rightBuffer[j] = leftBuffer[j];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
||||||
|
short int value;
|
||||||
|
|
||||||
|
value = pcmBuffer[i++];
|
||||||
|
leftBuffer[j] = ((float) value) / 32768.f;
|
||||||
|
value = pcmBuffer[i++];
|
||||||
|
rightBuffer[j] = ((float) value) / 32768.f;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Convert an unsigned char buffer holding 16 bit PCM values with channels
|
||||||
|
* interleaved to two float buffers (one for each channel)
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
VorbisLibEncoder :: conv16 ( unsigned char * pcmBuffer,
|
||||||
|
unsigned int lenPcmBuffer,
|
||||||
|
float * leftBuffer,
|
||||||
|
float * rightBuffer,
|
||||||
|
unsigned int channels )
|
||||||
|
{
|
||||||
|
if ( channels == 1 ) {
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
||||||
|
short int value;
|
||||||
|
|
||||||
|
value = pcmBuffer[i++];
|
||||||
|
value += pcmBuffer[i++] << 8;
|
||||||
|
leftBuffer[j] = ((float) value) / 32768.f;
|
||||||
|
rightBuffer[j] = leftBuffer[j];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
||||||
|
short int value;
|
||||||
|
|
||||||
|
value = pcmBuffer[i++];
|
||||||
|
value += pcmBuffer[i++] << 8;
|
||||||
|
leftBuffer[j] = ((float) value) / 32768.f;
|
||||||
|
value = pcmBuffer[i++];
|
||||||
|
value += pcmBuffer[i++] << 8;
|
||||||
|
rightBuffer[j] = ((float) value) / 32768.f;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Write data to the encoder
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
unsigned int
|
||||||
|
VorbisLibEncoder :: write ( const void * buf,
|
||||||
|
unsigned int len ) throw ( Exception )
|
||||||
|
{
|
||||||
|
if ( !isOpen() ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int bitsPerSample = getInBitsPerSample();
|
||||||
|
unsigned int channels = getInChannel();
|
||||||
|
|
||||||
|
if ( channels != 1 && channels != 2 ) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"unsupported number of channels for the encoder",
|
||||||
|
channels );
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int sampleSize = (bitsPerSample / 8) * channels;
|
||||||
|
unsigned char * b = (unsigned char*) buf;
|
||||||
|
unsigned int processed = len - (len % sampleSize);
|
||||||
|
unsigned int nSamples = processed / sampleSize;
|
||||||
|
float ** vorbisBuffer;
|
||||||
|
|
||||||
|
vorbisBuffer = vorbis_analysis_buffer( &vorbisDspState, nSamples);
|
||||||
|
|
||||||
|
if ( bitsPerSample == 8 ) {
|
||||||
|
conv8( b, processed, vorbisBuffer[0], vorbisBuffer[1], channels);
|
||||||
|
} else if ( bitsPerSample == 16 ) {
|
||||||
|
conv16( b, processed, vorbisBuffer[0], vorbisBuffer[1], channels);
|
||||||
|
} else {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"unsupported number of bits per sample for the encoder",
|
||||||
|
bitsPerSample );
|
||||||
|
}
|
||||||
|
|
||||||
|
vorbis_analysis_wrote( &vorbisDspState, nSamples);
|
||||||
|
|
||||||
|
while ( 1 == vorbis_analysis_blockout( &vorbisDspState, &vorbisBlock) ) {
|
||||||
|
ogg_packet oggPacket;
|
||||||
|
ogg_page oggPage;
|
||||||
|
|
||||||
|
vorbis_analysis( &vorbisBlock, &oggPacket);
|
||||||
|
ogg_stream_packetin( &oggStreamState, &oggPacket);
|
||||||
|
|
||||||
|
while ( ogg_stream_pageout( &oggStreamState, &oggPage) ) {
|
||||||
|
int written;
|
||||||
|
|
||||||
|
written = sink->write( oggPage.header, oggPage.header_len);
|
||||||
|
reportEvent( 5, "written to server ", written, " bytes.");
|
||||||
|
if ( written < oggPage.header_len ) {
|
||||||
|
// just let go data that could not be written
|
||||||
|
reportEvent( 2,
|
||||||
|
"couldn't write full vorbis header to underlying sink",
|
||||||
|
oggPage.header_len - written);
|
||||||
|
}
|
||||||
|
|
||||||
|
written = sink->write( oggPage.body, oggPage.body_len);
|
||||||
|
reportEvent( 5, "written to server ", written, " bytes.");
|
||||||
|
if ( written < oggPage.body_len ) {
|
||||||
|
// just let go data that could not be written
|
||||||
|
reportEvent( 2,
|
||||||
|
"couldn't write full vorbis body to underlying sink",
|
||||||
|
oggPage.body_len - written);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return processed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Flush the data from the encoder
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
VorbisLibEncoder :: flush ( void )
|
||||||
|
throw ( Exception )
|
||||||
|
{
|
||||||
|
if ( !isOpen() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vorbis_analysis_wrote( &vorbisDspState, 0);
|
||||||
|
// ???
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Close the encoding session
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
VorbisLibEncoder :: close ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
if ( isOpen() ) {
|
||||||
|
flush();
|
||||||
|
|
||||||
|
ogg_stream_clear( &oggStreamState);
|
||||||
|
vorbis_block_clear( &vorbisBlock);
|
||||||
|
vorbis_dsp_clear( &vorbisDspState);
|
||||||
|
vorbis_info_clear( &vorbisInfo);
|
||||||
|
|
||||||
|
encoderOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
$Source$
|
||||||
|
|
||||||
|
$Log$
|
||||||
|
Revision 1.1 2001/09/14 19:31:06 darkeye
|
||||||
|
added IceCast2 / vorbis support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -0,0 +1,442 @@
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2000 Tyrell Corporation. All rights reserved.
|
||||||
|
|
||||||
|
Tyrell DarkIce
|
||||||
|
|
||||||
|
File : VorbisLibEncoder.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 VORBIS_LIB_ENCODER_H
|
||||||
|
#define VORBIS_LIB_ENCODER_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#error This is a C++ include file
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================================================ include files */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
#include <vorbis/vorbisenc.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "Ref.h"
|
||||||
|
#include "Exception.h"
|
||||||
|
#include "Reporter.h"
|
||||||
|
#include "AudioEncoder.h"
|
||||||
|
#include "Sink.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================================ constants */
|
||||||
|
|
||||||
|
|
||||||
|
/* =================================================================== macros */
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================== data types */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class representing the ogg vorbis encoder linked as a shared object or
|
||||||
|
* as a static library.
|
||||||
|
*
|
||||||
|
* @author $Author$
|
||||||
|
* @version $Revision$
|
||||||
|
*/
|
||||||
|
class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value indicating if the encoding process is going on
|
||||||
|
*/
|
||||||
|
bool encoderOpen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ogg Vorbis library global info
|
||||||
|
*/
|
||||||
|
vorbis_info vorbisInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ogg Vorbis library global DSP state
|
||||||
|
*/
|
||||||
|
vorbis_dsp_state vorbisDspState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ogg Vorbis library global block
|
||||||
|
*/
|
||||||
|
vorbis_block vorbisBlock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ogg library global stream state
|
||||||
|
*/
|
||||||
|
ogg_stream_state oggStreamState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Sink to dump mp3 data to
|
||||||
|
*/
|
||||||
|
Ref<Sink> sink;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the object.
|
||||||
|
*
|
||||||
|
* @param sink the sink to send mp3 output to
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline void
|
||||||
|
init ( Sink * sink ) throw ( Exception )
|
||||||
|
{
|
||||||
|
this->sink = sink;
|
||||||
|
|
||||||
|
if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"specified bits per sample not supported",
|
||||||
|
getInBitsPerSample() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( getOutSampleRate() != getInSampleRate() ) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"different in and out sample rate not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( getInChannel() != getOutChannel() ) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"different in and out channels not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
encoderOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De-initialize the object.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline void
|
||||||
|
strip ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a char buffer holding 8 bit PCM values to a short buffer
|
||||||
|
*
|
||||||
|
* @param pcmBuffer buffer holding 8 bit PCM audio values,
|
||||||
|
* channels are interleaved
|
||||||
|
* @param lenPcmBuffer length of pcmBuffer
|
||||||
|
* @param leftBuffer put the left channel here (must be big enough)
|
||||||
|
* @param rightBuffer put the right channel here (if mono, same
|
||||||
|
* as leftChannel, must be big enough)
|
||||||
|
* @param channels number of channels (1 = mono, 2 = stereo)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
conv8 ( unsigned char * pcmBuffer,
|
||||||
|
unsigned int lenPcmBuffer,
|
||||||
|
float * leftBuffer,
|
||||||
|
float * rightBuffer,
|
||||||
|
unsigned int channels );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a char buffer holding 16 bit PCM values to a short buffer
|
||||||
|
*
|
||||||
|
* @param pcmBuffer buffer holding 16 bit PCM audio values,
|
||||||
|
* channels are interleaved
|
||||||
|
* @param lenPcmBuffer length of pcmBuffer
|
||||||
|
* @param leftBuffer put the left channel here (must be big enough)
|
||||||
|
* @param rightBuffer put the right channel here (if mono, same
|
||||||
|
* as leftChannel, must be big enough)
|
||||||
|
* @param channels number of channels (1 = mono, 2 = stereo)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
conv16 ( unsigned char * pcmBuffer,
|
||||||
|
unsigned int lenPcmBuffer,
|
||||||
|
float * leftBuffer,
|
||||||
|
float * rightBuffer,
|
||||||
|
unsigned int channels );
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor. Always throws an Exception.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
VorbisLibEncoder ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
throw Exception( __FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param sink the sink to send mp3 output to
|
||||||
|
* @param inSampleRate sample rate of the input.
|
||||||
|
* @param inBitsPerSample number of bits per sample of the input.
|
||||||
|
* @param inChannel number of channels of the input.
|
||||||
|
* @param outBitrate bit rate of the output (bits/sec).
|
||||||
|
* @param outSampleRate sample rate of the output.
|
||||||
|
* If 0, inSampleRate is used.
|
||||||
|
* @param outChannel number of channels of the output.
|
||||||
|
* If 0, inChannel is used.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
VorbisLibEncoder ( Sink * sink,
|
||||||
|
unsigned int inSampleRate,
|
||||||
|
unsigned int inBitsPerSample,
|
||||||
|
unsigned int inChannel,
|
||||||
|
unsigned int outBitrate,
|
||||||
|
unsigned int outSampleRate = 0,
|
||||||
|
unsigned int outChannel = 0 )
|
||||||
|
throw ( Exception )
|
||||||
|
|
||||||
|
: AudioEncoder ( inSampleRate,
|
||||||
|
inBitsPerSample,
|
||||||
|
inChannel,
|
||||||
|
outBitrate,
|
||||||
|
outSampleRate,
|
||||||
|
outChannel )
|
||||||
|
{
|
||||||
|
init( sink);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param sink the sink to send mp3 output to
|
||||||
|
* @param as get input sample rate, bits per sample and channels
|
||||||
|
* from this AudioSource.
|
||||||
|
* @param outBitrate bit rate of the output (bits/sec).
|
||||||
|
* @param outSampleRate sample rate of the output.
|
||||||
|
* If 0, input sample rate is used.
|
||||||
|
* @param outChannel number of channels of the output.
|
||||||
|
* If 0, input channel is used.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
VorbisLibEncoder ( Sink * sink,
|
||||||
|
const AudioSource * as,
|
||||||
|
unsigned int outBitrate,
|
||||||
|
unsigned int outSampleRate = 0,
|
||||||
|
unsigned int outChannel = 0 )
|
||||||
|
throw ( Exception )
|
||||||
|
|
||||||
|
: AudioEncoder ( as,
|
||||||
|
outBitrate,
|
||||||
|
outSampleRate,
|
||||||
|
outChannel )
|
||||||
|
{
|
||||||
|
init( sink);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*
|
||||||
|
* @param encoder the VorbisLibEncoder to copy.
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
VorbisLibEncoder ( const VorbisLibEncoder & encoder )
|
||||||
|
throw ( Exception )
|
||||||
|
: AudioEncoder( encoder )
|
||||||
|
{
|
||||||
|
if( encoder.isOpen() ) {
|
||||||
|
throw Exception(__FILE__, __LINE__, "don't copy open encoders");
|
||||||
|
}
|
||||||
|
init( encoder.sink.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline virtual
|
||||||
|
~VorbisLibEncoder ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
if ( isOpen() ) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
strip();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assignment operator.
|
||||||
|
*
|
||||||
|
* @param encoder the VorbisLibEncoder to assign this to.
|
||||||
|
* @return a reference to this VorbisLibEncoder.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline virtual VorbisLibEncoder &
|
||||||
|
operator= ( const VorbisLibEncoder & encoder ) throw ( Exception )
|
||||||
|
{
|
||||||
|
if( encoder.isOpen() ) {
|
||||||
|
throw Exception(__FILE__, __LINE__, "don't copy open encoders");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this != &encoder ) {
|
||||||
|
strip();
|
||||||
|
AudioEncoder::operator=( encoder);
|
||||||
|
init( encoder.sink.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check wether encoding is in progress.
|
||||||
|
*
|
||||||
|
* @return true if encoding is in progress, false otherwise.
|
||||||
|
*/
|
||||||
|
inline virtual bool
|
||||||
|
isRunning ( void ) const throw ()
|
||||||
|
{
|
||||||
|
return isOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start encoding. This function returns as soon as possible,
|
||||||
|
* with encoding started in the background.
|
||||||
|
*
|
||||||
|
* @return true if encoding has started, false otherwise.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline virtual bool
|
||||||
|
start ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
return open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop encoding. Stops the encoding running in the background.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline virtual void
|
||||||
|
stop ( void ) throw ( Exception )
|
||||||
|
{
|
||||||
|
return close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open an encoding session.
|
||||||
|
*
|
||||||
|
* @return true if opening was successfull, false otherwise.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
virtual bool
|
||||||
|
open ( void ) throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the encoding session is open.
|
||||||
|
*
|
||||||
|
* @return true if the encoding session is open, false otherwise.
|
||||||
|
*/
|
||||||
|
inline virtual bool
|
||||||
|
isOpen ( void ) const throw ()
|
||||||
|
{
|
||||||
|
return encoderOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the encoder is ready to accept data.
|
||||||
|
*
|
||||||
|
* @param sec the maximum seconds to block.
|
||||||
|
* @param usec micro seconds to block after the full seconds.
|
||||||
|
* @return true if the encoder is ready to accept data,
|
||||||
|
* false otherwise.
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
inline virtual bool
|
||||||
|
canWrite ( unsigned int sec,
|
||||||
|
unsigned int usec ) throw ( Exception )
|
||||||
|
{
|
||||||
|
if ( !isOpen() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to the encoder.
|
||||||
|
* Buf is expected to be a sequence of big-endian 16 bit values,
|
||||||
|
* with left and right channels interleaved. Len is the number of
|
||||||
|
* bytes, must be a multiple of 4.
|
||||||
|
*
|
||||||
|
* @param buf the data to write.
|
||||||
|
* @param len number of bytes to write from buf.
|
||||||
|
* @return the number of bytes written (may be less than len).
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
virtual unsigned int
|
||||||
|
write ( const void * buf,
|
||||||
|
unsigned int len ) throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush all data that was written to the encoder to the underlying
|
||||||
|
* connection.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
virtual void
|
||||||
|
flush ( void ) throw ( Exception );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the encoding session.
|
||||||
|
*
|
||||||
|
* @exception Exception
|
||||||
|
*/
|
||||||
|
virtual void
|
||||||
|
close ( void ) throw ( Exception );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================= external data structures */
|
||||||
|
|
||||||
|
|
||||||
|
/* ====================================================== function prototypes */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* VORBIS_LIB_ENCODER_H */
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
$Source$
|
||||||
|
|
||||||
|
$Log$
|
||||||
|
Revision 1.1 2001/09/14 19:31:06 darkeye
|
||||||
|
added IceCast2 / vorbis support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in New Issue