added multiple outputs
added configuration reading added command line processing
This commit is contained in:
parent
7c682a8a12
commit
d9d97e3821
|
@ -73,9 +73,10 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <iostream.h>
|
#include <iostream.h>
|
||||||
|
#include <fstream.h>
|
||||||
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Util.h"
|
||||||
#include "DarkIce.h"
|
#include "DarkIce.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,51 +108,185 @@ static const char fileid[] = "$Id$";
|
||||||
|
|
||||||
/* ============================================================= module code */
|
/* ============================================================= module code */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Constructor
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
DarkIce :: DarkIce ( int argc,
|
||||||
|
char * argv[] ) throw ( Exception )
|
||||||
|
{
|
||||||
|
const char * configFileName = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while ( (i = getopt( argc, argv, "c:")) != -1 ) {
|
||||||
|
switch ( i ) {
|
||||||
|
case 'c':
|
||||||
|
configFileName = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case ':':
|
||||||
|
case '?':
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"error parsing command line options");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !configFileName ) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "no configuration file specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "configFileName: " << configFileName << endl;
|
||||||
|
|
||||||
|
ifstream configFile( configFileName);
|
||||||
|
Config config( configFile);
|
||||||
|
|
||||||
|
init( config);
|
||||||
|
|
||||||
|
cout << "no. of outputs: " << noOutputs << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Initialize the object
|
* Initialize the object
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
DarkIce :: init ( void ) throw ( Exception )
|
DarkIce :: init ( const Config & config ) throw ( Exception )
|
||||||
{
|
{
|
||||||
/* the pipes */
|
const ConfigSection * cs;
|
||||||
encOutPipe = new PipeSource( "enc.out");
|
const char * str;
|
||||||
encInPipe = new PipeSink( "enc.in");
|
unsigned int u, v, w;
|
||||||
|
int i;
|
||||||
|
|
||||||
if ( !encOutPipe->exists() ) {
|
// the [general] section
|
||||||
if ( !encOutPipe->create() ) {
|
if ( !(cs = config.get( "general")) ) {
|
||||||
throw Exception( __FILE__, __LINE__, "can't create out pipe");
|
throw Exception( __FILE__, __LINE__, "no section [general] in config");
|
||||||
|
}
|
||||||
|
str = cs->getForSure( "duration", " missing in section [general]");
|
||||||
|
duration = Util::strToL( str);
|
||||||
|
|
||||||
|
|
||||||
|
// the [input] section
|
||||||
|
if ( !(cs = config.get( "input")) ) {
|
||||||
|
throw Exception( __FILE__, __LINE__, "no section [general] in config");
|
||||||
|
}
|
||||||
|
|
||||||
|
str = cs->getForSure( "sampleRate", " missing in section [input]");
|
||||||
|
u = Util::strToL( str);
|
||||||
|
|
||||||
|
str = cs->getForSure( "bitsPerSample", " missing in section [input]");
|
||||||
|
v = Util::strToL( str);
|
||||||
|
|
||||||
|
str = cs->getForSure( "channel", " missing in section [input]");
|
||||||
|
w = Util::strToL( str);
|
||||||
|
|
||||||
|
str = cs->getForSure( "device", " missing in section [input]");
|
||||||
|
|
||||||
|
dsp = new OssDspSource( str, u, v, w);
|
||||||
|
encConnector = new Connector( dsp.get());
|
||||||
|
|
||||||
|
|
||||||
|
// look for lame encoder output streams, sections [lame0], [lame1], etc.
|
||||||
|
char lame[] = "lame ";
|
||||||
|
size_t lameLen = Util::strLen( lame);
|
||||||
|
char * pipeOutExt = ".out";
|
||||||
|
size_t pipeOutExtLen = Util::strLen( pipeOutExt);
|
||||||
|
char * pipeInExt = ".in";
|
||||||
|
size_t pipeInExtLen = Util::strLen( pipeInExt);
|
||||||
|
|
||||||
|
for ( i = 0; i < maxOutput; ++i ) {
|
||||||
|
// ugly hack to change the section name to "lame0", "lame1", etc.
|
||||||
|
lame[lameLen-1] = '0' + i;
|
||||||
|
|
||||||
|
if ( !(cs = config.get( lame)) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * encoder = 0;
|
||||||
|
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;
|
||||||
|
|
||||||
|
encoder = cs->getForSure( "encoder", " missing in section ", lame);
|
||||||
|
str = cs->getForSure( "bitrate", " missing in section ", lame);
|
||||||
|
bitrate = Util::strToL( str);
|
||||||
|
server = cs->getForSure( "server", " missing in section ", lame);
|
||||||
|
str = cs->getForSure( "port", " missing in section ", lame);
|
||||||
|
port = Util::strToL( str);
|
||||||
|
password = cs->getForSure( "password", " missing in section ", lame);
|
||||||
|
mountPoint = cs->getForSure( "mountPoint"," missing in section ",lame);
|
||||||
|
name = cs->getForSure( "name", " missing in section ", lame);
|
||||||
|
description = cs->getForSure("description"," missing in section ",lame);
|
||||||
|
url = cs->getForSure( "url", " missing in section ", lame);
|
||||||
|
genre = cs->getForSure( "genre", " missing in section ", lame);
|
||||||
|
str = cs->getForSure( "public", " missing in section ", lame);
|
||||||
|
isPublic = Util::strEq( str, "yes") ? true : false;
|
||||||
|
|
||||||
|
// generate the pipe names
|
||||||
|
char pipeOutName[lameLen + pipeOutExtLen + 1];
|
||||||
|
char pipeInName[lameLen + pipeInExtLen + 1];
|
||||||
|
|
||||||
|
Util::strCpy( pipeOutName, lame);
|
||||||
|
Util::strCat( pipeOutName, pipeOutExt);
|
||||||
|
Util::strCpy( pipeInName, lame);
|
||||||
|
Util::strCat( pipeInName, pipeInExt);
|
||||||
|
|
||||||
|
// go on and create the things
|
||||||
|
|
||||||
|
// the pipes
|
||||||
|
outputs[i].encOutPipe = new PipeSource( pipeOutName);
|
||||||
|
outputs[i].encInPipe = new PipeSink( pipeInName);
|
||||||
|
|
||||||
|
if ( !outputs[i].encOutPipe->exists() ) {
|
||||||
|
if ( !outputs[i].encOutPipe->create() ) {
|
||||||
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"can't create out pipe ",
|
||||||
|
pipeOutName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !encInPipe->exists() ) {
|
if ( !outputs[i].encInPipe->exists() ) {
|
||||||
if ( !encInPipe->create() ) {
|
if ( !outputs[i].encInPipe->create() ) {
|
||||||
throw Exception( __FILE__, __LINE__, "can't create in pipe");
|
throw Exception( __FILE__, __LINE__,
|
||||||
|
"can't create in pipe",
|
||||||
|
pipeInName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* encoder related stuff */
|
// encoder related stuff
|
||||||
dsp = new OssDspSource( "/dev/dsp", 22050, 16, 2);
|
outputs[i].encIn = new BufferedSink( outputs[i].encInPipe.get(),
|
||||||
encIn = new BufferedSink( encInPipe.get(), 64 * 1024);
|
64 * 1024);
|
||||||
encConnector = new Connector( dsp.get(), encInPipe.get());
|
encConnector->attach( outputs[i].encIn.get());
|
||||||
encoder = new LameEncoder( "notlame",
|
outputs[i].encoder = new LameEncoder( encoder,
|
||||||
encInPipe->getFileName(),
|
outputs[i].encInPipe->getFileName(),
|
||||||
dsp.get(),
|
dsp.get(),
|
||||||
encOutPipe->getFileName(),
|
outputs[i].encOutPipe->getFileName(),
|
||||||
96 );
|
bitrate );
|
||||||
|
|
||||||
|
|
||||||
/* streaming related stuff */
|
// streaming related stuff
|
||||||
socket = new TcpSocket( "susi", 8000);
|
outputs[i].socket = new TcpSocket( server, port);
|
||||||
ice = new IceCast( socket.get(),
|
outputs[i].ice = new IceCast( outputs[i].socket.get(),
|
||||||
"hackme",
|
password,
|
||||||
"sample",
|
mountPoint,
|
||||||
"name",
|
name,
|
||||||
"description",
|
description,
|
||||||
"http://ez.az/",
|
url,
|
||||||
"sajat",
|
genre,
|
||||||
128,
|
bitrate,
|
||||||
false );
|
isPublic );
|
||||||
shoutConnector = new Connector( encOutPipe.get(), ice.get());
|
outputs[i].shoutConnector = new Connector( outputs[i].encOutPipe.get(),
|
||||||
|
outputs[i].ice.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
noOutputs = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,8 +297,11 @@ bool
|
||||||
DarkIce :: encode ( void ) throw ( Exception )
|
DarkIce :: encode ( void ) throw ( Exception )
|
||||||
{
|
{
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
int i;
|
||||||
|
|
||||||
encoder->start();
|
for ( i = 0; i < noOutputs; ++i ) {
|
||||||
|
outputs[i].encoder->start();
|
||||||
|
}
|
||||||
|
|
||||||
sleep( 1 );
|
sleep( 1 );
|
||||||
|
|
||||||
|
@ -171,13 +309,21 @@ DarkIce :: encode ( void ) throw ( Exception )
|
||||||
throw Exception( __FILE__, __LINE__, "can't open connector");
|
throw Exception( __FILE__, __LINE__, "can't open connector");
|
||||||
}
|
}
|
||||||
|
|
||||||
len = encConnector->transfer( 22050 * 2 * 2 * 120, 4096, 1, 0 );
|
len = encConnector->transfer( dsp->getSampleRate() *
|
||||||
|
(dsp->getBitsPerSample() / 8) *
|
||||||
|
dsp->getChannel() *
|
||||||
|
duration,
|
||||||
|
4096,
|
||||||
|
1,
|
||||||
|
0 );
|
||||||
|
|
||||||
cout << len << " bytes transfered" << endl;
|
cout << len << " bytes transfered" << endl;
|
||||||
|
|
||||||
encConnector->close();
|
encConnector->close();
|
||||||
|
|
||||||
encoder->stop();
|
for ( i = 0; i < noOutputs; ++i ) {
|
||||||
|
outputs[i].encoder->stop();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -187,19 +333,29 @@ DarkIce :: encode ( void ) throw ( Exception )
|
||||||
* Run the encoder
|
* Run the encoder
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
bool
|
bool
|
||||||
DarkIce :: shout ( void ) throw ( Exception )
|
DarkIce :: shout ( unsigned int ix ) throw ( Exception )
|
||||||
{
|
{
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
if ( !shoutConnector->open() ) {
|
if ( ix >= noOutputs ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !outputs[ix].shoutConnector->open() ) {
|
||||||
throw Exception( __FILE__, __LINE__, "can't open connector");
|
throw Exception( __FILE__, __LINE__, "can't open connector");
|
||||||
}
|
}
|
||||||
|
|
||||||
len = shoutConnector->transfer( 128 * 1024 / 8 * 120, 4096, 1, 0 );
|
len = outputs[ix].shoutConnector->transfer (
|
||||||
|
outputs[ix].encoder->getOutBitrate()
|
||||||
|
* (1024 / 8)
|
||||||
|
* duration,
|
||||||
|
4096,
|
||||||
|
1,
|
||||||
|
0 );
|
||||||
|
|
||||||
cout << len << " bytes transfered" << endl;
|
cout << len << " bytes transfered" << endl;
|
||||||
|
|
||||||
shoutConnector->close();
|
outputs[ix].shoutConnector->close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -214,32 +370,6 @@ DarkIce :: run ( void ) throw ( Exception )
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
cout << "DarkIce" << endl << endl << flush;
|
cout << "DarkIce" << endl << endl << flush;
|
||||||
/*
|
|
||||||
Config config;
|
|
||||||
const ConfigSection * cs;
|
|
||||||
const char * str;
|
|
||||||
|
|
||||||
config.read( cin);
|
|
||||||
|
|
||||||
cs = config.get( "first");
|
|
||||||
if ( cs ) {
|
|
||||||
str = cs->get( "blahblah");
|
|
||||||
cout << str << endl;
|
|
||||||
str = cs->get( "ejj");
|
|
||||||
cout << str << endl;
|
|
||||||
str = cs->get( "ojj");
|
|
||||||
cout << str << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
cs = config.get( "second");
|
|
||||||
if ( cs ) {
|
|
||||||
str = cs->get( "blahblah");
|
|
||||||
cout << str << endl;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
init();
|
|
||||||
|
|
||||||
cout << "init OK" << endl << flush;
|
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
|
|
||||||
|
@ -248,11 +378,14 @@ DarkIce :: run ( void ) throw ( Exception )
|
||||||
|
|
||||||
} else if ( pid == 0 ) {
|
} else if ( pid == 0 ) {
|
||||||
// this is the child
|
// this is the child
|
||||||
|
int i;
|
||||||
|
|
||||||
sleep ( 2 );
|
sleep ( 2 );
|
||||||
|
|
||||||
cout << "shouting" << endl << flush;
|
cout << "shouting" << endl << flush;
|
||||||
shout();
|
for ( i = 0; i < noOutputs; ++i ) {
|
||||||
|
shout( i);
|
||||||
|
}
|
||||||
cout << "shouting ends" << endl << flush;
|
cout << "shouting ends" << endl << flush;
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -280,6 +413,11 @@ DarkIce :: run ( void ) throw ( Exception )
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.4 2000/11/09 22:09:46 darkeye
|
||||||
|
added multiple outputs
|
||||||
|
added configuration reading
|
||||||
|
added command line processing
|
||||||
|
|
||||||
Revision 1.3 2000/11/08 17:29:50 darkeye
|
Revision 1.3 2000/11/08 17:29:50 darkeye
|
||||||
added configuration file reader
|
added configuration file reader
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "PipeSource.h"
|
#include "PipeSource.h"
|
||||||
#include "TcpSocket.h"
|
#include "TcpSocket.h"
|
||||||
#include "IceCast.h"
|
#include "IceCast.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
/* ================================================================ constants */
|
||||||
|
@ -71,20 +72,29 @@ class DarkIce : public virtual Referable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Ref<OssDspSource> dsp;
|
static const unsigned int maxOutput = 8;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
Ref<PipeSink> encInPipe;
|
Ref<PipeSink> encInPipe;
|
||||||
Ref<BufferedSink> encIn;
|
Ref<BufferedSink> encIn;
|
||||||
Ref<Connector> encConnector;
|
|
||||||
Ref<LameEncoder> encoder;
|
Ref<LameEncoder> encoder;
|
||||||
|
|
||||||
Ref<PipeSource> encOutPipe;
|
Ref<PipeSource> encOutPipe;
|
||||||
Ref<TcpSocket> socket;
|
Ref<TcpSocket> socket;
|
||||||
Ref<IceCast> ice;
|
Ref<IceCast> ice;
|
||||||
Ref<Connector> shoutConnector;
|
Ref<Connector> shoutConnector;
|
||||||
|
} Output;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int duration;
|
||||||
|
Ref<OssDspSource> dsp;
|
||||||
|
Ref<Connector> encConnector;
|
||||||
|
|
||||||
|
Output outputs[maxOutput];
|
||||||
|
unsigned int noOutputs;
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
init ( void ) throw ( Exception );
|
init ( const Config & config ) throw ( Exception );
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -92,7 +102,7 @@ class DarkIce : public virtual Referable
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
shout ( void ) throw ( Exception );
|
shout ( unsigned int ) throw ( Exception );
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -109,11 +119,8 @@ class DarkIce : public virtual Referable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
DarkIce ( int argc,
|
DarkIce ( int argc,
|
||||||
char * argv[] ) throw ()
|
char * argv[] ) throw ( Exception );
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline virtual
|
inline virtual
|
||||||
|
@ -157,8 +164,13 @@ class DarkIce : public virtual Referable
|
||||||
$Source$
|
$Source$
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.1 2000/11/05 10:05:50 darkeye
|
Revision 1.2 2000/11/09 22:09:46 darkeye
|
||||||
Initial revision
|
added multiple outputs
|
||||||
|
added configuration reading
|
||||||
|
added command line processing
|
||||||
|
|
||||||
|
Revision 1.1.1.1 2000/11/05 10:05:50 darkeye
|
||||||
|
initial version
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
------------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in New Issue