Browse Source

rebase from trunk 3353:3367

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3368 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.8
sletz 16 years ago
parent
commit
6926652401
19 changed files with 388 additions and 454 deletions
  1. +12
    -1
      ChangeLog
  2. +30
    -77
      common/JackAudioAdapter.cpp
  3. +0
    -6
      common/JackAudioAdapter.h
  4. +156
    -17
      common/JackAudioAdapterInterface.cpp
  5. +23
    -27
      common/JackAudioAdapterInterface.h
  6. +2
    -2
      common/JackLibSampleRateResampler.cpp
  7. +2
    -2
      common/JackLibSampleRateResampler.h
  8. +32
    -150
      common/JackNetAPI.cpp
  9. +1
    -1
      common/JackNetAdapter.cpp
  10. +9
    -1
      common/JackResampler.cpp
  11. +3
    -1
      common/JackResampler.h
  12. +6
    -19
      common/jack/net.h
  13. +8
    -2
      common/wscript
  14. +19
    -38
      linux/alsa/JackAlsaAdapter.cpp
  15. +20
    -9
      linux/alsa/JackAlsaAdapter.h
  16. +23
    -27
      macosx/coreaudio/JackCoreAudioAdapter.cpp
  17. +19
    -30
      solaris/oss/JackOSSAdapter.cpp
  18. +1
    -1
      solaris/oss/JackOSSAdapter.h
  19. +22
    -43
      windows/portaudio/JackPortAudioAdapter.cpp

+ 12
- 1
ChangeLog View File

@@ -22,11 +22,22 @@ Michael Voigt
--------------------------- ---------------------------
Jackdmp changes log Jackdmp changes log
--------------------------- ---------------------------

2009-02-27 Stephane Letz <letz@grame.fr>
* Improve generated gnuplot files for adapting code.

2009-02-25 Stephane Letz <letz@grame.fr>
* Major cleanup in adapter code.
2009-02-25 Stephane Letz <letz@grame.fr> 2009-02-25 Stephane Letz <letz@grame.fr>
* Fix JackNetDriver::Close method. * Fix JackNetDriver::Close method.
* For audio device reservation, add card_to_num function. * For audio device reservation, add card_to_num function.
* Fix buffer size and sample rate handling in JackAlsaAdapter.
* Add control for adapter ringbuffer size.
* Fix JackAlsaAdapter.h for 64 bits compilation.
2009-02-24 Stephane Letz <letz@grame.fr> 2009-02-24 Stephane Letz <letz@grame.fr>
@@ -37,7 +48,7 @@ Michael Voigt
* Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h. * Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h.
* Move generic code and data in JackNetInterface and JackNetMasterInterface classes. * Move generic code and data in JackNetInterface and JackNetMasterInterface classes.
* First version of D-Bus based audio device rerservation.
* First version of D-Bus based audio device reservation.
2009-02-20 Stephane Letz <letz@grame.fr> 2009-02-20 Stephane Letz <letz@grame.fr>


+ 30
- 77
common/JackAudioAdapter.cpp View File

@@ -18,7 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */


#include "JackAudioAdapter.h" #include "JackAudioAdapter.h"
#include "JackLibSampleRateResampler.h"
#include "JackError.h" #include "JackError.h"
#include "JackCompilerDeps.h" #include "JackCompilerDeps.h"
#include "JackTools.h" #include "JackTools.h"
@@ -34,40 +33,22 @@ namespace Jack
{ {


//static methods *********************************************************** //static methods ***********************************************************
int JackAudioAdapter::Process ( jack_nframes_t frames, void* arg )
int JackAudioAdapter::Process (jack_nframes_t frames, void* arg)
{ {
JackAudioAdapter* adapter = static_cast<JackAudioAdapter*> ( arg );
float* buffer;
bool failure = false;
int i;

if ( !adapter->fAudioAdapter->IsRunning() )
JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg);
if (!adapter->fAudioAdapter->IsRunning())
return 0; return 0;

// DLL
adapter->fAudioAdapter->SetCallbackTime (GetMicroSeconds());

// Push/pull from ringbuffer
for ( i = 0; i < adapter->fCaptureChannels; i++ )
{
buffer = static_cast<float*> ( jack_port_get_buffer ( adapter->fCapturePortList[i], frames ) );
if ( adapter->fCaptureRingBuffer[i]->Read ( buffer, frames ) < frames )
failure = true;
float* inputBuffer[adapter->fAudioAdapter->GetInputs()];
float* outputBuffer[adapter->fAudioAdapter->GetOutputs()];
for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) {
inputBuffer[i] = (float*)jack_port_get_buffer(adapter->fCapturePortList[i], frames);
} }

for ( i = 0; i < adapter->fPlaybackChannels; i++ )
{
buffer = static_cast<float*> ( jack_port_get_buffer ( adapter->fPlaybackPortList[i], frames ) );
if ( adapter->fPlaybackRingBuffer[i]->Write ( buffer, frames ) < frames )
failure = true;
}

// Reset all ringbuffers in case of failure
if ( failure )
{
jack_error ( "JackCallbackAudioAdapter::Process ringbuffer failure... reset" );
adapter->Reset();
for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) {
outputBuffer[i] = (float*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames);
} }
adapter->fAudioAdapter->PullAndPush(inputBuffer, outputBuffer, frames);
return 0; return 0;
} }


@@ -91,24 +72,15 @@ namespace Jack
JackAudioAdapter::~JackAudioAdapter() JackAudioAdapter::~JackAudioAdapter()
{ {
// When called, Close has already been used for the client, thus ports are already unregistered. // When called, Close has already been used for the client, thus ports are already unregistered.
int i;
for ( i = 0; i < fCaptureChannels; i++ )
delete ( fCaptureRingBuffer[i] );
for ( i = 0; i < fPlaybackChannels; i++ )
delete ( fPlaybackRingBuffer[i] );

delete[] fCaptureRingBuffer;
delete[] fPlaybackRingBuffer;
delete fAudioAdapter; delete fAudioAdapter;
} }


