Commit 51fbf0cf authored by sletz's avatar sletz
Browse files

rebase from trunk 3420:3447

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3448 0c269be4-1314-0410-8aa9-9f06e86f4224
parent b63e6a8f
......@@ -17,38 +17,55 @@ Nedko Arnaudov
Fernando Lopez-Lezcano
Romain Moret
Florian Faber
Michael Voigt
Michael Voigt
Torben Hohn
---------------------------
Jackdmp changes log
---------------------------
---------------------------
2009-03-10 Stephane Letz <letz@grame.fr>
2009-03-19 Stephane Letz <letz@grame.fr>
* Tim Blechmann optimization patch (inlining some heavy used methods).
2009-03-12 Stephane Letz <letz@grame.fr>
* Add -g (ring-buffer) parameter to netadapter.
* Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1).
2009-03-12 Stephane Letz <letz@grame.fr>
* Try automatic adaptative mode in adapters.
2009-03-11 Stephane Letz <letz@grame.fr>
* Client incorrect re-naming fixed : now done at socket level also.
2009-03-10 Stephane Letz <letz@grame.fr>
* Add -g (ring-buffer) parameter to netadapter.
* Automatic adaptative ringbuffer size mode when -g = 0.
2009-03-09 Stephane Letz <letz@grame.fr>
* Use Torben Hohn PI controler code for adapters (in progress).
* Use Torben Hohn PI controler code for adapters (in progress).
2009-03-05 Stephane Letz <letz@grame.fr>
* Support for BIG_ENDIAN machines in NetJack2 for transport data.
* Support for BIG_ENDIAN machines in NetJack2 for transport data.
* Add auto_connect parameter in netmanager and netadapter.
2009-03-03 Stephane Letz <letz@grame.fr>
* More robust profiling tools when clients come and go.
2009-03-01 Stephane Letz <letz@grame.fr>
* Raise default port number to 1024.
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.
......@@ -57,8 +74,8 @@ Torben Hohn
* Fix JackNetDriver::Close method.
* 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 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>
......
......@@ -219,10 +219,12 @@ extern "C"
thread_routine routine,
void *arg);
EXPORT int jack_drop_real_time_scheduling (pthread_t thread);
EXPORT int jack_client_stop_thread (jack_client_t* client, pthread_t thread);
EXPORT int jack_client_kill_thread (jack_client_t* client, pthread_t thread);
#ifndef WIN32
EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc);
#endif
EXPORT char * jack_get_internal_client_name (jack_client_t *client,
jack_intclient_t intclient);
EXPORT jack_intclient_t jack_internal_client_handle (jack_client_t *client,
......@@ -1759,8 +1761,8 @@ EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client)
JackEngineControl* control = GetEngineControl();
return (control->fRealTime) ? control->fMaxClientPriority : -1;
}
}
}
EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority)
{
JackEngineControl* control = GetEngineControl();
......@@ -1792,6 +1794,13 @@ EXPORT int jack_client_kill_thread(jack_client_t* client, pthread_t thread)
return JackThread::KillImp(thread);
}
#ifndef WIN32
EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc)
{
JackGlobals::fJackThreadCreator = jtc;
}
#endif
// intclient.h
EXPORT int jack_internal_client_new (const char *client_name,
const char *load_name,
......
......@@ -36,20 +36,21 @@ namespace Jack
int JackAudioAdapter::Process (jack_nframes_t frames, void* arg)
{
JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg);
if (!adapter->fAudioAdapter->IsRunning())
return 0;
float* inputBuffer[adapter->fAudioAdapter->GetInputs()];
float* outputBuffer[adapter->fAudioAdapter->GetOutputs()];
// Always clear output
for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) {
inputBuffer[i] = (float*)jack_port_get_buffer(adapter->fCapturePortList[i], frames);
memset(inputBuffer[i], 0, frames * sizeof(float));
}
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;
}
int JackAudioAdapter::BufferSize ( jack_nframes_t buffer_size, void* arg )
......@@ -70,23 +71,23 @@ namespace Jack
//JackAudioAdapter *********************************************************
JackAudioAdapter::JackAudioAdapter (jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params, bool system)
JackAudioAdapter::JackAudioAdapter (jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params, bool system)
:fJackClient(jack_client), fAudioAdapter(audio_io)
{
const JSList* node;
const jack_driver_param_t* param;
fAutoConnect = false;
for (node = params; node; node = jack_slist_next(node)) {
param = (const jack_driver_param_t*) node->data;
switch (param->character) {
case 'c':
fAutoConnect = param->value.i;
fAutoConnect = true;
break;
}
}
}
JackAudioAdapter::~JackAudioAdapter()
{
// When called, Close has already been used for the client, thus ports are already unregistered.
......@@ -105,11 +106,11 @@ namespace Jack
delete[] fCapturePortList;
delete[] fPlaybackPortList;
}
void JackAudioAdapter::ConnectPorts()
{
const char **ports;
ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
if (ports != NULL) {
for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) {
......@@ -117,7 +118,7 @@ namespace Jack
}
free(ports);
}
ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput);
if (ports != NULL) {
for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) {
......@@ -137,7 +138,7 @@ namespace Jack
char name[32];
jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs());
fAudioAdapter->Create();
//jack ports
fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()];
fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()];
......@@ -165,7 +166,7 @@ namespace Jack
goto fail;
if ( jack_activate ( fJackClient ) < 0 )
goto fail;
if (fAutoConnect)
ConnectPorts();
......
......@@ -52,13 +52,12 @@ namespace Jack
for (int i = 1; i < max; i++)
{
fprintf(file, "%d \t %d \t %d \t %f \t %f \t %d \t %d \n",
fTable[i].delta, fTable[i+1].time1 - fTable[i].time1,
fTable[i+1].time2 - fTable[i].time2,
fTable[i].delta, fTable[i].time1, fTable[i].time2,
fTable[i].r1, fTable[i].r2, fTable[i].pos1, fTable[i].pos2);
}
fclose(file);
/* No used for now
// No used for now
// Adapter timing 1
file = fopen("AdapterTiming1.plot", "w");
fprintf(file, "set multiplot\n");
......@@ -68,9 +67,9 @@ namespace Jack
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,");
sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Ringbuffer error\" with lines,");
fprintf(file, buffer);
sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines");
sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Ringbuffer error with timing correction\" with lines");
fprintf(file, buffer);
fprintf(file, "\n unset multiplot\n");
......@@ -89,8 +88,7 @@ namespace Jack
fprintf(file, buffer);
fclose(file);
*/
// Adapter timing 2
file = fopen("AdapterTiming2.plot", "w");
fprintf(file, "set multiplot\n");
......@@ -155,16 +153,32 @@ namespace Jack
}
#endif
void JackAudioAdapterInterface::GrowRingBufferSize()
{
fRingbufferCurSize *= 2;
}
void JackAudioAdapterInterface::AdaptRingBufferSize()
{
if (fHostBufferSize > fAdaptedBufferSize)
fRingbufferCurSize = 4 * fHostBufferSize;
else
fRingbufferCurSize = 4 * fAdaptedBufferSize;
}
void JackAudioAdapterInterface::ResetRingBuffers()
{
if (fRingbufferCurSize > DEFAULT_RB_SIZE)
fRingbufferCurSize = DEFAULT_RB_SIZE;
for (int i = 0; i < fCaptureChannels; i++)
fCaptureRingBuffer[i]->Reset();
fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
for (int i = 0; i < fPlaybackChannels; i++)
fPlaybackRingBuffer[i]->Reset();
fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
}
void JackAudioAdapterInterface::Reset()
void JackAudioAdapterInterface::Reset()
{
ResetRingBuffers();
fRunning = false;
......@@ -179,11 +193,25 @@ namespace Jack
//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 (fAdaptative) {
AdaptRingBufferSize();
jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize);
} else {
if (fRingbufferCurSize > DEFAULT_RB_SIZE)
fRingbufferCurSize = DEFAULT_RB_SIZE;
jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize);
}
for (int i = 0; i < fCaptureChannels; i++ ) {
fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality);
fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
}
for (int i = 0; i < fPlaybackChannels; i++ ) {
fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality);
fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
}
if (fCaptureChannels > 0)
jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
if (fPlaybackChannels > 0)
......@@ -206,14 +234,14 @@ namespace Jack
{
bool failure = false;
fRunning = true;
// Finer estimation of the position in the ringbuffer
int delta_frames = (fPullAndPushTime > 0) ? (int)((float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0;
double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames);
/*
Finer estimation of the position in the ringbuffer ??
int delta_frames = (int)(float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f;
double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset() - delta_frames);
*/
double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset());
#ifdef JACK_MONITOR
fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace());
#endif
// Push/pull from ringbuffer
for (int i = 0; i < fCaptureChannels; i++) {
......@@ -223,18 +251,17 @@ namespace Jack
}
for (int i = 0; i < fPlaybackChannels; i++) {
fPlaybackRingBuffer[i]->SetRatio(1 / ratio);
fPlaybackRingBuffer[i]->SetRatio(1/ratio);
if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames)
failure = true;
}
#ifdef JACK_MONITOR
fTable.Write(0, 0, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace());
#endif
// Reset all ringbuffers in case of failure
if (failure) {
jack_error("JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset");
if (fAdaptative) {
GrowRingBufferSize();
jack_info("Ringbuffer size = %d frames", fRingbufferCurSize);
}
ResetRingBuffers();
return -1;
} else {
......@@ -244,28 +271,24 @@ namespace Jack
int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames)
{
bool failure = false;
fPullAndPushTime = GetMicroSeconds();
if (!fRunning)
return 0;
int res = 0;
// Push/pull from ringbuffer
for (int i = 0; i < fCaptureChannels; i++) {
if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames)
failure = true;
res = -1;
}
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;
res = -1;
}
return res;
}
} // namespace
......@@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackResampler.h"
#include "JackFilters.h"
#include "JackConstants.h"
#include <stdio.h>
namespace Jack
{
......@@ -89,12 +90,15 @@ namespace Jack
JackResampler** fPlaybackRingBuffer;
unsigned int fQuality;
unsigned int fRingbufferSize;
unsigned int fRingbufferCurSize;
jack_time_t fPullAndPushTime;
bool fRunning;
bool fAdaptative;
void ResetRingBuffers();
void AdaptRingBufferSize();
void GrowRingBufferSize();
public:
......@@ -107,9 +111,11 @@ namespace Jack
fAdaptedSampleRate ( sample_rate ),
fPIControler(sample_rate / sample_rate, 256),
fCaptureRingBuffer(NULL), fPlaybackRingBuffer(NULL),
fQuality(0), fRingbufferSize(DEFAULT_RB_SIZE),
fQuality(0),
fRingbufferCurSize(DEFAULT_ADAPTATIVE_SIZE),
fPullAndPushTime(0),
fRunning(false)
fRunning(false),
fAdaptative(true)
{}
JackAudioAdapterInterface ( jack_nframes_t host_buffer_size,
jack_nframes_t host_sample_rate,
......@@ -123,7 +129,6 @@ namespace Jack
fAdaptedSampleRate ( adapted_sample_rate ),
fPIControler(host_sample_rate / host_sample_rate, 256),
fQuality(0),
fRingbufferSize(DEFAULT_RB_SIZE),
fPullAndPushTime(0),
fRunning ( false )
{}
......@@ -131,11 +136,6 @@ namespace Jack
virtual ~JackAudioAdapterInterface()
{}
bool IsRunning()
{
return fRunning;
}
virtual void Reset();
virtual void Create();
......@@ -154,12 +154,16 @@ namespace Jack
virtual int SetHostBufferSize ( jack_nframes_t buffer_size )
{
fHostBufferSize = buffer_size;
if (fAdaptative)
AdaptRingBufferSize();
return 0;
}
virtual int SetAdaptedBufferSize ( jack_nframes_t buffer_size )
{
fAdaptedBufferSize = buffer_size;
if (fAdaptative)
AdaptRingBufferSize();
return 0;
}
......@@ -217,7 +221,7 @@ namespace Jack
int PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames);
int PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames);
};
}
......
......@@ -674,13 +674,11 @@ int JackClient::TransportReposition(jack_position_t* pos)
jack_transport_state_t JackClient::TransportQuery(jack_position_t* pos)
{
jack_log("TransportQuery");
return GetEngineControl()->fTransport.Query(pos);
}
jack_nframes_t JackClient::GetCurrentTransportFrame()
{
jack_log("GetCurrentTransportFrame");
return GetEngineControl()->fTransport.GetCurrentFrame();
}
......
......@@ -83,11 +83,6 @@ bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const
// External API
//--------------
int JackConnectionManager::GetActivation(int refnum) const
{
return fInputCounter[refnum].GetValue();
}
/*!
\brief Connect port_src to port_dst.
*/
......
......@@ -440,7 +440,12 @@ class SERVER_EXPORT JackConnectionManager
void DirectConnect(int ref1, int ref2);
void DirectDisconnect(int ref1, int ref2);
int GetActivation(int refnum) const;
int GetActivation(int refnum) const
{
return fInputCounter[refnum].GetValue();
}
// Graph
void ResetGraph(JackClientTiming* timing);
......
......@@ -33,44 +33,6 @@ static inline jack_time_t JACK_MAX(jack_time_t a, jack_time_t b)
return (a < b) ? b : a;
}
void JackEngineControl::CycleIncTime(jack_time_t callback_usecs)
{
// Timer
fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs);
}
void JackEngineControl::CycleBegin(JackClientInterface** table,
JackGraphManager* manager,
jack_time_t cur_cycle_begin,
jack_time_t prev_cycle_end)
{
fTransport.CycleBegin(fSampleRate, cur_cycle_begin);
CalcCPULoad(table, manager, cur_cycle_begin, prev_cycle_end);
#ifdef JACK_MONITOR
fProfiler.Profile(table, manager, fPeriodUsecs, cur_cycle_begin, prev_cycle_end);
#endif
}
void JackEngineControl::CycleEnd(JackClientInterface** table)
{
fTransport.CycleEnd(table, fSampleRate, fBufferSize);
}
void JackEngineControl::InitFrameTime()
{
fFrameTimer.InitFrameTime();
}
void JackEngineControl::ResetFrameTime(jack_time_t cur_cycle_begin)
{
fFrameTimer.ResetFrameTime(fSampleRate, cur_cycle_begin, fPeriodUsecs);
}
void JackEngineControl::ReadFrameTime(JackTimer* timer)
{
fFrameTimer.ReadFrameTime(timer);
}
void JackEngineControl::CalcCPULoad(JackClientInterface** table,
JackGraphManager* manager,
jack_time_t cur_cycle_begin,
......@@ -126,9 +88,4 @@ void JackEngineControl::NotifyXRun(float delayed_usecs)
fMaxDelayedUsecs = delayed_usecs;
}
void JackEngineControl::ResetXRun()
{
fMaxDelayedUsecs = 0.f;
}
} // end of namespace
......@@ -119,18 +119,48 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem
{}
// Cycle
void CycleIncTime(jack_time_t callback_usecs);
void CycleBegin(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end);
void CycleEnd(JackClientInterface** table);
void CycleIncTime(jack_time_t callback_usecs)
{
// Timer
fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs);
}
void CycleBegin(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end)
{
fTransport.CycleBegin(fSampleRate, cur_cycle_begin);
CalcCPULoad(table, manager, cur_cycle_begin, prev_cycle_end);
#ifdef JACK_MONITOR
fProfiler.Profile(table, manager, fPeriodUsecs, cur_cycle_begin, prev_cycle_end);
#endif
}
void CycleEnd(JackClientInterface** table)
{
fTransport.CycleEnd(table, fSampleRate, fBufferSize);
}
// Timer
void InitFrameTime();
void ResetFrameTime(jack_time_t callback_usecs);
void ReadFrameTime(JackTimer* timer);
void InitFrameTime()
{
fFrameTimer.InitFrameTime();
}
void ResetFrameTime(jack_time_t callback_usecs)
{