Commit 5d29fcff authored by sletz's avatar sletz
Browse files

rebase from trunk 3613:3638

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3639 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 187a3aed
......@@ -23,7 +23,31 @@ Paul Davis
---------------------------
Jackdmp changes log
---------------------------
---------------------------
2009-08-28 Stephane Letz <letz@grame.fr>
* Correct monitor port naming in JackAudioDriver and JackCoreAudioDriver.
* Big endian bug fix in memops.c (http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=11_be24bit.patch;att=1;bug=486308)
2009-07-31 Stephane Letz <letz@grame.fr>
* Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend.
2009-07-29 Stephane Letz <letz@grame.fr>
* Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period).
2009-07-28 Stephane Letz <letz@grame.fr>
* Fix CopyAndConvertIn for Solaris backends.
2009-07-22 Stephane Letz <letz@grame.fr>
* Version 1.9.4 started.
* Solaris boomer backend now working in capture or playback only mode.
* Fix control.h for proper compilation on Solaris.
2009-07-17 Stephane Letz <letz@grame.fr>
......
......@@ -42,7 +42,6 @@ Known problems, limitations
- use of POSIX named semaphore is currently unstable and not recommended yet.
----------------
Solaris version
----------------
......
......@@ -139,12 +139,13 @@ int JackAudioDriver::Attach()
// Monitor ports
if (fWithMonitorPorts) {
jack_log("Create monitor port ");
snprintf(name, sizeof(name) - 1, "%s:%s:monitor_%u", fAliasName, fPlaybackDriverName, i + 1);
snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1);
if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) {
jack_error("Cannot register monitor port for %s", name);
return -1;
} else {
port = fGraphManager->GetPort(port_index);
port->SetAlias(alias);
port->SetLatency(fEngineControl->fBufferSize);
fMonitorPortList[i] = port_index;
}
......
......@@ -24,7 +24,7 @@
#include "config.h"
#endif
#define VERSION "1.9.3"
#define VERSION "1.9.4"
#define BUFFER_SIZE_MAX 8192
......
......@@ -31,7 +31,9 @@
#include <jack/jslist.h>
#include <jack/systemdeps.h>
#if !defined (__sun__)
#include <stdbool.h>
#endif
/** Parameter types, intentionally similar to jack_driver_param_type_t */
typedef enum
......
......@@ -481,7 +481,7 @@ void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned
x <<= 8;
x |= (unsigned char)(src[0]);
/* correct sign bit and the rest of the top byte */
if (src[0] & 0x80) {
if (src[2] & 0x80) {
x |= 0xff << 24;
}
#endif
......
......@@ -106,10 +106,10 @@ SERVER_EXPORT void audio_release(const char * device_name)
}
if (i < DEVICE_MAX) {
jack_info("Released audio card %s", device_name);
jack_info("Released audio card %s", device_name);
rd_release(gReservedDevice[i].reserved_device);
} else {
jack_error("Audio card %s not found!!", device_name);
jack_error("Audio card %s not found!!", device_name);
}
// Close DBus connection last time
......
......@@ -1763,7 +1763,8 @@ JACK_DBUS_METHOD_ARGUMENTS_BEGIN(DisconnectPortsByConnectionID)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetClientPID)
JACK_DBUS_METHOD_ARGUMENT("client_id", DBUS_TYPE_INT64_AS_STRING, false)
JACK_DBUS_METHOD_ARGUMENT("client_id", DBUS_TYPE_UINT64_AS_STRING, false)
JACK_DBUS_METHOD_ARGUMENT("process_id", DBUS_TYPE_INT64_AS_STRING, true)
JACK_DBUS_METHOD_ARGUMENTS_END
JACK_DBUS_METHODS_BEGIN
......
......@@ -23,7 +23,7 @@ PROJECT_NAME = "Jack2"
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 1.9.3
PROJECT_NUMBER = 1.9.4
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
......
......@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>Jackservermp</string>
<key>CFBundleGetInfoString</key>
<string>Jackdmp 1.9.3, @03-09 Paul Davis, Grame</string>
<string>Jackdmp 1.9.4, @03-09 Paul Davis, Grame</string>
<key>CFBundleIdentifier</key>
<string>com.grame.Jackmp</string>
<key>CFBundleInfoDictionaryVersion</key>
......@@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.9.3</string>
<string>1.9.4</string>
</dict>
</plist>
......@@ -126,13 +126,13 @@ UInt32 JackMachThread::GetThreadPriority(pthread_t thread, int inWhichPriority)
return 0;
}
int JackMachThread::GetParams(UInt64* period, UInt64* computation, UInt64* constraint)
int JackMachThread::GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint)
{
thread_time_constraint_policy_data_t theTCPolicy;
mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT;
boolean_t get_default = false;
kern_return_t res = thread_policy_get(pthread_mach_thread_np(pthread_self()),
kern_return_t res = thread_policy_get(pthread_mach_thread_np(thread),
THREAD_TIME_CONSTRAINT_POLICY,
(thread_policy_t) & theTCPolicy,
&count,
......@@ -187,7 +187,7 @@ int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 c
UInt64 int_period;
UInt64 int_computation;
UInt64 int_constraint;
GetParams(&int_period, &int_computation, &int_constraint);
GetParams(thread, &int_period, &int_computation, &int_constraint);
return 0;
}
......
......@@ -109,7 +109,7 @@ class SERVER_EXPORT JackMachThread : public JackPosixThread
int AcquireRealTime(int priority);
int DropRealTime();
void SetParams(UInt64 period, UInt64 computation, UInt64 constraint);
static int GetParams(UInt64* period, UInt64* computation, UInt64* constraint);
static int GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint);
static int SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint);
static int AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint);
......
......@@ -10846,7 +10846,7 @@
CoreFoundation,
);
OTHER_REZFLAGS = "";
PRODUCT_NAME = jack_midiseq;
PRODUCT_NAME = jack_showtime;
REZ_EXECUTABLE = YES;
SDKROOT = "";
SECTORDER_FLAGS = "";
......
......@@ -21,6 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackError.h"
#include <unistd.h>
#include <CoreServices/CoreServices.h>
namespace Jack
{
......
......@@ -218,7 +218,12 @@ OSStatus JackCoreAudioDriver::MeasureCallback(AudioDeviceID inDevice,
AudioDeviceStop(driver->fDeviceID, MeasureCallback);
jack_log("JackCoreAudioDriver::MeasureCallback called");
JackMachThread::GetParams(&driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint);
JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint);
if (driver->fComputationGrain > 0) {
jack_log("JackCoreAudioDriver::MeasureCallback : RT thread computation setup to %ld percent of period", int(driver->fComputationGrain * 100));
driver->fEngineControl->fComputation = driver->fEngineControl->fPeriod * driver->fComputationGrain;
}
// Setup threadded based log function
set_threaded_log_function();
......@@ -441,7 +446,7 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe
}
JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
: JackAudioDriver(name, alias, engine, table), fJackInputData(NULL), fDriverOutputData(NULL), fState(false), fIOUsage(1.f)
: JackAudioDriver(name, alias, engine, table), fJackInputData(NULL), fDriverOutputData(NULL), fState(false), fIOUsage(1.f),fComputationGrain(-1.f)
{}
JackCoreAudioDriver::~JackCoreAudioDriver()
......@@ -1103,7 +1108,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
const char* playback_driver_uid,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency,
int async_output_latency)
int async_output_latency,
int computation_grain)
{
int in_nChannels = 0;
int out_nChannels = 0;
......@@ -1120,7 +1126,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
strcpy(fPlaybackUID, playback_driver_uid);
fCaptureLatency = capture_latency;
fPlaybackLatency = playback_latency;
fIOUsage = float(async_output_latency)/ 100.f;
fIOUsage = float(async_output_latency) / 100.f;
fComputationGrain = float(computation_grain) / 100.f;
if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name) < 0)
return -1;
......@@ -1259,12 +1266,13 @@ int JackCoreAudioDriver::Attach()
// Monitor ports
if (fWithMonitorPorts) {
jack_log("Create monitor port ");
snprintf(name, sizeof(name) - 1, "%s:%s:monitor_%u", fAliasName, fPlaybackDriverName, i + 1);
snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1);
if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) {
jack_error("Cannot register monitor port for %s", name);
return -1;
} else {
port = fGraphManager->GetPort(port_index);
port->SetAlias(alias);
port->SetLatency(fEngineControl->fBufferSize);
fMonitorPortList[i] = port_index;
}
......@@ -1364,7 +1372,7 @@ extern "C"
strcpy(desc->name, "coreaudio"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
strcpy(desc->desc, "Apple CoreAudio API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
desc->nparams = 14;
desc->nparams = 15;
desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
i = 0;
......@@ -1478,6 +1486,14 @@ extern "C"
desc->params[i].value.i = 100;
strcpy(desc->params[i].short_desc, "Extra output latency in aynchronous mode (percent)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "grain");
desc->params[i].character = 'G';
desc->params[i].type = JackDriverParamUInt;
desc->params[i].value.i = 100;
strcpy(desc->params[i].short_desc, "Computation grain in RT thread (percent)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
return desc;
}
......@@ -1498,6 +1514,7 @@ extern "C"
jack_nframes_t systemic_input_latency = 0;
jack_nframes_t systemic_output_latency = 0;
int async_output_latency = 100;
int computation_grain = -1;
for (node = params; node; node = jack_slist_next(node)) {
param = (const jack_driver_param_t *) node->data;
......@@ -1567,6 +1584,10 @@ extern "C"
case 'L':
async_output_latency = param->value.ui;
break;
case 'G':
computation_grain = param->value.ui;
break;
}
}
......@@ -1578,7 +1599,7 @@ extern "C"
Jack::JackCoreAudioDriver* driver = new Jack::JackCoreAudioDriver("system", "coreaudio", engine, table);
if (driver->Open(frames_per_interrupt, srate, capture, playback, chan_in, chan_out, monitor, capture_driver_uid,
playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency) == 0) {
playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain) == 0) {
return driver;
} else {
delete driver;
......
......@@ -72,6 +72,7 @@ class JackCoreAudioDriver : public JackAudioDriver
bool fMonitor;
float fIOUsage;
float fComputationGrain;
/*
#ifdef MAC_OS_X_VERSION_10_5
......@@ -164,7 +165,8 @@ class JackCoreAudioDriver : public JackAudioDriver
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency,
int async_output_latency);
int async_output_latency,
int computation_grain);
int Close();
int Attach();
......
......@@ -68,51 +68,51 @@ int gCycleWriteCount = 0;
inline int int2pow2(int x) { int r = 0; while ((1 << r) < x) r++; return r; }
static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int chcount, int bits)
static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int byte_skip, int bits)
{
switch (bits) {
case 16: {
signed short *s16src = (signed short*)src;
s16src += channel;
sample_move_dS_s16(dst, (char*)s16src, nframes, chcount<<1);
sample_move_dS_s16(dst, (char*)s16src, nframes, byte_skip);
break;
}
case 24: {
signed short *s32src = (signed short*)src;
signed int *s32src = (signed int*)src;
s32src += channel;
sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2);
sample_move_dS_s24(dst, (char*)s32src, nframes, byte_skip);
break;
}
case 32: {
signed short *s32src = (signed short*)src;
signed int *s32src = (signed int*)src;
s32src += channel;
sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2);
sample_move_dS_s32u24(dst, (char*)s32src, nframes, byte_skip);
break;
}
}
}
static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int chcount, int bits)
static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int byte_skip, int bits)
{
switch (bits) {
case 16: {
signed short *s16dst = (signed short*)dst;
s16dst += channel;
sample_move_d16_sS((char*)s16dst, src, nframes, chcount<<1, NULL); // No dithering for now...
sample_move_d16_sS((char*)s16dst, src, nframes, byte_skip, NULL); // No dithering for now...
break;
}
case 24: {
signed int *s32dst = (signed int*)dst;
s32dst += channel;
sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now...
sample_move_d24_sS((char*)s32dst, src, nframes, byte_skip, NULL);
break;
}
case 32: {
signed int *s32dst = (signed int*)dst;
s32dst += channel;
sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL);
sample_move_d32u24_sS((char*)s32dst, src, nframes, byte_skip, NULL);
break;
}
}
......@@ -124,16 +124,16 @@ void JackBoomerDriver::SetSampleFormat()
case 24: /* native-endian LSB aligned 24-bits in 32-bits integer */
fSampleFormat = AFMT_S24_NE;
fSampleSize = sizeof(int);
fSampleSize = 4;
break;
case 32: /* native-endian 32-bit integer */
fSampleFormat = AFMT_S32_NE;
fSampleSize = sizeof(int);
fSampleSize = 4;
break;
case 16: /* native-endian 16-bit integer */
default:
fSampleFormat = AFMT_S16_NE;
fSampleSize = sizeof(short);
fSampleSize = 2;
break;
}
}
......@@ -171,6 +171,7 @@ void JackBoomerDriver::DisplayDeviceInfo()
} else {
jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d",
info.fragments, info.fragstotal, info.fragsize, info.bytes);
fFragmentSize = info.fragsize;
}
if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) {
......@@ -233,7 +234,8 @@ void JackBoomerDriver::DisplayDeviceInfo()
JackBoomerDriver::JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
: JackAudioDriver(name, alias, engine, table),
fInFD(-1), fOutFD(-1), fBits(0),
fSampleFormat(0), fNperiods(0), fRWMode(0), fExcl(false), fIgnoreHW(true),
fSampleFormat(0), fNperiods(0), fSampleSize(0), fFragmentSize(0),
fRWMode(0), fExcl(false), fSyncIO(false),
fInputBufferSize(0), fOutputBufferSize(0),
fInputBuffer(NULL), fOutputBuffer(NULL),
fInputThread(&fInputHandler), fOutputThread(&fOutputHandler),
......@@ -401,15 +403,8 @@ int JackBoomerDriver::Open(jack_nframes_t nframes,
const char* playback_driver_uid,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency,
int bits,
bool ignorehwbuf)
int bits, bool syncio)
{
if (playing && !capturing) {
jack_error("Playback only mode is not yet supported, use duplex instead");
return -1;
}
// Generic JackAudioDriver Open
if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor,
capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) {
......@@ -424,10 +419,10 @@ int JackBoomerDriver::Open(jack_nframes_t nframes,
fRWMode |= ((capturing) ? kRead : 0);
fRWMode |= ((playing) ? kWrite : 0);
fBits = bits;
fIgnoreHW = ignorehwbuf;
fNperiods = user_nperiods;
fExcl = excl;
fNperiods = (user_nperiods == 0) ? 1 : user_nperiods ;
fSyncIO = syncio;
#ifdef JACK_MONITOR
// Force memory page in
memset(&gCycleTable, 0, sizeof(gCycleTable));
......@@ -514,12 +509,12 @@ int JackBoomerDriver::OpenAux()
void JackBoomerDriver::CloseAux()
{
if (fRWMode & kRead && fInFD > 0) {
if (fRWMode & kRead && fInFD >= 0) {
close(fInFD);
fInFD = -1;
}
if (fRWMode & kWrite && fOutFD > 0) {
if (fRWMode & kWrite && fOutFD >= 0) {
close(fOutFD);
fOutFD = -1;
}
......@@ -538,8 +533,61 @@ int JackBoomerDriver::Start()
jack_log("JackBoomerDriver::Start");
JackAudioDriver::Start();
// Input/output synchronisation
if (fInFD >= 0 && fOutFD >= 0 && fSyncIO) {
jack_log("JackBoomerDriver::Start sync input/output");
// Create and fill synch group
int id;
oss_syncgroup group;
group.id = 0;
group.mode = PCM_ENABLE_INPUT;
if (ioctl(fInFD, SNDCTL_DSP_SYNCGROUP, &group) == -1)
jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno);
group.mode = PCM_ENABLE_OUTPUT;
if (ioctl(fOutFD, SNDCTL_DSP_SYNCGROUP, &group) == -1)
jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno);
// Prefill output buffer : 2 fragments of silence as described in http://manuals.opensound.com/developer/synctest.c.html#LOC6
char* silence_buf = (char*)malloc(fFragmentSize);
memset(silence_buf, 0, fFragmentSize);
jack_log ("JackBoomerDriver::Start prefill size = %d", fFragmentSize);
for (int i = 0; i < 2; i++) {
ssize_t count = ::write(fOutFD, silence_buf, fFragmentSize);
if (count < (int)fFragmentSize) {
jack_error("JackBoomerDriver::Start error bytes written = %ld", count);
}
}
free(silence_buf);
// Start input/output in sync
id = group.id;
if (ioctl(fInFD, SNDCTL_DSP_SYNCSTART, &id) == -1)
jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCSTART : %s@%i, errno = %d", __FILE__, __LINE__, errno);
} else if (fOutFD >= 0) {
// Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html
memset(fOutputBuffer, 0, fOutputBufferSize);
// Prefill ouput buffer
for (int i = 0; i < fNperiods; i++) {
ssize_t count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize);
if (count < (int)fOutputBufferSize) {
jack_error("JackBoomerDriver::Start error bytes written = %ld", count);
}
}
}
// Start input thread only when needed
if (fInFD > 0) {
if (fInFD >= 0) {
if (fInputThread.StartSync() < 0) {
jack_error("Cannot start input thread");
return -1;
......@@ -547,7 +595,7 @@ int JackBoomerDriver::Start()
}
// Start output thread only when needed
if (fOutFD > 0) {
if (fOutFD >= 0) {
if (fOutputThread.StartSync() < 0) {
jack_error("Cannot start output thread");
return -1;
......@@ -560,38 +608,18 @@ int JackBoomerDriver::Start()
int JackBoomerDriver::Stop()
{
// Stop input thread only when needed
if (fInFD > 0) {
if (fInFD >= 0) {
fInputThread.Kill();
}
// Stop output thread only when needed
if (fOutFD > 0) {
if (fOutFD >= 0) {
fOutputThread.Kill();
}
return 0;
}
int JackBoomerDriver::Read()
{
/*
// Keep begin cycle time
JackDriver::CycleTakeBeginTime();
*/
return 0;
}
int JackBoomerDriver::Write()
{
/*
// Keep begin cycle time
JackDriver::CycleTakeEndTime();
*/
return 0;
}
bool JackBoomerDriver::JackBoomerDriverInput::Init()
{
if (fDriver->IsRealTime()) {
......@@ -602,18 +630,13 @@ bool JackBoomerDriver::JackBoomerDriverInput::Init()
set_threaded_log_function();
}
}
return true;
}
bool JackBoomerDriver::JackBoomerDriverInput::Execute()
{
if (fDriver->fInFD < 0) {
// Keep begin cycle time
fDriver->CycleTakeBeginTime();
return true;
}
#ifdef JACK_MONITOR
gCycleTable.fTable[gCycleReadCount].fBeforeRead = GetMicroSeconds();
#endif
......@@ -651,7 +674,12 @@ bool JackBoomerDriver::JackBoomerDriverInput::Execute()
fDriver->CycleTakeBeginTime();
for (int i = 0; i < fDriver->fCaptureChannels; i++) {
if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fCapturePortList[i]) > 0) {
CopyAndConvertIn(fDriver->GetInputBuffer(i), fDriver->fInputBuffer, fDriver->fEngineControl->fBufferSize, i, fDriver->fCaptureChannels, fDriver->fBits);
CopyAndConvertIn(fDriver->GetInputBuffer(i),
fDriver->fInputBuffer,
fDriver->fEngineControl->fBufferSize,
i,