void JackAudioAdapter::FreePorts() void JackAudioAdapter::FreePorts()
{ {
int i;
for ( i = 0; i < fCaptureChannels; i++ )
for (int i = 0; i < fAudioAdapter->GetInputs(); i++ )
if ( fCapturePortList[i] ) if ( fCapturePortList[i] )
jack_port_unregister ( fJackClient, fCapturePortList[i] ); jack_port_unregister ( fJackClient, fCapturePortList[i] );
for ( i = 0; i < fCaptureChannels; i++ )
for (int i = 0; i < fAudioAdapter->GetOutputs(); i++ )
if ( fPlaybackPortList[i] ) if ( fPlaybackPortList[i] )
jack_port_unregister ( fJackClient, fPlaybackPortList[i] ); jack_port_unregister ( fJackClient, fPlaybackPortList[i] );


@@ -118,52 +90,30 @@ namespace Jack


void JackAudioAdapter::Reset() void JackAudioAdapter::Reset()
{ {
int i;
for ( i = 0; i < fCaptureChannels; i++ )
fCaptureRingBuffer[i]->Reset();
for ( i = 0; i < fPlaybackChannels; i++ )
fPlaybackRingBuffer[i]->Reset();
fAudioAdapter->Reset(); fAudioAdapter->Reset();
} }


int JackAudioAdapter::Open() int JackAudioAdapter::Open()
{ {
int i;
char name[32]; char name[32];

fCaptureChannels = fAudioAdapter->GetInputs();
fPlaybackChannels = fAudioAdapter->GetOutputs();

jack_log ( "JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fCaptureChannels, fPlaybackChannels );

//ringbuffers
fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
for ( i = 0; i < fCaptureChannels; i++ )
fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality());
for ( i = 0; i < fPlaybackChannels; i++ )
fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality());
fAudioAdapter->SetRingBuffers ( fCaptureRingBuffer, fPlaybackRingBuffer );
if (fCaptureChannels > 0)
jack_log ( "ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace() );
if (fPlaybackChannels > 0)
jack_log ( "WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace() );

jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs());
fAudioAdapter->Create();
//jack ports //jack ports
fCapturePortList = new jack_port_t* [fCaptureChannels];
fPlaybackPortList = new jack_port_t* [fPlaybackChannels];
fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()];
fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()];


for ( i = 0; i < fCaptureChannels; i++ )
for (int i = 0; i < fAudioAdapter->GetInputs(); i++)
{ {
sprintf ( name, "capture_%d", i+1 );
if ( ( fCapturePortList[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ) ) == NULL )
sprintf(name, "capture_%d", i + 1);
if ((fCapturePortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL)
goto fail; goto fail;
} }


for ( i = 0; i < fPlaybackChannels; i++ )
for (int i = 0; i < fAudioAdapter->GetOutputs(); i++)
{ {
sprintf ( name, "playback_%d", i+1 );
if ( ( fPlaybackPortList[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ) ) == NULL )
sprintf(name, "playback_%d", i + 1);
if ((fPlaybackPortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 )) == NULL)
goto fail; goto fail;
} }


@@ -177,17 +127,20 @@ namespace Jack
if ( jack_activate ( fJackClient ) < 0 ) if ( jack_activate ( fJackClient ) < 0 )
goto fail; goto fail;


//ringbuffers and jack clients are ok, we can now open the adapter driver interface
// Ring buffer are now allocated..
return fAudioAdapter->Open(); return fAudioAdapter->Open();


fail: fail:
FreePorts(); FreePorts();
fAudioAdapter->Destroy();
return -1; return -1;
} }


int JackAudioAdapter::Close() int JackAudioAdapter::Close()
{ {
return fAudioAdapter->Close();
fAudioAdapter->Close();
fAudioAdapter->Destroy();
return 0;
} }


} //namespace } //namespace

+ 0
- 6
common/JackAudioAdapter.h View File

@@ -37,12 +37,6 @@ namespace Jack
static int BufferSize ( jack_nframes_t buffer_size, void *arg ); static int BufferSize ( jack_nframes_t buffer_size, void *arg );
static int SampleRate ( jack_nframes_t sample_rate, void *arg ); static int SampleRate ( jack_nframes_t sample_rate, void *arg );


int fCaptureChannels;
int fPlaybackChannels;

JackResampler** fCaptureRingBuffer;
JackResampler** fPlaybackRingBuffer;

jack_port_t** fCapturePortList; jack_port_t** fCapturePortList;
jack_port_t** fPlaybackPortList; jack_port_t** fPlaybackPortList;




+ 156
- 17
common/JackAudioAdapterInterface.cpp View File

@@ -18,6 +18,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */


#include "JackAudioAdapter.h" #include "JackAudioAdapter.h"
#include <TargetConditionals.h>
#ifndef TARGET_OS_IPHONE
#include "JackLibSampleRateResampler.h"
#endif
#include "JackTime.h" #include "JackTime.h"
#include <stdio.h> #include <stdio.h>


@@ -37,7 +41,7 @@ namespace Jack
fTable[pos].pos2 = pos2; fTable[pos].pos2 = pos2;
} }


void MeasureTable::Save()
void MeasureTable::Save(unsigned int fHostBufferSize, unsigned int fHostSampleRate, unsigned int fAdaptedSampleRate, unsigned int fAdaptedBufferSize)
{ {
char buffer[1024]; char buffer[1024];
FILE* file = fopen("JackAudioAdapter.log", "w"); FILE* file = fopen("JackAudioAdapter.log", "w");
@@ -54,6 +58,22 @@ namespace Jack


// Adapter timing 1 // Adapter timing 1
file = fopen("AdapterTiming1.plot", "w"); file = fopen("AdapterTiming1.plot", "w");
fprintf(file, "set multiplot\n");
fprintf(file, "set grid\n");
fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"frames\"\n");
fprintf(file, "plot ");
sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,");
fprintf(file, buffer);
sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines");
fprintf(file, buffer);
fprintf(file, "\n unset multiplot\n");
fprintf(file, "set output 'AdapterTiming1.pdf\n");
fprintf(file, "set terminal pdf\n");
fprintf(file, "set multiplot\n"); fprintf(file, "set multiplot\n");
fprintf(file, "set grid\n"); fprintf(file, "set grid\n");
fprintf(file, "set title \"Audio adapter timing\"\n"); fprintf(file, "set title \"Audio adapter timing\"\n");
@@ -64,10 +84,27 @@ namespace Jack
fprintf(file, buffer); fprintf(file, buffer);
sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines"); sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines");
fprintf(file, buffer); fprintf(file, buffer);
fclose(file); fclose(file);


// Adapter timing 2 // Adapter timing 2
file = fopen("AdapterTiming2.plot", "w"); file = fopen("AdapterTiming2.plot", "w");
fprintf(file, "set multiplot\n");
fprintf(file, "set grid\n");
fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"resampling ratio\"\n");
fprintf(file, "plot ");
sprintf(buffer, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,");
fprintf(file, buffer);
sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines");
fprintf(file, buffer);
fprintf(file, "\n unset multiplot\n");
fprintf(file, "set output 'AdapterTiming2.pdf\n");
fprintf(file, "set terminal pdf\n");
fprintf(file, "set multiplot\n"); fprintf(file, "set multiplot\n");
fprintf(file, "set grid\n"); fprintf(file, "set grid\n");
fprintf(file, "set title \"Audio adapter timing\"\n"); fprintf(file, "set title \"Audio adapter timing\"\n");
@@ -78,10 +115,27 @@ namespace Jack
fprintf(file, buffer); fprintf(file, buffer);
sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines"); sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines");
fprintf(file, buffer); fprintf(file, buffer);
fclose(file); fclose(file);


