Source Code (Use browser search to find items of interest.)
Class Index
kdelibs'Synth_PLAY_impl (./kdelibs/arts/flow/synth_play_impl.cc:37)
class Synth_PLAY_impl : virtual public Synth_PLAY_skel,
virtual public ASProducer,
virtual public IONotify
{
protected:
AudioSubSystem *as;
bool haveSubSys;
/*
* these are to prevent the following situation
* 1) audio subsystem needs more data
* 2) calculation is started
* 3) somehow, some module makes a synchronous invocation to the outside
* world and waits for the result
* 4) since the audio subsystem still needs data, and since we are in an
* idle state now, another calculation will be started, which will of
* course fail due to reentrancy
* 5) repeat 4) until result is there => lots of wasted CPU cycles (when
* running with realtime priority: system freeze)
*/
bool inProgress; // we are just doing some calculations
bool restartIOHandling; // I/O handlers removed upon reaching 4: restart
int audiofd;
typedef unsigned char uchar;
unsigned char *outblock;
unsigned long maxsamples;
unsigned long channels;
public:
/*
* functions from the SynthModule interface (which is inherited by
* SynthPlay)
*/
void firstInitialize() {
//cout << "Synth_PLAY: firstInitialize() called." << endl;
}
void initialize() {
as = AudioSubSystem::the();
//cout << "Synth_PLAY: initialize() called." << endl;
channels = as->channels();
maxsamples = 0;
outblock = 0;
inProgress = false;
haveSubSys = as->attachProducer(this);
if(!haveSubSys)
{
printf("SynthGenericPlay: audio subsystem is already used\n");
return;
}
audiofd = as->open(false);
if(audiofd < 0)
{
printf("SynthGenericPlay: audio subsystem init failed\n");
printf("ASError = %s\n",as->error());
return;
}
}
void start() {
//cout << "Synth_PLAY: start() called." << endl;
if(audiofd >= 0)
{
IOManager *iom = Dispatcher::the()->ioManager();
iom->watchFD(audiofd,IOType::write|IOType::except,this);
}
}
void deInitialize() {
cout << "Synth_PLAY: deInitialize() called." << endl;
artsdebug("SynthGenericPlay: closing audio fd\n");
if(audiofd >= 0)
{
IOManager *iom = Dispatcher::the()->ioManager();
iom->remove(this,IOType::all);
audiofd = 0;
}
AudioSubSystem::the()->detachProducer();
if(outblock)
{
delete[] outblock;
outblock = 0;
}
}
AutoSuspendState autoSuspend()
{
return asSuspendStop;
}
void calculateBlock(unsigned long samples)
{
// no audio subsystem, no play
if(!as->running() || !haveSubSys) return;
if(samples > maxsamples)
{
maxsamples = samples;
if(outblock) delete[] outblock;
outblock = new uchar[maxsamples * 4]; // 2 channels, 16 bit
}
assert(channels);
if(channels == 1)
convert_mono_float_16le(samples,invalue_left,outblock);
if(channels == 2)
convert_stereo_2float_i16le(samples,invalue_left,invalue_right,
outblock);
as->write(outblock,channels * 2 * samples);
}
/**
* notifyIO from the IONotify interface (IOManager)
*/
void notifyIO(int fd, int type)
{
if(!as->running())
{
printf("SynthGenericPlay: got notifyIO while audio subsystem"
"is down\n");
return;
}
assert(fd == audiofd);
switch(type)
{
case IOType::read: type = AudioSubSystem::ioRead;
break;
case IOType::write: type = AudioSubSystem::ioWrite;
break;
default: assert(false);
}
if(inProgress)
{
if(!restartIOHandling)
{
// prevent lots of retries - we just can't do calculations
// now, so we need to wait until the situation has resolved
Dispatcher::the()->ioManager()->remove(this,IOType::all);
restartIOHandling = true;
}
return;
}
restartIOHandling = false;
inProgress = true;
as->handleIO(type);
inProgress = false;
if(restartIOHandling) start();
}
/**
* needmore from the ASProducer interface (AudioSubSystem)
*/
void needMore()
{
_node()->requireFlow();
}
};
kdelibs'Synth_PLAY_impl::needMore() (./kdelibs/arts/flow/synth_play_impl.cc:201)
void needMore()
{
_node()->requireFlow();
}
};