added initial implementation of file dump cutting, re #3
This commit is contained in:
parent
cf2d4c85f0
commit
ee4ae648d0
|
@ -1,12 +1,14 @@
|
|||
DarkIce next release
|
||||
|
||||
o added logging facility - [file-X] targets will cut the saved file
|
||||
and rename it as needed when darkice recieves the SIGUSR1 signal
|
||||
o added default configuration file handling - if no configuration file
|
||||
is specified, /etc/darkice.cfg is used
|
||||
o fix to enable compiling on 64 bit platforms
|
||||
thanks to Alexander Vlasov <zulu@galaradio.com> and
|
||||
is specified, /etc/darkice.cfg is used
|
||||
o fix to enable compiling on 64 bit platforms
|
||||
thanks to Alexander Vlasov <zulu@galaradio.com> and
|
||||
Mariusz Mazur <mmazur@kernel.pl>
|
||||
o fix to enable file dump feature using ogg vorbis.
|
||||
thanks to <derrick@csociety.org>
|
||||
o fix to enable file dump feature using ogg vorbis.
|
||||
thanks to <derrick@csociety.org>
|
||||
|
||||
|
||||
19-05-2006 DarkIce 0.17.1 released
|
||||
|
|
|
@ -71,6 +71,11 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The Sink to dump the encoded data to
|
||||
*/
|
||||
Ref<Sink> sink;
|
||||
|
||||
/**
|
||||
* Sample rate of the input.
|
||||
*/
|
||||
|
@ -119,6 +124,7 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
/**
|
||||
* Initialize the object.
|
||||
*
|
||||
* @param sink the sink to send encoded 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.
|
||||
|
@ -130,7 +136,8 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
* @exception Exception
|
||||
*/
|
||||
inline void
|
||||
init ( unsigned int inSampleRate,
|
||||
init ( Sink * sink,
|
||||
unsigned int inSampleRate,
|
||||
unsigned int inBitsPerSample,
|
||||
unsigned int inChannel,
|
||||
bool inBigEndian,
|
||||
|
@ -140,6 +147,7 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
unsigned int outSampleRate,
|
||||
unsigned int outChannel ) throw ( Exception )
|
||||
{
|
||||
this->sink = sink;
|
||||
this->inSampleRate = inSampleRate;
|
||||
this->inBitsPerSample = inBitsPerSample;
|
||||
this->inChannel = inChannel;
|
||||
|
@ -182,6 +190,7 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param sink the sink to send encoded 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.
|
||||
|
@ -196,7 +205,8 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
* @exception Exception
|
||||
*/
|
||||
inline
|
||||
AudioEncoder ( unsigned int inSampleRate,
|
||||
AudioEncoder ( Sink * sink,
|
||||
unsigned int inSampleRate,
|
||||
unsigned int inBitsPerSample,
|
||||
unsigned int inChannel,
|
||||
bool inBigEndian,
|
||||
|
@ -207,7 +217,8 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
unsigned int outChannel = 0 )
|
||||
throw ( Exception )
|
||||
{
|
||||
init ( inSampleRate,
|
||||
init ( sink,
|
||||
inSampleRate,
|
||||
inBitsPerSample,
|
||||
inChannel,
|
||||
inBigEndian,
|
||||
|
@ -221,6 +232,7 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param sink the sink to send encoded output to
|
||||
* @param as get input sample rate, bits per sample and channels
|
||||
* from this AudioSource.
|
||||
* @param outBitrateMode the bit rate mode of the output.
|
||||
|
@ -233,7 +245,8 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
* @exception Exception
|
||||
*/
|
||||
inline
|
||||
AudioEncoder ( const AudioSource * as,
|
||||
AudioEncoder ( Sink * sink,
|
||||
const AudioSource * as,
|
||||
BitrateMode outBitrateMode,
|
||||
unsigned int outBitrate,
|
||||
double outQuality,
|
||||
|
@ -241,7 +254,8 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
unsigned int outChannel = 0 )
|
||||
throw ( Exception)
|
||||
{
|
||||
init( as->getSampleRate(),
|
||||
init( sink,
|
||||
as->getSampleRate(),
|
||||
as->getBitsPerSample(),
|
||||
as->getChannel(),
|
||||
as->isBigEndian(),
|
||||
|
@ -260,7 +274,8 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
inline
|
||||
AudioEncoder ( const AudioEncoder & encoder ) throw ( Exception )
|
||||
{
|
||||
init ( encoder.inSampleRate,
|
||||
init ( encoder.sink.get(),
|
||||
encoder.inSampleRate,
|
||||
encoder.inBitsPerSample,
|
||||
encoder.inChannel,
|
||||
encoder.inBigEndian,
|
||||
|
@ -284,7 +299,8 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
if ( this != &encoder ) {
|
||||
strip();
|
||||
|
||||
init ( encoder.inSampleRate,
|
||||
init ( encoder.sink.get(),
|
||||
encoder.inSampleRate,
|
||||
encoder.inBitsPerSample,
|
||||
encoder.inChannel,
|
||||
encoder.inBigEndian,
|
||||
|
@ -312,6 +328,17 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
strip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying sink, that the encoded content is sent to.
|
||||
*
|
||||
* @return the underlying sink
|
||||
*/
|
||||
inline virtual Ref<Sink>
|
||||
getSink(void) throw ()
|
||||
{
|
||||
return sink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of channels of the input.
|
||||
*
|
||||
|
@ -438,6 +465,20 @@ class AudioEncoder : public Sink, public virtual Referable
|
|||
*/
|
||||
virtual void
|
||||
stop ( void ) throw ( Exception ) = 0;
|
||||
|
||||
/**
|
||||
* Cut what the sink has been doing so far, and start anew.
|
||||
* This usually means separating the data sent to the sink up
|
||||
* until now, and start saving a new chunk of data.
|
||||
*
|
||||
* Typically this action is delegated to the underlying sink.
|
||||
*/
|
||||
inline virtual void
|
||||
cut ( void ) throw ()
|
||||
{
|
||||
sink->cut();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -366,6 +366,18 @@ class BufferedSink : public Sink, public virtual Reporter
|
|||
write( b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut what the sink has been doing so far, and start anew.
|
||||
* This usually means separating the data sent to the sink up
|
||||
* until now, and start saving a new chunk of data.
|
||||
*/
|
||||
inline virtual void
|
||||
cut ( void ) throw ()
|
||||
{
|
||||
flush();
|
||||
sink->cut();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the BufferedSink. Closes the underlying Sink.
|
||||
*
|
||||
|
|
|
@ -362,6 +362,19 @@ class CastSink : public Sink, public virtual Reporter
|
|||
return getSink()->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut what the sink has been doing so far, and start anew.
|
||||
* This usually means separating the data sent to the sink up
|
||||
* until now, and start saving a new chunk of data.
|
||||
*/
|
||||
inline virtual void
|
||||
cut ( void ) throw ()
|
||||
{
|
||||
if ( streamDump != 0 ) {
|
||||
streamDump->cut();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the CastSink.
|
||||
*
|
||||
|
|
|
@ -325,6 +325,22 @@ Connector :: transfer ( unsigned long bytes,
|
|||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Signal to each sink to cut what they've done so far, and start anew.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
Connector :: cut ( void ) throw ()
|
||||
{
|
||||
unsigned int u;
|
||||
|
||||
for ( u = 0; u < numSinks; ++u ) {
|
||||
if ( sinks[u]->isOpen() ) {
|
||||
sinks[u]->cut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Close the source and all the sinks if needed
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -234,6 +234,15 @@ class Connector : public virtual Referable, public virtual Reporter
|
|||
unsigned int sec,
|
||||
unsigned int usec ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* Signal to each sink we have that they need to cut what they are
|
||||
* doing, and start again. For FileSinks, this usually means to
|
||||
* save the archive file recorded so far, and start a new archive
|
||||
* file.
|
||||
*/
|
||||
virtual void
|
||||
cut ( void ) throw ();
|
||||
|
||||
/**
|
||||
* Close the Connector. The Source and all Sinks are closed.
|
||||
*
|
||||
|
|
|
@ -1137,6 +1137,20 @@ DarkIce :: run ( void ) throw ( Exception )
|
|||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Tell each sink to cut what they are doing, and start again.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
DarkIce :: cut ( void ) throw ()
|
||||
{
|
||||
reportEvent( 5, "cutting");
|
||||
|
||||
encConnector->cut();
|
||||
|
||||
reportEvent( 5, "cutting ends");
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
$Source$
|
||||
|
|
|
@ -296,6 +296,15 @@ class DarkIce : public virtual Referable, public virtual Reporter
|
|||
virtual int
|
||||
run ( void ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* Signal to each sink we have that they need to cut what they are
|
||||
* doing, and start again. For FileSinks, this usually means to
|
||||
* save the archive file recorded so far, and start a new archive
|
||||
* file.
|
||||
*/
|
||||
virtual void
|
||||
cut ( void ) throw ();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ FaacEncoder :: open ( void )
|
|||
}
|
||||
|
||||
// open the underlying sink
|
||||
if ( !sink->open() ) {
|
||||
if ( !getSink()->open() ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"faac lib opening underlying sink error");
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ FaacEncoder :: write ( const void * buf,
|
|||
inSamples,
|
||||
faacBuf,
|
||||
maxOutputBytes);
|
||||
sink->write(faacBuf, outputBytes);
|
||||
getSink()->write(faacBuf, outputBytes);
|
||||
|
||||
processedSamples += inSamples;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ FaacEncoder :: flush ( void )
|
|||
return;
|
||||
}
|
||||
|
||||
sink->flush();
|
||||
getSink()->flush();
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,7 +182,7 @@ FaacEncoder :: close ( void ) throw ( Exception )
|
|||
faacEncClose(encoderHandle);
|
||||
faacOpen = false;
|
||||
|
||||
sink->close();
|
||||
getSink()->close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,15 +98,9 @@ class FaacEncoder : public AudioEncoder, public virtual Reporter
|
|||
*/
|
||||
int lowpass;
|
||||
|
||||
/**
|
||||
* The Sink to dump mp3 data to
|
||||
*/
|
||||
Ref<Sink> sink;
|
||||
|
||||
/**
|
||||
* Initialize the object.
|
||||
*
|
||||
* @param sink the sink to send mp3 output to
|
||||
* @param lowpass frequency threshold for the lowpass filter.
|
||||
* Input above this frequency is cut.
|
||||
* If 0, faac's default values are used,
|
||||
|
@ -114,11 +108,9 @@ class FaacEncoder : public AudioEncoder, public virtual Reporter
|
|||
* @exception Exception
|
||||
*/
|
||||
inline void
|
||||
init ( Sink * sink,
|
||||
int lowpass) throw (Exception)
|
||||
init ( int lowpass) throw (Exception)
|
||||
{
|
||||
this->faacOpen = false;
|
||||
this->sink = sink;
|
||||
this->lowpass = lowpass;
|
||||
|
||||
if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) {
|
||||
|
@ -205,7 +197,8 @@ class FaacEncoder : public AudioEncoder, public virtual Reporter
|
|||
int lowpass = 0)
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( inSampleRate,
|
||||
: AudioEncoder ( sink,
|
||||
inSampleRate,
|
||||
inBitsPerSample,
|
||||
inChannel,
|
||||
inBigEndian,
|
||||
|
@ -215,7 +208,7 @@ class FaacEncoder : public AudioEncoder, public virtual Reporter
|
|||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink, lowpass);
|
||||
init( lowpass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -248,14 +241,15 @@ class FaacEncoder : public AudioEncoder, public virtual Reporter
|
|||
int lowpass = 0)
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( as,
|
||||
: AudioEncoder ( sink,
|
||||
as,
|
||||
outBitrateMode,
|
||||
outBitrate,
|
||||
outQuality,
|
||||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink, lowpass);
|
||||
init( lowpass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,7 +262,7 @@ class FaacEncoder : public AudioEncoder, public virtual Reporter
|
|||
throw ( Exception )
|
||||
: AudioEncoder( encoder )
|
||||
{
|
||||
init( encoder.sink.get(), encoder.lowpass);
|
||||
init( encoder.lowpass);
|
||||
}
|
||||
|
||||
|
||||
|
@ -299,7 +293,7 @@ class FaacEncoder : public AudioEncoder, public virtual Reporter
|
|||
if ( this != &encoder ) {
|
||||
strip();
|
||||
AudioEncoder::operator=( encoder);
|
||||
init( encoder.sink.get(), encoder.lowpass);
|
||||
init( encoder.lowpass);
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
|
|
@ -238,6 +238,17 @@ class FileCast : public CastSink
|
|||
return targetFile->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut what the sink has been doing so far, and start anew.
|
||||
* This usually means separating the data sent to the sink up
|
||||
* until now, and start saving a new chunk of data.
|
||||
*/
|
||||
inline virtual void
|
||||
cut ( void ) throw ()
|
||||
{
|
||||
targetFile->cut();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the FileCast.
|
||||
*
|
||||
|
|
|
@ -81,6 +81,17 @@
|
|||
#error need string.h
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#else
|
||||
#error need signal.h
|
||||
#endif
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
#include "Util.h"
|
||||
#include "Exception.h"
|
||||
|
@ -242,7 +253,8 @@ FileSink :: canWrite ( unsigned int sec,
|
|||
unsigned int usec ) throw ( Exception )
|
||||
{
|
||||
fd_set fdset;
|
||||
struct timeval tv;
|
||||
struct timespec timespec;
|
||||
sigset_t sigset;
|
||||
int ret;
|
||||
|
||||
if ( !isOpen() ) {
|
||||
|
@ -251,10 +263,15 @@ FileSink :: canWrite ( unsigned int sec,
|
|||
|
||||
FD_ZERO( &fdset);
|
||||
FD_SET( fileDescriptor, &fdset);
|
||||
tv.tv_sec = sec;
|
||||
tv.tv_usec = usec;
|
||||
|
||||
ret = select( fileDescriptor + 1, NULL, &fdset, NULL, &tv);
|
||||
timespec.tv_sec = sec;
|
||||
timespec.tv_nsec = usec * 1000L;
|
||||
|
||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGUSR1);
|
||||
|
||||
ret = pselect( fileDescriptor + 1, NULL, &fdset, NULL, ×pec, &sigset);
|
||||
|
||||
if ( ret == -1 ) {
|
||||
throw Exception( __FILE__, __LINE__, "select error");
|
||||
|
@ -291,6 +308,58 @@ FileSink :: write ( const void * buf,
|
|||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Get the file name to where to move the data saved so far.
|
||||
* The trick is to read the file name from a file named
|
||||
* /tmp/darkice.$PID , where $PID is the current process id
|
||||
*----------------------------------------------------------------------------*/
|
||||
std::string
|
||||
FileSink :: getArchiveFileName ( void ) throw ( Exception )
|
||||
{
|
||||
pid_t pid = getpid();
|
||||
std::stringstream metaFileName;
|
||||
|
||||
metaFileName << "/tmp/darkice." << pid;
|
||||
|
||||
std::ifstream ifs(metaFileName.str().c_str());
|
||||
if (!ifs.good()) {
|
||||
throw Exception(__FILE__, __LINE__,
|
||||
"can't find file ", metaFileName.str().c_str(), 0);
|
||||
}
|
||||
|
||||
std::string archiveFileName;
|
||||
ifs >> archiveFileName;
|
||||
ifs.close();
|
||||
|
||||
return archiveFileName;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Cut what we've done so far, and start anew.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
FileSink :: cut ( void ) throw ()
|
||||
{
|
||||
flush();
|
||||
close();
|
||||
|
||||
try {
|
||||
std::string archiveFileName = getArchiveFileName();
|
||||
|
||||
if (::rename(fileName, archiveFileName.c_str()) != 0) {
|
||||
reportEvent(2, "couldn't move file", fileName,
|
||||
"to", archiveFileName);
|
||||
}
|
||||
|
||||
} catch ( Exception &e ) {
|
||||
reportEvent(2, "error during archive cut", e);
|
||||
}
|
||||
|
||||
create();
|
||||
open();
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Close the FileSink
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -80,6 +80,16 @@ class FileSink : public Sink, public virtual Reporter
|
|||
void
|
||||
strip ( void ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* Get the file name to where to move the data saved so far.
|
||||
* Used in cut().
|
||||
*
|
||||
* @return the file name where to move the data saved so far.
|
||||
* @throws Exception on file operation errors
|
||||
*/
|
||||
std::string
|
||||
getArchiveFileName( void ) throw ( Exception );
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -227,6 +237,14 @@ class FileSink : public Sink, public virtual Reporter
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut what the sink has been doing so far, and start anew.
|
||||
* This usually means separating the data sent to the sink up
|
||||
* until now, and start saving a new chunk of data.
|
||||
*/
|
||||
virtual void
|
||||
cut ( void ) throw ();
|
||||
|
||||
/**
|
||||
* Close the FileSink.
|
||||
*
|
||||
|
|
|
@ -69,6 +69,12 @@
|
|||
#error need string.h
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#else
|
||||
#error need signal.h
|
||||
#endif
|
||||
|
||||
|
||||
#include "Exception.h"
|
||||
#include "Util.h"
|
||||
|
@ -197,7 +203,8 @@ FileSource :: canRead ( unsigned int sec,
|
|||
unsigned int usec ) throw ( Exception )
|
||||
{
|
||||
fd_set fdset;
|
||||
struct timeval tv;
|
||||
struct timespec timespec;
|
||||
sigset_t sigset;
|
||||
int ret;
|
||||
|
||||
if ( !isOpen() ) {
|
||||
|
@ -206,10 +213,15 @@ FileSource :: canRead ( unsigned int sec,
|
|||
|
||||
FD_ZERO( &fdset);
|
||||
FD_SET( fileDescriptor, &fdset);
|
||||
tv.tv_sec = sec;
|
||||
tv.tv_usec = usec;
|
||||
|
||||
ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv);
|
||||
timespec.tv_sec = sec;
|
||||
timespec.tv_nsec = usec * 1000L;
|
||||
|
||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGUSR1);
|
||||
|
||||
ret = pselect( fileDescriptor + 1, &fdset, NULL, NULL, ×pec, &sigset);
|
||||
|
||||
if ( ret == -1 ) {
|
||||
throw Exception( __FILE__, __LINE__, "select error");
|
||||
|
|
|
@ -71,7 +71,7 @@ LameLibEncoder :: open ( void )
|
|||
}
|
||||
|
||||
// open the underlying sink
|
||||
if ( !sink->open() ) {
|
||||
if ( !getSink()->open() ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"lame lib opening underlying sink error");
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ LameLibEncoder :: write ( const void * buf,
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int written = sink->write( mp3Buf, ret);
|
||||
unsigned int written = getSink()->write( mp3Buf, ret);
|
||||
delete[] mp3Buf;
|
||||
// just let go data that could not be written
|
||||
if ( written < (unsigned int) ret ) {
|
||||
|
@ -362,7 +362,7 @@ LameLibEncoder :: flush ( void )
|
|||
|
||||
ret = lame_encode_flush( lameGlobalFlags, mp3Buf, mp3Size );
|
||||
|
||||
unsigned int written = sink->write( mp3Buf, ret);
|
||||
unsigned int written = getSink()->write( mp3Buf, ret);
|
||||
delete[] mp3Buf;
|
||||
|
||||
// just let go data that could not be written
|
||||
|
@ -372,7 +372,7 @@ LameLibEncoder :: flush ( void )
|
|||
ret - written);
|
||||
}
|
||||
|
||||
sink->flush();
|
||||
getSink()->flush();
|
||||
}
|
||||
|
||||
|
||||
|
@ -387,7 +387,7 @@ LameLibEncoder :: close ( void ) throw ( Exception )
|
|||
lame_close( lameGlobalFlags);
|
||||
lameGlobalFlags = 0;
|
||||
|
||||
sink->close();
|
||||
getSink()->close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,11 +78,6 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
*/
|
||||
lame_global_flags * lameGlobalFlags;
|
||||
|
||||
/**
|
||||
* The Sink to dump mp3 data to
|
||||
*/
|
||||
Ref<Sink> sink;
|
||||
|
||||
/**
|
||||
* Lowpass filter. Sound frequency in Hz, from where up the
|
||||
* input is cut.
|
||||
|
@ -98,7 +93,6 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
/**
|
||||
* Initialize the object.
|
||||
*
|
||||
* @param sink the sink to send mp3 output to
|
||||
* @param lowpass frequency threshold for the lowpass filter.
|
||||
* Input above this frequency is cut.
|
||||
* If 0, lame's default values are used,
|
||||
|
@ -110,12 +104,10 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
* @exception Exception
|
||||
*/
|
||||
inline void
|
||||
init ( Sink * sink,
|
||||
int lowpass,
|
||||
init ( int lowpass,
|
||||
int highpass ) throw ( Exception )
|
||||
{
|
||||
this->lameGlobalFlags = NULL;
|
||||
this->sink = sink;
|
||||
this->lowpass = lowpass;
|
||||
this->highpass = highpass;
|
||||
|
||||
|
@ -209,7 +201,8 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
int highpass = 0 )
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( inSampleRate,
|
||||
: AudioEncoder ( sink,
|
||||
inSampleRate,
|
||||
inBitsPerSample,
|
||||
inChannel,
|
||||
inBigEndian,
|
||||
|
@ -219,7 +212,7 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink, lowpass, highpass);
|
||||
init( lowpass, highpass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,14 +250,15 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
int highpass = 0 )
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( as,
|
||||
: AudioEncoder ( sink,
|
||||
as,
|
||||
outBitrateMode,
|
||||
outBitrate,
|
||||
outQuality,
|
||||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink, lowpass, highpass);
|
||||
init( lowpass, highpass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -277,7 +271,7 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
throw ( Exception )
|
||||
: AudioEncoder( encoder )
|
||||
{
|
||||
init( encoder.sink.get(), encoder.lowpass, encoder.highpass );
|
||||
init( encoder.lowpass, encoder.highpass );
|
||||
}
|
||||
|
||||
|
||||
|
@ -308,7 +302,7 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
if ( this != &encoder ) {
|
||||
strip();
|
||||
AudioEncoder::operator=( encoder);
|
||||
init( encoder.sink.get(), encoder.lowpass, encoder.highpass );
|
||||
init( encoder.lowpass, encoder.highpass );
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
|
|
@ -293,6 +293,11 @@ MultiThreadedConnector :: sinkThread( int ixSink )
|
|||
break;
|
||||
}
|
||||
|
||||
if ( threadData->cut) {
|
||||
sink->cut();
|
||||
threadData->cut = false;
|
||||
}
|
||||
|
||||
if ( threadData->accepting ) {
|
||||
if ( sink->canWrite( 0, 0) ) {
|
||||
try {
|
||||
|
@ -337,6 +342,22 @@ MultiThreadedConnector :: sinkThread( int ixSink )
|
|||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Signal to each sink to cut what they've done so far, and start anew.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MultiThreadedConnector :: cut ( void ) throw ()
|
||||
{
|
||||
for ( unsigned int i = 0; i < numSinks; ++i ) {
|
||||
threads[i].cut = true;
|
||||
}
|
||||
|
||||
// TODO: it might be more appropriate to signal all the threads here
|
||||
// but, they'll get signaled on new data anyway, and it might be
|
||||
// enough for them to cut at that time
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Stop the treads
|
||||
* Close the source and all the sinks if needed
|
||||
|
|
|
@ -107,6 +107,12 @@ class MultiThreadedConnector : public virtual Connector
|
|||
*/
|
||||
bool isDone;
|
||||
|
||||
/**
|
||||
* A flag to show that the sink should be made to cut in the
|
||||
* next iteration.
|
||||
*/
|
||||
bool cut;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
|
@ -118,6 +124,7 @@ class MultiThreadedConnector : public virtual Connector
|
|||
this->thread = 0;
|
||||
this->accepting = false;
|
||||
this->isDone = false;
|
||||
this->cut = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -313,6 +320,15 @@ class MultiThreadedConnector : public virtual Connector
|
|||
unsigned int sec,
|
||||
unsigned int usec ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* Signal to each sink we have that they need to cut what they are
|
||||
* doing, and start again. For FileSinks, this usually means to
|
||||
* save the archive file recorded so far, and start a new archive
|
||||
* file.
|
||||
*/
|
||||
virtual void
|
||||
cut ( void ) throw ();
|
||||
|
||||
/**
|
||||
* Close the Connector. The Source and all Sinks are closed.
|
||||
*
|
||||
|
@ -322,7 +338,7 @@ class MultiThreadedConnector : public virtual Connector
|
|||
close ( void ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* This is the function for each thread.
|
||||
* This is the worker function for each thread.
|
||||
* This function has to return fast
|
||||
*
|
||||
* @param ixSink the index of the sink this thread works on.
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#error need sys/ioctl.h
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#else
|
||||
#error need signal.h
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOUNDCARD_H
|
||||
#include <sys/soundcard.h>
|
||||
#else
|
||||
|
@ -230,7 +236,8 @@ OssDspSource :: canRead ( unsigned int sec,
|
|||
unsigned int usec ) throw ( Exception )
|
||||
{
|
||||
fd_set fdset;
|
||||
struct timeval tv;
|
||||
struct timespec timespec;
|
||||
sigset_t sigset;
|
||||
int ret;
|
||||
|
||||
if ( !isOpen() ) {
|
||||
|
@ -247,10 +254,15 @@ OssDspSource :: canRead ( unsigned int sec,
|
|||
|
||||
FD_ZERO( &fdset);
|
||||
FD_SET( fileDescriptor, &fdset);
|
||||
tv.tv_sec = sec;
|
||||
tv.tv_usec = usec;
|
||||
|
||||
ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv);
|
||||
timespec.tv_sec = sec;
|
||||
timespec.tv_nsec = usec * 1000L;
|
||||
|
||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGUSR1);
|
||||
|
||||
ret = pselect( fileDescriptor + 1, &fdset, NULL, NULL, ×pec, &sigset);
|
||||
|
||||
if ( ret == -1 ) {
|
||||
throw Exception( __FILE__, __LINE__, "select error");
|
||||
|
|
|
@ -156,6 +156,14 @@ class Sink : public virtual Referable
|
|||
virtual void
|
||||
flush ( void ) throw ( Exception ) = 0;
|
||||
|
||||
/**
|
||||
* Cut what the sink has been doing so far, and start anew.
|
||||
* This usually means separating the data sent to the sink up
|
||||
* until now, and start saving a new chunk of data.
|
||||
*/
|
||||
virtual void
|
||||
cut ( void ) throw () = 0;
|
||||
|
||||
/**
|
||||
* Close the Sink.
|
||||
*
|
||||
|
|
|
@ -80,6 +80,12 @@
|
|||
#error need sys/ioctl.h
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#else
|
||||
#error need signal.h
|
||||
#endif
|
||||
|
||||
#if defined( HAVE_SYS_AUDIO_H )
|
||||
#include <sys/audio.h>
|
||||
#elif defined( HAVE_SYS_AUDIOIO_H )
|
||||
|
@ -202,7 +208,8 @@ SolarisDspSource :: canRead ( unsigned int sec,
|
|||
unsigned int usec ) throw ( Exception )
|
||||
{
|
||||
fd_set fdset;
|
||||
struct timeval tv;
|
||||
struct timespec timespec;
|
||||
sigset_t sigset;
|
||||
int ret;
|
||||
|
||||
if ( !isOpen() ) {
|
||||
|
@ -211,10 +218,15 @@ SolarisDspSource :: canRead ( unsigned int sec,
|
|||
|
||||
FD_ZERO( &fdset);
|
||||
FD_SET( fileDescriptor, &fdset);
|
||||
tv.tv_sec = sec;
|
||||
tv.tv_usec = usec;
|
||||
|
||||
ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv);
|
||||
timespec.tv_sec = sec;
|
||||
timespec.tv_nsec = usec * 1000L;
|
||||
|
||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGUSR1);
|
||||
|
||||
ret = pselect( fileDescriptor + 1, &fdset, NULL, NULL, ×pec, &sigset);
|
||||
|
||||
if ( ret == -1 ) {
|
||||
throw Exception( __FILE__, __LINE__, "select error");
|
||||
|
|
|
@ -81,6 +81,12 @@
|
|||
#error need sys/time.h
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#else
|
||||
#error need signal.h
|
||||
#endif
|
||||
|
||||
|
||||
#include "Util.h"
|
||||
#include "Exception.h"
|
||||
|
@ -243,7 +249,8 @@ TcpSocket :: canRead ( unsigned int sec,
|
|||
unsigned int usec ) throw ( Exception )
|
||||
{
|
||||
fd_set fdset;
|
||||
struct timeval tv;
|
||||
struct timespec timespec;
|
||||
sigset_t sigset;
|
||||
int ret;
|
||||
|
||||
if ( !isOpen() ) {
|
||||
|
@ -252,10 +259,15 @@ TcpSocket :: canRead ( unsigned int sec,
|
|||
|
||||
FD_ZERO( &fdset);
|
||||
FD_SET( sockfd, &fdset);
|
||||
tv.tv_sec = sec;
|
||||
tv.tv_usec = usec;
|
||||
|
||||
ret = select( sockfd + 1, &fdset, NULL, NULL, &tv);
|
||||
timespec.tv_sec = sec;
|
||||
timespec.tv_nsec = usec * 1000L;
|
||||
|
||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGUSR1);
|
||||
|
||||
ret = pselect( sockfd + 1, &fdset, NULL, NULL, ×pec, &sigset);
|
||||
|
||||
if ( ret == -1 ) {
|
||||
throw Exception( __FILE__, __LINE__, "select error");
|
||||
|
@ -305,7 +317,8 @@ TcpSocket :: canWrite ( unsigned int sec,
|
|||
unsigned int usec ) throw ( Exception )
|
||||
{
|
||||
fd_set fdset;
|
||||
struct timeval tv;
|
||||
struct timespec timespec;
|
||||
sigset_t sigset;
|
||||
int ret;
|
||||
|
||||
if ( !isOpen() ) {
|
||||
|
@ -314,10 +327,15 @@ TcpSocket :: canWrite ( unsigned int sec,
|
|||
|
||||
FD_ZERO( &fdset);
|
||||
FD_SET( sockfd, &fdset);
|
||||
tv.tv_sec = sec;
|
||||
tv.tv_usec = usec;
|
||||
|
||||
ret = select( sockfd + 1, NULL, &fdset, NULL, &tv);
|
||||
timespec.tv_sec = sec;
|
||||
timespec.tv_nsec = usec * 1000L;
|
||||
|
||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGUSR1);
|
||||
|
||||
ret = pselect( sockfd + 1, NULL, &fdset, NULL, ×pec, &sigset);
|
||||
|
||||
if ( ret == -1 ) {
|
||||
throw Exception( __FILE__, __LINE__, "select error");
|
||||
|
|
|
@ -258,6 +258,18 @@ class TcpSocket : public Source, public Sink
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut what the sink has been doing so far, and start anew.
|
||||
* This usually means separating the data sent to the sink up
|
||||
* until now, and start saving a new chunk of data.
|
||||
*
|
||||
* For TcpSocket, this is a no-op.
|
||||
*/
|
||||
inline virtual void
|
||||
cut ( void ) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the TcpSocket.
|
||||
*
|
||||
|
|
|
@ -65,10 +65,9 @@ static const char fileid[] = "$Id$";
|
|||
* Initialize the object
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
TwoLameLibEncoder :: init ( Sink * sink ) throw ( Exception )
|
||||
TwoLameLibEncoder :: init ( void ) throw ( Exception )
|
||||
{
|
||||
this->twolame_opts = NULL;
|
||||
this->sink = sink;
|
||||
|
||||
if ( getInBitsPerSample() != 16 ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
|
@ -106,7 +105,7 @@ TwoLameLibEncoder :: open ( void )
|
|||
}
|
||||
|
||||
// open the underlying sink
|
||||
if ( !sink->open() ) {
|
||||
if ( !getSink()->open() ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"TwoLAME lib opening underlying sink error");
|
||||
}
|
||||
|
@ -239,7 +238,7 @@ TwoLameLibEncoder :: write ( const void * buf,
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int written = sink->write( mp2Buf, ret);
|
||||
unsigned int written = getSink()->write( mp2Buf, ret);
|
||||
delete[] mp2Buf;
|
||||
// just let go data that could not be written
|
||||
if ( written < (unsigned int) ret ) {
|
||||
|
@ -270,7 +269,7 @@ TwoLameLibEncoder :: flush ( void )
|
|||
|
||||
ret = twolame_encode_flush( twolame_opts, mp2Buf, mp2Size );
|
||||
|
||||
unsigned int written = sink->write( mp2Buf, ret);
|
||||
unsigned int written = getSink()->write( mp2Buf, ret);
|
||||
delete[] mp2Buf;
|
||||
|
||||
// just let go data that could not be written
|
||||
|
@ -280,7 +279,7 @@ TwoLameLibEncoder :: flush ( void )
|
|||
ret - written);
|
||||
}
|
||||
|
||||
sink->flush();
|
||||
getSink()->flush();
|
||||
}
|
||||
|
||||
|
||||
|
@ -293,7 +292,7 @@ TwoLameLibEncoder :: close ( void ) throw ( Exception )
|
|||
if ( isOpen() ) {
|
||||
flush();
|
||||
twolame_close( &twolame_opts );
|
||||
sink->close();
|
||||
getSink()->close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,11 +78,6 @@ class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
*/
|
||||
twolame_options * twolame_opts;
|
||||
|
||||
/**
|
||||
* The Sink to dump mp2 data to
|
||||
*/
|
||||
Ref<Sink> sink;
|
||||
|
||||
/**
|
||||
* Initialize the object.
|
||||
*
|
||||
|
@ -90,7 +85,7 @@ class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
* @exception Exception
|
||||
*/
|
||||
void
|
||||
init ( Sink * sink ) throw ( Exception );
|
||||
init ( void ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* De-initialize the object.
|
||||
|
@ -147,7 +142,8 @@ class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
unsigned int outChannel = 0 )
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( inSampleRate,
|
||||
: AudioEncoder ( sink,
|
||||
inSampleRate,
|
||||
inBitsPerSample,
|
||||
inChannel,
|
||||
inBigEndian,
|
||||
|
@ -157,7 +153,7 @@ class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink );
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,14 +179,15 @@ class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
unsigned int outChannel = 0 )
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( as,
|
||||
: AudioEncoder ( sink,
|
||||
as,
|
||||
outBitrateMode,
|
||||
outBitrate,
|
||||
0.0f, // outQuality
|
||||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink );
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,7 +200,7 @@ class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
throw ( Exception )
|
||||
: AudioEncoder( encoder )
|
||||
{
|
||||
init( encoder.sink.get() );
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -234,7 +231,7 @@ class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
if ( this != &encoder ) {
|
||||
strip();
|
||||
AudioEncoder::operator=( encoder);
|
||||
init( encoder.sink.get() );
|
||||
init();
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
|
|
@ -62,11 +62,9 @@ static const char fileid[] = "$Id$";
|
|||
* Initialize the encoder
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
VorbisLibEncoder :: init ( CastSink * sink,
|
||||
unsigned int outMaxBitrate )
|
||||
VorbisLibEncoder :: init ( unsigned int outMaxBitrate )
|
||||
throw ( Exception )
|
||||
{
|
||||
this->sink = sink;
|
||||
this->outMaxBitrate = outMaxBitrate;
|
||||
|
||||
if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) {
|
||||
|
@ -140,7 +138,7 @@ VorbisLibEncoder :: open ( void )
|
|||
}
|
||||
|
||||
// open the underlying sink
|
||||
if ( !sink->open() ) {
|
||||
if ( !getSink()->open() ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"vorbis lib opening underlying sink error");
|
||||
}
|
||||
|
@ -206,11 +204,17 @@ VorbisLibEncoder :: open ( void )
|
|||
|
||||
// create an empty vorbis_comment structure
|
||||
vorbis_comment_init( &vorbisComment);
|
||||
/* FIXME: removed title metadata when the sink type was changed from
|
||||
* CastSink to the more generic Sink.
|
||||
* make sure to add metadata somehow
|
||||
// Add comment to vorbis headers to show title in players
|
||||
// stupid cast to (char*) because of stupid vorbis API
|
||||
if ( sink->getName() ) {
|
||||
vorbis_comment_add_tag(&vorbisComment, "TITLE", (char*)sink->getName());
|
||||
if ( getSink()->getName() ) {
|
||||
vorbis_comment_add_tag(&vorbisComment,
|
||||
"TITLE",
|
||||
(char*) getSink()->getName());
|
||||
}
|
||||
*/
|
||||
|
||||
// create the vorbis stream headers and send them to the underlying sink
|
||||
ogg_packet header;
|
||||
|
@ -231,8 +235,8 @@ VorbisLibEncoder :: open ( void )
|
|||
|
||||
ogg_page oggPage;
|
||||
while ( ogg_stream_flush( &oggStreamState, &oggPage) ) {
|
||||
sink->write( oggPage.header, oggPage.header_len);
|
||||
sink->write( oggPage.body, oggPage.body_len);
|
||||
getSink()->write( oggPage.header, oggPage.header_len);
|
||||
getSink()->write( oggPage.body, oggPage.body_len);
|
||||
}
|
||||
|
||||
vorbis_comment_clear( &vorbisComment );
|
||||
|
@ -346,7 +350,7 @@ VorbisLibEncoder :: flush ( void )
|
|||
|
||||
vorbis_analysis_wrote( &vorbisDspState, 0);
|
||||
vorbisBlocksOut();
|
||||
sink->flush();
|
||||
getSink()->flush();
|
||||
}
|
||||
|
||||
|
||||
|
@ -370,8 +374,8 @@ VorbisLibEncoder :: vorbisBlocksOut ( void ) throw ( Exception )
|
|||
while ( ogg_stream_pageout( &oggStreamState, &oggPage) ) {
|
||||
int written;
|
||||
|
||||
written = sink->write( oggPage.header, oggPage.header_len);
|
||||
written += sink->write( oggPage.body, oggPage.body_len);
|
||||
written = getSink()->write(oggPage.header, oggPage.header_len);
|
||||
written += getSink()->write( oggPage.body, oggPage.body_len);
|
||||
|
||||
if ( written < oggPage.header_len + oggPage.body_len ) {
|
||||
// just let go data that could not be written
|
||||
|
@ -402,7 +406,7 @@ VorbisLibEncoder :: close ( void ) throw ( Exception )
|
|||
|
||||
encoderOpen = false;
|
||||
|
||||
sink->close();
|
||||
getSink()->close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -104,11 +104,6 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
*/
|
||||
ogg_stream_state oggStreamState;
|
||||
|
||||
/**
|
||||
* The Sink to dump encoded data to
|
||||
*/
|
||||
Ref<CastSink> sink;
|
||||
|
||||
/**
|
||||
* Maximum bitrate of the output in kbits/sec. If 0, don't care.
|
||||
*/
|
||||
|
@ -127,13 +122,11 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
/**
|
||||
* Initialize the object.
|
||||
*
|
||||
* @param sink the sink to send encoded output to
|
||||
* @param the maximum bit rate
|
||||
* @exception Exception
|
||||
*/
|
||||
void
|
||||
init ( CastSink * sink,
|
||||
unsigned int outMaxBitrate ) throw ( Exception );
|
||||
init ( unsigned int outMaxBitrate ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* De-initialize the object.
|
||||
|
@ -204,7 +197,8 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
unsigned int outMaxBitrate = 0 )
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( inSampleRate,
|
||||
: AudioEncoder ( sink,
|
||||
inSampleRate,
|
||||
inBitsPerSample,
|
||||
inChannel,
|
||||
inBigEndian,
|
||||
|
@ -214,7 +208,7 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink, outMaxBitrate);
|
||||
init( outMaxBitrate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,14 +239,15 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
unsigned int outMaxBitrate = 0 )
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( as,
|
||||
: AudioEncoder ( sink,
|
||||
as,
|
||||
outBitrateMode,
|
||||
outBitrate,
|
||||
outQuality,
|
||||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink, outMaxBitrate);
|
||||
init( outMaxBitrate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,7 +263,7 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
if( encoder.isOpen() ) {
|
||||
throw Exception(__FILE__, __LINE__, "don't copy open encoders");
|
||||
}
|
||||
init( encoder.sink.get(), encoder.getOutMaxBitrate() );
|
||||
init( encoder.getOutMaxBitrate() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -302,7 +297,7 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
|
|||
if ( this != &encoder ) {
|
||||
strip();
|
||||
AudioEncoder::operator=( encoder);
|
||||
init( encoder.sink.get(), encoder.getOutMaxBitrate() );
|
||||
init( encoder.getOutMaxBitrate() );
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
|
|
@ -43,6 +43,12 @@
|
|||
#error needs stdlib.h
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#else
|
||||
#error needs signal.h
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
|
@ -54,6 +60,11 @@
|
|||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* The DarkIce object we're running
|
||||
*----------------------------------------------------------------------------*/
|
||||
static Ref<DarkIce> darkice;
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
|
@ -76,6 +87,12 @@ static const char *DEFAULT_CONFIG_FILE = "/etc/darkice.cfg";
|
|||
static void
|
||||
showUsage ( std::ostream & os );
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Handler for the SIGUSR1 signal
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
sigusr1Handler(int value);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
|
@ -126,9 +143,12 @@ main (
|
|||
Reporter::setReportVerbosity( verbosity );
|
||||
Reporter::setReportOutputStream( std::cout );
|
||||
Config config( configFile);
|
||||
Ref<DarkIce> di = new DarkIce( config);
|
||||
|
||||
res = di->run();
|
||||
darkice = new DarkIce( config);
|
||||
|
||||
signal(SIGUSR1, sigusr1Handler);
|
||||
|
||||
res = darkice->run();
|
||||
|
||||
} catch ( Exception & e ) {
|
||||
std::cout << "DarkIce: " << e << std::endl << std::flush;
|
||||
|
@ -162,6 +182,16 @@ showUsage ( std::ostream & os )
|
|||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Handle the SIGUSR1 signal here
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
sigusr1Handler(int value)
|
||||
{
|
||||
darkice->cut();
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
$Source$
|
||||
|
|
Loading…
Reference in New Issue