// Adapter timing 3 // Adapter timing 3
file = fopen("AdapterTiming3.plot", "w"); file = fopen("AdapterTiming3.plot", "w");
fprintf(file, "set multiplot\n");
fprintf(file, "set grid\n");
fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n"
,float(fHostSampleRate)/1000.f, fHostBufferSize, float(fAdaptedSampleRate)/1000.f, fAdaptedBufferSize);
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"frames\"\n");
fprintf(file, "plot ");
sprintf(buffer, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,");
fprintf(file, buffer);
sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines");
fprintf(file, buffer);
fprintf(file, "\n unset multiplot\n");
fprintf(file, "set output 'AdapterTiming3.pdf\n");
fprintf(file, "set terminal pdf\n");
fprintf(file, "set multiplot\n"); fprintf(file, "set multiplot\n");
fprintf(file, "set grid\n"); fprintf(file, "set grid\n");
fprintf(file, "set title \"Audio adapter timing\"\n"); fprintf(file, "set title \"Audio adapter timing\"\n");
@@ -92,35 +146,32 @@ namespace Jack
fprintf(file, buffer); fprintf(file, buffer);
sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines"); sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines");
fprintf(file, buffer); fprintf(file, buffer);
fclose(file); fclose(file);
} }


#endif #endif
void JackAudioAdapterInterface::ResetRingBuffers() void JackAudioAdapterInterface::ResetRingBuffers()
{ {
int i;
for (i = 0; i < fCaptureChannels; i++)
for (int i = 0; i < fCaptureChannels; i++)
fCaptureRingBuffer[i]->Reset(); fCaptureRingBuffer[i]->Reset();
for (i = 0; i < fPlaybackChannels; i++)
for (int i = 0; i < fPlaybackChannels; i++)
fPlaybackRingBuffer[i]->Reset(); fPlaybackRingBuffer[i]->Reset();
} }


void JackAudioAdapterInterface::ResampleFactor ( jack_nframes_t& frame1, jack_nframes_t& frame2 )
void JackAudioAdapterInterface::ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 )
{ {
jack_time_t time = GetMicroSeconds(); jack_time_t time = GetMicroSeconds();


if ( !fRunning )
{
if (!fRunning) {
// Init DLL // Init DLL
fRunning = true; fRunning = true;
fHostDLL.Init ( time );
fAdaptedDLL.Init ( time );
fHostDLL.Init(time);
fAdaptedDLL.Init(time);
frame1 = 1; frame1 = 1;
frame2 = 1; frame2 = 1;
}
else
{
} else {
// DLL // DLL
fAdaptedDLL.IncFrame(time); fAdaptedDLL.IncFrame(time);
jack_nframes_t time1 = fHostDLL.Time2Frames(time); jack_nframes_t time1 = fHostDLL.Time2Frames(time);
@@ -131,15 +182,103 @@ namespace Jack
long(time1), long(time2), double(time1) / double(time2), double(time2) / double(time1)); long(time1), long(time2), double(time1) / double(time2), double(time2) / double(time1));
} }
} }
void JackAudioAdapterInterface::Reset()
{
ResetRingBuffers();
fRunning = false;
}
#ifdef TARGET_OS_IPHONE
void JackAudioAdapterInterface::Create()
{}
#else
void JackAudioAdapterInterface::Create()
{
//ringbuffers
fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
for (int i = 0; i < fCaptureChannels; i++ )
fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize);
for (int i = 0; i < fPlaybackChannels; i++ )
fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize);

if (fCaptureChannels > 0)
jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
if (fPlaybackChannels > 0)
jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
}
#endif
void JackAudioAdapterInterface::Destroy()
{
for (int i = 0; i < fCaptureChannels; i++ )
delete ( fCaptureRingBuffer[i] );
for (int i = 0; i < fPlaybackChannels; i++ )
delete ( fPlaybackRingBuffer[i] );


int JackAudioAdapterInterface::Open()
delete[] fCaptureRingBuffer;
delete[] fPlaybackRingBuffer;
}
int JackAudioAdapterInterface::PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames)
{ {
return 0;
bool failure = false;
jack_time_t time1, time2;
ResampleFactor(time1, time2);

// Push/pull from ringbuffer
for (int i = 0; i < fCaptureChannels; i++) {
fCaptureRingBuffer[i]->SetRatio(time1, time2);
if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames)
failure = true;
}

for (int i = 0; i < fPlaybackChannels; i++) {
fPlaybackRingBuffer[i]->SetRatio(time2, time1);
if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames)
failure = true;
}

#ifdef JACK_MONITOR
fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1),
fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace());
#endif

// Reset all ringbuffers in case of failure
if (failure) {
jack_error("JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset");
ResetRingBuffers();
return -1;
} else {
return 0;
}
} }


int JackAudioAdapterInterface::Close()
int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames)
{ {
return 0;
bool failure = false;
fHostDLL.IncFrame(GetMicroSeconds());

// Push/pull from ringbuffer
for (int i = 0; i < fCaptureChannels; i++) {
if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames)
failure = true;
}

for (int i = 0; i < fPlaybackChannels; i++) {
if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames)
failure = true;
}

// Reset all ringbuffers in case of failure
if (failure) {
jack_error("JackCallbackAudioAdapter::PullAndPush ringbuffer failure... reset");
Reset();
return -1;
} else {
return 0;
}
} }


} // namespace } // namespace

+ 23
- 27
common/JackAudioAdapterInterface.h View File

@@ -51,8 +51,8 @@ namespace Jack
MeasureTable() :fCount ( 0 ) MeasureTable() :fCount ( 0 )
{} {}


void Write ( int time1, int time2, float r1, float r2, int pos1, int pos2 );
void Save();
void Write(int time1, int time2, float r1, float r2, int pos1, int pos2);
void Save(unsigned int fHostBufferSize, unsigned int fHostSampleRate, unsigned int fAdaptedSampleRate, unsigned int fAdaptedBufferSize);


}; };


@@ -90,9 +90,13 @@ namespace Jack
JackResampler** fPlaybackRingBuffer; JackResampler** fPlaybackRingBuffer;
unsigned int fQuality; unsigned int fQuality;

unsigned int fRingbufferSize;
bool fRunning; bool fRunning;

void ResetRingBuffers();
void ResampleFactor ( jack_time_t& frame1, jack_time_t& frame2 );
public: public:


JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, JackAudioAdapterInterface ( jack_nframes_t host_buffer_size,
@@ -106,6 +110,7 @@ namespace Jack
fHostDLL ( host_buffer_size, host_sample_rate ), fHostDLL ( host_buffer_size, host_sample_rate ),
fAdaptedDLL ( host_buffer_size, host_sample_rate ), fAdaptedDLL ( host_buffer_size, host_sample_rate ),
fQuality(0), fQuality(0),
fRingbufferSize(DEFAULT_RB_SIZE),
fRunning ( false ) fRunning ( false )
{} {}
JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, JackAudioAdapterInterface ( jack_nframes_t host_buffer_size,
@@ -121,38 +126,33 @@ namespace Jack
fHostDLL ( host_buffer_size, host_sample_rate ), fHostDLL ( host_buffer_size, host_sample_rate ),
fAdaptedDLL ( adapted_buffer_size, adapted_sample_rate ), fAdaptedDLL ( adapted_buffer_size, adapted_sample_rate ),
fQuality(0), fQuality(0),
fRingbufferSize(DEFAULT_RB_SIZE),
fRunning ( false ) fRunning ( false )
{} {}


virtual ~JackAudioAdapterInterface() virtual ~JackAudioAdapterInterface()
{} {}


void SetRingBuffers ( JackResampler** input, JackResampler** output )
{
fCaptureRingBuffer = input;
fPlaybackRingBuffer = output;
}

bool IsRunning() bool IsRunning()
{ {
return fRunning; return fRunning;
} }


virtual void Reset()
virtual void Reset();
virtual void Create();
virtual void Destroy();
virtual int Open()
{ {
fRunning = false;
return 0;
} }

void ResetRingBuffers();
unsigned int GetQuality()
virtual int Close()
{ {
return fQuality;
return 0;
} }


virtual int Open();
virtual int Close();

virtual int SetHostBufferSize ( jack_nframes_t buffer_size ) virtual int SetHostBufferSize ( jack_nframes_t buffer_size )
{ {
fHostBufferSize = buffer_size; fHostBufferSize = buffer_size;
@@ -194,14 +194,7 @@ namespace Jack
SetAdaptedSampleRate ( sample_rate ); SetAdaptedSampleRate ( sample_rate );
return 0; return 0;
} }

virtual void SetCallbackTime ( jack_time_t callback_usec )
{
fHostDLL.IncFrame ( callback_usec );
}

void ResampleFactor ( jack_nframes_t& frame1, jack_nframes_t& frame2 );

void SetInputs ( int inputs ) void SetInputs ( int inputs )
{ {
jack_log ( "JackAudioAdapterInterface::SetInputs %d", inputs ); jack_log ( "JackAudioAdapterInterface::SetInputs %d", inputs );
@@ -225,6 +218,9 @@ namespace Jack
jack_log ( "JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels ); jack_log ( "JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels );
return fPlaybackChannels; return fPlaybackChannels;
} }
int PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames);
int PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames);


}; };




+ 2
- 2
common/JackLibSampleRateResampler.cpp View File

@@ -31,8 +31,8 @@ JackLibSampleRateResampler::JackLibSampleRateResampler()
jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error));
} }


JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality)
:JackResampler(),fRatio(1)
JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size)
:JackResampler(ringbuffer_size),fRatio(1)
{ {
switch (quality) { switch (quality) {
case 0: case 0:


+ 2
- 2
common/JackLibSampleRateResampler.h View File

@@ -46,7 +46,7 @@ class JackLibSampleRateResampler : public JackResampler
public: public:
JackLibSampleRateResampler(); JackLibSampleRateResampler();
JackLibSampleRateResampler(unsigned int quality);
JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size);
virtual ~JackLibSampleRateResampler(); virtual ~JackLibSampleRateResampler();
unsigned int ReadResample(float* buffer, unsigned int frames); unsigned int ReadResample(float* buffer, unsigned int frames);
@@ -55,7 +55,7 @@ class JackLibSampleRateResampler : public JackResampler
void SetRatio(unsigned int num, unsigned int denom) void SetRatio(unsigned int num, unsigned int denom)
{ {
JackResampler::SetRatio(num, denom); JackResampler::SetRatio(num, denom);
fRatio = Range(0.25f, 4.0f, (double(num) / double(denom)));
fRatio = Range(0.25, 4.0, (double(num) / double(denom)));
} }
void Reset(); void Reset();


+ 32
- 150
common/JackNetAPI.cpp View File

@@ -106,18 +106,16 @@ extern "C"
typedef struct _jack_adapter jack_adapter_t; typedef struct _jack_adapter jack_adapter_t;
SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size,
SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
jack_nframes_t host_buffer_size,
jack_nframes_t host_sample_rate, jack_nframes_t host_sample_rate,
jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_buffer_size,
jack_nframes_t adapted_sample_rate); jack_nframes_t adapted_sample_rate);
SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter); SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter);


SERVER_EXPORT int jack_adapter_push_input(jack_adapter_t* adapter, int channels, float** buffers);
SERVER_EXPORT int jack_adapter_pull_input(jack_adapter_t* adapter, int channels, float** buffers);
SERVER_EXPORT int jack_adapter_push_output(jack_adapter_t* adapter, int channels, float** buffers);
SERVER_EXPORT int jack_adapter_pull_output(jack_adapter_t* adapter, int channels, float** buffers);
SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);
SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@@ -734,144 +732,39 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
struct JackNetAdapter : public JackAudioAdapterInterface { struct JackNetAdapter : public JackAudioAdapterInterface {




JackNetAdapter(jack_nframes_t host_buffer_size,
JackNetAdapter(int input, int output,
jack_nframes_t host_buffer_size,
jack_nframes_t host_sample_rate, jack_nframes_t host_sample_rate,
jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_buffer_size,
jack_nframes_t adapted_sample_rate) jack_nframes_t adapted_sample_rate)
:JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate) :JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate)
{ {
fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
/*
for (i = 0; i < fCaptureChannels; i++)
fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality());
for (i = 0; i < fPlaybackChannels; i++)
fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fAudioAdapter->GetQuality());
*/
int i;
for (i = 0; i < fCaptureChannels; i++)
fCaptureRingBuffer[i] = new JackResampler();
for (i = 0; i < fPlaybackChannels; i++)
fPlaybackRingBuffer[i] = new JackResampler();
}

virtual ~JackNetAdapter()
{
int i;
for (i = 0; i < fCaptureChannels; i++)
delete (fCaptureRingBuffer[i]);
for (i = 0; i < fPlaybackChannels; i++)
delete(fPlaybackRingBuffer[i] );

delete[] fCaptureRingBuffer;
delete[] fPlaybackRingBuffer;
}
void Reset()
{
int i;
for (i = 0; i < fCaptureChannels; i++)
fCaptureRingBuffer[i]->Reset();
for (i = 0; i < fPlaybackChannels; i++)
fPlaybackRingBuffer[i]->Reset();
}
int PushInput(int audio_input, float** audio_input_buffer)
{
bool failure = false;
int port_index;
// Get the resample factor,
jack_nframes_t time1, time2;
ResampleFactor(time1, time2);

// Resample input data,
for (port_index = 0; port_index < audio_input; port_index++) {
fCaptureRingBuffer[port_index]->SetRatio(time1, time2);
if (fCaptureRingBuffer[port_index]->WriteResample(audio_input_buffer[port_index], fAdaptedBufferSize) < fAdaptedBufferSize)
failure = true;
}
if (failure) {
ResetRingBuffers();
return -1;
}
return 0;
fCaptureChannels = input;
fPlaybackChannels = output;
Create();
} }
int PullInput(int audio_input, float** audio_input_buffer)
void JackNetAdapter::Create()
{ {
bool failure = false;
int port_index;
// DLL
SetCallbackTime(GetMicroSeconds());

// Push/pull from ringbuffer
for (port_index = 0; port_index < audio_input; port_index++) {
if (fCaptureRingBuffer[port_index]->Read(audio_input_buffer[port_index], fHostBufferSize) < fHostBufferSize)
failure = true;
}
// Reset all ringbuffers in case of failure
if (failure) {
Reset();
return -1;
}
return 0;
}
int PushOutput(int audio_input, float** audio_input_buffer)
{
bool failure = false;
int port_index;
// DLL
SetCallbackTime(GetMicroSeconds());
//ringbuffers
fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
for (int i = 0; i < fCaptureChannels; i++ )
fCaptureRingBuffer[i] = new JackResampler(fRingbufferSize);
for (int i = 0; i < fPlaybackChannels; i++ )
fPlaybackRingBuffer[i] = new JackResampler(fRingbufferSize);


// Push/pull from ringbuffer
for (port_index = 0; port_index < audio_input; port_index++) {
if (fPlaybackRingBuffer[port_index]->Write(audio_input_buffer[port_index], fHostBufferSize) < fHostBufferSize)
failure = true;
}
// Reset all ringbuffers in case of failure
if (failure) {
Reset();
return -1;
}
return 0;
if (fCaptureChannels > 0)
jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
if (fPlaybackChannels > 0)
jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
} }


int PullOutput(int audio_output, float** audio_output_buffer)
virtual ~JackNetAdapter()
{ {
bool failure = false;
int port_index;

//get the resample factor,
jack_nframes_t time1, time2;
ResampleFactor(time1, time2);

//resample output data,
for (port_index = 0; port_index < fPlaybackChannels; port_index++) {
fPlaybackRingBuffer[port_index]->SetRatio(time2, time1);
if (fPlaybackRingBuffer[port_index]->ReadResample(audio_output_buffer[port_index], fAdaptedBufferSize) < fAdaptedBufferSize)
failure = true;
}
if (failure) {
ResetRingBuffers();
return -1;
}
return 0;
Destroy();
} }
}; };




@@ -968,12 +861,13 @@ SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output,


// Adapter API // Adapter API


SERVER_EXPORT jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size,
SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
jack_nframes_t host_buffer_size,
jack_nframes_t host_sample_rate, jack_nframes_t host_sample_rate,
jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_buffer_size,
jack_nframes_t adapted_sample_rate) jack_nframes_t adapted_sample_rate)
{ {
return (jack_adapter_t*)new JackNetAdapter(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
} }


SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter)
@@ -982,30 +876,18 @@ SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter)
return 0; return 0;
} }


SERVER_EXPORT int jack_adapter_push_input(jack_adapter_t * adapter, int channels, float** buffers)
SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames)
{ {
JackNetAdapter* slave = (JackNetAdapter*)adapter; JackNetAdapter* slave = (JackNetAdapter*)adapter;
return slave->PushInput(channels, buffers);
return slave->PushAndPull(input, output, frames);
} }


SERVER_EXPORT int jack_adapter_pull_input(jack_adapter_t * adapter, int channels, float** buffers)
SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames)
{ {
JackNetAdapter* slave = (JackNetAdapter*)adapter; JackNetAdapter* slave = (JackNetAdapter*)adapter;
return slave->PullInput(channels, buffers);
}
SERVER_EXPORT int jack_adapter_push_output(jack_adapter_t * adapter, int channels, float** buffers)
{
JackNetAdapter* slave = (JackNetAdapter*)adapter;
return slave->PushOutput(channels, buffers);
return slave->PullAndPush(input, output, frames);
} }


SERVER_EXPORT int jack_adapter_pull_output(jack_adapter_t * adapter, int channels, float** buffers)
{
JackNetAdapter* slave = (JackNetAdapter*)adapter;
return slave->PullOutput(channels, buffers);
}


// Empty code for now.. // Empty code for now..
//#ifdef TARGET_OS_IPHONE //#ifdef TARGET_OS_IPHONE


+ 1
- 1
common/JackNetAdapter.cpp View File

@@ -367,7 +367,7 @@ namespace Jack
return SOCKET_ERROR; return SOCKET_ERROR;


//get the resample factor, //get the resample factor,
jack_nframes_t time1, time2;
jack_time_t time1, time2;
ResampleFactor ( time1, time2 ); ResampleFactor ( time1, time2 );


//resample input data, //resample input data,


+ 9
- 1
common/JackResampler.cpp View File

@@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */


#include "JackResampler.h" #include "JackResampler.h"
#include <stdio.h>


namespace Jack namespace Jack
{ {
@@ -28,6 +29,12 @@ JackResampler::JackResampler():fNum(1),fDenom(1)
jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * DEFAULT_RB_SIZE) / 2); jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * DEFAULT_RB_SIZE) / 2);
} }


JackResampler::JackResampler(unsigned int ringbuffer_size):fNum(1),fDenom(1),fRingBufferSize(ringbuffer_size)
{
fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize);
jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2);
}

JackResampler::~JackResampler() JackResampler::~JackResampler()
{ {
if (fRingBuffer) if (fRingBuffer)
@@ -36,7 +43,8 @@ JackResampler::~JackResampler()


void JackResampler::Reset() void JackResampler::Reset()
{ {
jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * DEFAULT_RB_SIZE) / 2);
jack_ringbuffer_reset(fRingBuffer);
jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2);
} }


unsigned int JackResampler::ReadSpace() unsigned int JackResampler::ReadSpace()


+ 3
- 1
common/JackResampler.h View File

@@ -40,10 +40,12 @@ class JackResampler
jack_ringbuffer_t* fRingBuffer; jack_ringbuffer_t* fRingBuffer;
unsigned int fNum; unsigned int fNum;
unsigned int fDenom; unsigned int fDenom;
unsigned int fRingBufferSize;
public: public:
JackResampler(); JackResampler();
JackResampler(unsigned int ringbuffer_size);
virtual ~JackResampler(); virtual ~JackResampler();
virtual void Reset(); virtual void Reset();


+ 6
- 19
common/jack/net.h View File

@@ -255,7 +255,8 @@ typedef struct _jack_adapter jack_adapter_t;
* *
* @return 0 on success, otherwise a non-zero error code * @return 0 on success, otherwise a non-zero error code
*/ */
jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size,
jack_adapter_t* jack_create_adapter(int input, int output,
jack_nframes_t host_buffer_size,
jack_nframes_t host_sample_rate, jack_nframes_t host_sample_rate,
jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_buffer_size,
jack_nframes_t adapted_sample_rate); jack_nframes_t adapted_sample_rate);
@@ -268,32 +269,18 @@ jack_adapter_t* jack_create_adapter(jack_nframes_t host_buffer_size,
int jack_destroy_adapter(jack_adapter_t* adapter); int jack_destroy_adapter(jack_adapter_t* adapter);


/** /**
* Push input to ringbuffer
* Push input to and pull output from ringbuffer
* *
* @return 0 on success, otherwise a non-zero error code * @return 0 on success, otherwise a non-zero error code
*/ */
int jack_adapter_push_input(jack_adapter_t * adapter, int channels, float** buffers);
int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);


/** /**
* Pull input from ringbuffer
* Pull input to and push output from ringbuffer
* *
* @return 0 on success, otherwise a non-zero error code * @return 0 on success, otherwise a non-zero error code
*/ */
int jack_adapter_pull_input(jack_adapter_t * adapter, int channels, float** buffers);
/**
* Push output to ringbuffer
*
* @return error code.
*/
int jack_adapter_push_output(jack_adapter_t * adapter, int channels, float** buffers);

/**
* Pull output from ringbuffer
*
* @return 0 on success, otherwise a non-zero error code
*/
int jack_adapter_pull_output(jack_adapter_t * adapter, int channels, float** buffers);
int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);




#ifdef __cplusplus #ifdef __cplusplus


+ 8
- 2
common/wscript View File

@@ -182,9 +182,15 @@ def build(bld):
netlib.includes = includes netlib.includes = includes
netlib.name = 'netlib' netlib.name = 'netlib'
netlib.target = 'jacknet' netlib.target = 'jacknet'
netlib.uselib = uselib
netlib.uselib = 'SAMPLERATE'
netlib.install_path = '${LIBDIR}' netlib.install_path = '${LIBDIR}'
netlib.source = ['JackNetAPI.cpp', 'JackNetInterface.cpp', 'JackNetTool.cpp', 'JackAudioAdapterInterface.cpp', 'JackResampler.cpp', 'ringbuffer.c']
netlib.source = ['JackNetAPI.cpp',
'JackNetInterface.cpp',
'JackNetTool.cpp',
'JackAudioAdapterInterface.cpp',
'JackLibSampleRateResampler.cpp',
'JackResampler.cpp',
'ringbuffer.c']


if bld.env['IS_LINUX']: if bld.env['IS_LINUX']:
netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../linux/JackLinuxTime.c'] netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../linux/JackLinuxTime.c']


+ 19
- 38
linux/alsa/JackAlsaAdapter.cpp View File

@@ -66,14 +66,19 @@ namespace Jack
fAudioInterface.fCardName = strdup ( param->value.str ); fAudioInterface.fCardName = strdup ( param->value.str );
break; break;
case 'r': case 'r':
fAudioInterface.fFrequency = param->value.ui;
SetAdaptedSampleRate ( param->value.ui ); SetAdaptedSampleRate ( param->value.ui );
break; break;
case 'p': case 'p':
fAudioInterface.fBuffering = param->value.ui;
SetAdaptedBufferSize ( param->value.ui ); SetAdaptedBufferSize ( param->value.ui );
break; break;
case 'q': case 'q':
fQuality = param->value.ui; fQuality = param->value.ui;
break; break;
case 'g':
fRingbufferSize = param->value.ui;
break;
} }
} }


@@ -106,7 +111,7 @@ namespace Jack
int JackAlsaAdapter::Close() int JackAlsaAdapter::Close()
{ {
#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fTable.Save();
fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize);
#endif #endif
switch ( fThread.GetStatus() ) switch ( fThread.GetStatus() )
{ {
@@ -147,46 +152,15 @@ namespace Jack
bool JackAlsaAdapter::Execute() bool JackAlsaAdapter::Execute()
{ {
//read data from audio interface //read data from audio interface
if ( fAudioInterface.read() < 0 )
if (fAudioInterface.read() < 0)
return false; return false;

bool failure = false;

//compute resampling factor
jack_nframes_t time1, time2;
ResampleFactor ( time1, time2 );

//resample inputs
for ( int i = 0; i < fCaptureChannels; i++ )
{
fCaptureRingBuffer[i]->SetRatio ( time1, time2 );
if ( fCaptureRingBuffer[i]->WriteResample ( fAudioInterface.fInputSoftChannels[i], fAdaptedBufferSize ) < fAdaptedBufferSize )
failure = true;
}
//resample outputs
for ( int i = 0; i < fPlaybackChannels; i++ )
{
fPlaybackRingBuffer[i]->SetRatio ( time2, time1 );
if ( fPlaybackRingBuffer[i]->ReadResample ( fAudioInterface.fOutputSoftChannels[i], fAdaptedBufferSize ) < fAdaptedBufferSize )
failure = true;
}

#ifdef JACK_MONITOR
fTable.Write ( time1, time2, double ( time1 ) / double ( time2 ), double ( time2 ) / double ( time1 ),
fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace() );
#endif
PushAndPull(fAudioInterface.fInputSoftChannels, fAudioInterface.fOutputSoftChannels, fAdaptedBufferSize);


//write data to audio interface //write data to audio interface
if ( fAudioInterface.write() < 0 )
if (fAudioInterface.write() < 0)
return false; return false;


//reset all ringbuffers in case of failure
if ( failure )
{
jack_error ( "JackAlsaAdapter::Execute ringbuffer failure... reset" );
ResetRingBuffers();
}

return true; return true;
} }


@@ -220,7 +194,7 @@ extern "C"
strcpy ( desc->name, "audioadapter" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy ( desc->name, "audioadapter" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
strcpy ( desc->desc, "netjack audio <==> net backend adapter" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 strcpy ( desc->desc, "netjack audio <==> net backend adapter" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1


desc->nparams = 10;
desc->nparams = 11;
desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );


i = 0; i = 0;
@@ -299,7 +273,6 @@ extern "C"
strcpy ( desc->params[i].short_desc, strcpy ( desc->params[i].short_desc,
"Number of playback channels (defaults to hardware max)" ); "Number of playback channels (defaults to hardware max)" );
strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
i++; i++;
strcpy(desc->params[i].name, "quality"); strcpy(desc->params[i].name, "quality");
@@ -308,6 +281,14 @@ extern "C"
desc->params[i].value.ui = 0; desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "ring-buffer");
desc->params[i].character = 'g';
desc->params[i].type = JackDriverParamInt;
desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);


return desc; return desc;
} }


+ 20
- 9
linux/alsa/JackAlsaAdapter.h View File

@@ -182,6 +182,17 @@ namespace Jack
fInputParams = 0; fInputParams = 0;
fOutputParams = 0; fOutputParams = 0;
fPeriod = 2; fPeriod = 2;
fInputCardBuffer = 0;
fOutputCardBuffer = 0;
for ( int i = 0; i < 256; i++ )
{
fInputCardChannels[i] = 0;
fOutputCardChannels[i] = 0;
fInputSoftChannels[i] = 0;
fOutputSoftChannels[i] = 0;
}
} }


AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) : AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
@@ -369,10 +380,10 @@ namespace Jack
} }
else // SND_PCM_FORMAT_S32 else // SND_PCM_FORMAT_S32
{ {
long* buffer32b = ( long* ) fInputCardBuffer;
int32_t* buffer32b = ( int32_t* ) fInputCardBuffer;
for ( s = 0; s < fBuffering; s++ ) for ( s = 0; s < fBuffering; s++ )
for ( c = 0; c < fCardInputs; c++ ) for ( c = 0; c < fCardInputs; c++ )
fInputSoftChannels[c][s] = float ( buffer32b[c + s*fCardInputs] ) * ( 1.0/float ( LONG_MAX ) );
fInputSoftChannels[c][s] = float ( buffer32b[c + s*fCardInputs] ) * ( 1.0/float ( INT_MAX ) );
} }
break; break;
case SND_PCM_ACCESS_RW_NONINTERLEAVED : case SND_PCM_ACCESS_RW_NONINTERLEAVED :
@@ -394,12 +405,12 @@ namespace Jack
} }
else // SND_PCM_FORMAT_S32 else // SND_PCM_FORMAT_S32
{ {
long* chan32b;
int32_t* chan32b;
for ( c = 0; c < fCardInputs; c++ ) for ( c = 0; c < fCardInputs; c++ )
{ {
chan32b = ( long* ) fInputCardChannels[c];
chan32b = ( int32_t* ) fInputCardChannels[c];
for ( s = 0; s < fBuffering; s++ ) for ( s = 0; s < fBuffering; s++ )
fInputSoftChannels[c][s] = float ( chan32b[s] ) * ( 1.0/float ( LONG_MAX ) );
fInputSoftChannels[c][s] = float ( chan32b[s] ) * ( 1.0/float ( INT_MAX ) );
} }
} }
break; break;
@@ -436,13 +447,13 @@ namespace Jack
} }
else // SND_PCM_FORMAT_S32 else // SND_PCM_FORMAT_S32
{ {
long* buffer32b = ( long* ) fOutputCardBuffer;
int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer;
for ( f = 0; f < fBuffering; f++ ) for ( f = 0; f < fBuffering; f++ )
{ {
for ( unsigned int c = 0; c < fCardOutputs; c++ ) for ( unsigned int c = 0; c < fCardOutputs; c++ )
{ {
float x = fOutputSoftChannels[c][f]; float x = fOutputSoftChannels[c][f];
buffer32b[c + f * fCardOutputs] = long ( max ( min ( x, 1.0 ), -1.0 ) * float ( LONG_MAX ) );
buffer32b[c + f * fCardOutputs] = int32_t ( max ( min ( x, 1.0 ), -1.0 ) * float ( INT_MAX ) );
} }
} }
} }
@@ -472,11 +483,11 @@ namespace Jack
{ {
for ( c = 0; c < fCardOutputs; c++ ) for ( c = 0; c < fCardOutputs; c++ )
{ {
long* chan32b = ( long* ) fOutputCardChannels[c];
int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c];
for ( f = 0; f < fBuffering; f++ ) for ( f = 0; f < fBuffering; f++ )
{ {
float x = fOutputSoftChannels[c][f]; float x = fOutputSoftChannels[c][f];
chan32b[f] = long ( max ( min ( x,1.0 ),-1.0 ) * float ( LONG_MAX ) ) ;
chan32b[f] = int32_t ( max ( min ( x,1.0 ),-1.0 ) * float ( INT_MAX ) ) ;
} }
} }
} }


+ 23
- 27
macosx/coreaudio/JackCoreAudioAdapter.cpp View File

@@ -293,38 +293,22 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon,
{ {
JackCoreAudioAdapter* adapter = static_cast<JackCoreAudioAdapter*>(inRefCon); JackCoreAudioAdapter* adapter = static_cast<JackCoreAudioAdapter*>(inRefCon);
AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData); AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData);
bool failure = false;

jack_nframes_t time1, time2;
adapter->ResampleFactor(time1, time2);

float* inputBuffer[adapter->fCaptureChannels];
float* outputBuffer[adapter->fPlaybackChannels];
for (int i = 0; i < adapter->fCaptureChannels; i++) { for (int i = 0; i < adapter->fCaptureChannels; i++) {
adapter->fCaptureRingBuffer[i]->SetRatio(time1, time2);
if (adapter->fCaptureRingBuffer[i]->WriteResample((float*)adapter->fInputData->mBuffers[i].mData, inNumberFrames) < inNumberFrames)
failure = true;
inputBuffer[i] = (float*)adapter->fInputData->mBuffers[i].mData;
} }

for (int i = 0; i < adapter->fPlaybackChannels; i++) { for (int i = 0; i < adapter->fPlaybackChannels; i++) {
adapter->fPlaybackRingBuffer[i]->SetRatio(time2, time1);
if (adapter->fPlaybackRingBuffer[i]->ReadResample((float*)ioData->mBuffers[i].mData, inNumberFrames) < inNumberFrames)
failure = true;
}

#ifdef JACK_MONITOR
adapter->fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1),
adapter->fCaptureRingBuffer[0]->ReadSpace(), adapter->fPlaybackRingBuffer[0]->WriteSpace());
#endif

// Reset all ringbuffers in case of failure
if (failure) {
jack_error("JackCoreAudioAdapter::Render ringbuffer failure... reset");
adapter->ResetRingBuffers();
outputBuffer[i] = (float*)ioData->mBuffers[i].mData;
} }

adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, inNumberFrames);
return noErr; return noErr;
} }


JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params)
JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params)
:JackAudioAdapterInterface(buffer_size, sample_rate), fInputData(0), fCapturing(false), fPlaying(false), fState(false) :JackAudioAdapterInterface(buffer_size, sample_rate), fInputData(0), fCapturing(false), fPlaying(false), fState(false)
{ {


@@ -392,6 +376,10 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon,
case 'q': case 'q':
fQuality = param->value.ui; fQuality = param->value.ui;
break; break;
case 'g':
fRingbufferSize = param->value.ui;
break;
} }
} }
@@ -960,7 +948,7 @@ int JackCoreAudioAdapter::Open()
int JackCoreAudioAdapter::Close() int JackCoreAudioAdapter::Close()
{ {
#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fTable.Save();
fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize);
#endif #endif
AudioOutputUnitStop(fAUHAL); AudioOutputUnitStop(fAUHAL);
DisposeBuffers(); DisposeBuffers();
@@ -997,7 +985,7 @@ extern "C"
strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
desc->nparams = 11;
desc->nparams = 12;
desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t));


i = 0; i = 0;
@@ -1087,6 +1075,14 @@ extern "C"
desc->params[i].value.ui = 0; desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "ring-buffer");
desc->params[i].character = 'g';
desc->params[i].type = JackDriverParamInt;
desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);


return desc; return desc;
} }


+ 19
- 30
solaris/oss/JackOSSAdapter.cpp View File

@@ -181,6 +181,10 @@ JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample
case 'q': case 'q':
fQuality = param->value.ui; fQuality = param->value.ui;
break; break;
case 'g':
fRingbufferSize = param->value.ui;
break;


} }
} }
@@ -502,10 +506,9 @@ error:
int JackOSSAdapter::Close() int JackOSSAdapter::Close()
{ {
#ifdef DEBUG
fTable.Save();
#ifdef JACK_MONITOR
fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize);
#endif #endif

fThread.Stop(); fThread.Stop();
CloseAux(); CloseAux();
return 0; return 0;
@@ -600,38 +603,16 @@ int JackOSSAdapter::Write()


bool JackOSSAdapter::Execute() bool JackOSSAdapter::Execute()
{ {
//read data from audio interface
if (Read() < 0) if (Read() < 0)
return false; return false;

bool failure = false;
jack_nframes_t time1, time2;
ResampleFactor(time1, time2);
for (int i = 0; i < fCaptureChannels; i++) {
fCaptureRingBuffer[i]->SetRatio(time1, time2);
if (fCaptureRingBuffer[i]->WriteResample(fInputSampleBuffer[i], fAdaptedBufferSize) < fAdaptedBufferSize)
failure = true;
}
for (int i = 0; i < fPlaybackChannels; i++) {
fPlaybackRingBuffer[i]->SetRatio(time2, time1);
if (fPlaybackRingBuffer[i]->ReadResample(fOutputSampleBuffer[i], fAdaptedBufferSize) < fAdaptedBufferSize)
failure = true;
}

#ifdef DEBUG
fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1),
fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace());
#endif
PushAndPull(fInputSampleBuffer, fOutputSampleBuffer, fAdaptedBufferSize);
//write data to audio interface
if (Write() < 0) if (Write() < 0)
return false; return false;
// Reset all ringbuffers in case of failure
if (failure) {
jack_error("JackOSSAdapter::Execute ringbuffer failure... reset");
ResetRingBuffers();
}
return true; return true;
} }


@@ -756,6 +737,14 @@ extern "C"
desc->params[i].value.ui = 0; desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy(desc->params[i].name, "ring-buffer");
desc->params[i].character = 'g';
desc->params[i].type = JackDriverParamInt;
desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
return desc; return desc;
} }


+ 1
- 1
solaris/oss/JackOSSAdapter.h View File

@@ -34,7 +34,7 @@ namespace Jack


typedef jack_default_audio_sample_t jack_sample_t; typedef jack_default_audio_sample_t jack_sample_t;


#define OSS_DRIVER_N_PARAMS 12
#define OSS_DRIVER_N_PARAMS 13
#define OSS_DRIVER_DEF_DEV "/dev/dsp" #define OSS_DRIVER_DEF_DEV "/dev/dsp"
#define OSS_DRIVER_DEF_FS 48000 #define OSS_DRIVER_DEF_FS 48000
#define OSS_DRIVER_DEF_BLKSIZE 1024 #define OSS_DRIVER_DEF_BLKSIZE 1024


+ 22
- 43
windows/portaudio/JackPortAudioAdapter.cpp View File

@@ -27,47 +27,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack namespace Jack
{ {


int JackPortAudioAdapter::Render ( const void* inputBuffer,
void* outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void* userData)
int JackPortAudioAdapter::Render(const void* inputBuffer,
void* outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void* userData)
{ {
JackPortAudioAdapter* adapter = static_cast<JackPortAudioAdapter*>(userData); JackPortAudioAdapter* adapter = static_cast<JackPortAudioAdapter*>(userData);
float** paBuffer;
bool failure = false;

jack_nframes_t time1, time2;
adapter->ResampleFactor ( time1, time2 );

paBuffer = (float**)inputBuffer;
for ( int i = 0; i < adapter->fCaptureChannels; i++ )
{
adapter->fCaptureRingBuffer[i]->SetRatio ( time1, time2 );
if (adapter->fCaptureRingBuffer[i]->WriteResample ( (float*)paBuffer[i], framesPerBuffer ) < framesPerBuffer )
failure = true;
}

paBuffer = (float**)outputBuffer;
for ( int i = 0; i < adapter->fPlaybackChannels; i++ )
{
adapter->fPlaybackRingBuffer[i]->SetRatio ( time2, time1 );
if ( adapter->fPlaybackRingBuffer[i]->ReadResample ( (float*)paBuffer[i], framesPerBuffer ) < framesPerBuffer )
failure = true;
}

#ifdef JACK_MONITOR
adapter->fTable.Write ( time1, time2, double(time1) / double(time2), double(time2) / double(time1),
adapter->fCaptureRingBuffer[0]->ReadSpace(), adapter->fPlaybackRingBuffer[0]->WriteSpace() );
#endif

// Reset all ringbuffers in case of failure
if ( failure )
{
jack_error ( "JackPortAudioAdapter::Render ringbuffer failure... reset" );
adapter->ResetRingBuffers();
}
adapter->PushAndPull((float**)inputBuffer, (float**)outputBuffer, framesPerBuffer);
return paContinue; return paContinue;
} }


@@ -128,6 +96,9 @@ namespace Jack
case 'q': case 'q':
fQuality = param->value.ui; fQuality = param->value.ui;
break; break;
case 'g':
fRingbufferSize = param->value.ui;
break;
} }
} }


@@ -207,7 +178,7 @@ namespace Jack
int JackPortAudioAdapter::Close() int JackPortAudioAdapter::Close()
{ {
#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fTable.Save();
fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize);
#endif #endif
jack_log ( "JackPortAudioAdapter::Close" ); jack_log ( "JackPortAudioAdapter::Close" );
Pa_StopStream ( fStream ); Pa_StopStream ( fStream );
@@ -246,8 +217,8 @@ extern "C"


strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
desc->nparams = 9;
desc->nparams = 10;
desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t));


i = 0; i = 0;
@@ -314,7 +285,7 @@ extern "C"
desc->params[i].value.i = TRUE; desc->params[i].value.i = TRUE;
strcpy(desc->params[i].short_desc, "Display available PortAudio devices"); strcpy(desc->params[i].short_desc, "Display available PortAudio devices");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++; i++;
strcpy(desc->params[i].name, "quality"); strcpy(desc->params[i].name, "quality");
desc->params[i].character = 'q'; desc->params[i].character = 'q';
@@ -323,6 +294,14 @@ extern "C"
strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); strcpy(desc->params[i].long_desc, desc->params[i].short_desc);


i++;
strcpy(desc->params[i].name, "ring-buffer");
desc->params[i].character = 'g';
desc->params[i].type = JackDriverParamInt;
desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 32768)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);

return desc; return desc;
} }




Loading…
Cancel
Save