Commit 187a3aed authored by sletz's avatar sletz
Browse files

rebase from trunk 3563:3613

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3614 0c269be4-1314-0410-8aa9-9f06e86f4224
parent f385f2b0
......@@ -23,11 +23,57 @@ Paul Davis
---------------------------
Jackdmp changes log
---------------------------
---------------------------
2009-07-17 Stephane Letz <letz@grame.fr>
* Loopback backend reborn as a dynamically loadable separated backend.
* -L parameter for loopback backend activated again in jackd.
2009-07-17 Stephane Letz <letz@grame.fr>
* Big rewrite of Solaris boomer driver, seems to work in duplex mode at least.
2009-07-16 Stephane Letz <letz@grame.fr>
* In combined --dbus and --classic compilation code, use PulseAudio acquire/release code.
2009-07-15 Stephane Letz <letz@grame.fr>
* Rename JackDriver::Init method to JackDriver::Initialize (to avoid confusion with JackThread::Init method).
* Update Solaris boomer driver.
* Report some cleanup and documentation improvements done on JACK1 timing functions.
2009-07-11 Stephane Letz <letz@grame.fr>
* Raise drivers time out used in synchronous mode.
2009-07-09 Stephane Letz <letz@grame.fr>
* Use __attribute__((__packed__)) again, more fixes for 64/32 mixed mode.
* Torben Hohn changes for 64/32 mixed mode in wscripts.
* Add compile time option for maximum ports per application.
2009-07-07 Stephane Letz <letz@grame.fr>
* Use __attribute__((__aligned__(32))) instead of __attribute__((__packed__)) for 64/32 mixed mode.
2009-07-03 Stephane Letz <letz@grame.fr>
* Another Tim Bechmann memops.c optimization patch.
2009-07-01 Stephane Letz <letz@grame.fr>
* Tim Bechmann memops.c optimization patch.
2009-06-30 Stephane Letz <letz@grame.fr>
* Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created.
2009-06-19 Stephane Letz <letz@grame.fr>
* Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also.
* NetJack2 code : better error checkout, method renaming.
2009-06-17 Stephane Letz <letz@grame.fr>
......
......@@ -137,8 +137,6 @@ The binary elements are :
- JackRouter.dll : an ASIO/JACK driver that allows ASIO compatible applications to become JACK clients and access the JACK server. ASIO "jackified" applications appear with their names. Ableton Live, Samplitude, Reason, Arturia applications have been successfully tested. To install it, use "regsvr32 JackRouter.dll" in a terminal (use regsvr32 /u JackRouter.dll to uninstall). [VISTA special note: regsvr32 has to be used with "administrator" priviledges to properly register JackRouter.dll (Start Menu -> All Programs -> Accessories -> Right Click on Command Prompt -> Run As Administrator)]. A JackRouter.ini file is used by the driver to read parameters : an [IO] section allows to setup the number of input/output jack ports for the application and a [AUTO_CONNECT] section allows to setup jack ports autoconnection mode to machine input/output.
All dll are compiled in "release" mode. The "Debug" folder contains debug version of all dlls and libraries. MSVCRTD.dll and MSVCP60D.dll debug dll are also included.
WARNING !! WARNING !!
Depending of the used interface and driver settings, the PortAudio layer may add additionnal buffering between the real card interrupt and the jack server callback. This usually result in *unregular* calls of the jack server callback (for example if jack server used a 256 frames buffer and the card used a 512 frames, the jack server callback will be called twice every card interrupt). For proper functionning of jack server and clients in this case, the jack server has to be started in "synchronous" mode, using the "-S" parameter.
......@@ -156,16 +154,6 @@ Automatic server launch
Starting from the 0.64 version, automatic server launch from client is implemented : when the server is not yet running, and if the client uses the "jack_client_open" API, the server will be started automatically. The server configuration is saved in a ".jackdrc" file located in the user home folder. The Qjackctl tool allows to save its configuration in this . jackdrc (setting can be done in Qjackctl Setup/Misc). If no configuration file is found, a default setup will be used.
WARNING : automatic server launch is not implemented on Windows
----------------
Loopback driver
----------------
An experimental loopback driver allows to manually "pipeline" applications connected in sequence, and thus parallelize sequential sub-graph. Lets say we have A ==> B graph, by using the loopback driver, it can be rewritten as : A ==> loopback driver ==> B. At each cycle, the loopback driver copy buffers received on its input ports (at the previous cycle) to its output ports. The resulting graph become parallel and thus can take profit of multi-processors machines, at each cycle A and B can be activated in parallel. Note that the loopback driver add a one buffer delay in the connection, which may be relevant in more complex graphs when having global synchronicity between clients is a desirable property.
To activate loopback driver, use :
- jackd (jackdmp) ... -L n ... where n is the number of input/output ports.
------------------
Validations tools
......@@ -225,6 +213,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console.
1.9.0 : Waf based build system : Nedko Arnaudov, Grame for preliminary OSX support. Control API, dbus based server control access : Nedko Arnaudov, Grame. NetJack2 components (in progress) : jack_net backend, netmanager, audioadapter, netadapter : Romain Moret, Grame. Code restructuring to help port on other architectures : Michael Voigt. Code cleanup/optimization : Tim Blechmann. Improve handling of server internal clients that can now be loaded/unloaded using the new server control API : Grame. A lot of bug fix and improvements.
1.9.1 : Fix jackctl_server_unload_internal. Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. Better isolation of server and clients system resources to allow starting the server in several user account at the same time. Report ringbuffer.c fixes from jack1. Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). Use JACK_DRIVER_DIR variable in internal clients loader. For ALSA driver, synchronize with latest jack1 memops functions. Synchronize jack2 public headers with jack1 ones. Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. Cleanup server starting code for clients directly linked with libjackserver.so. JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. Synchronize ALSA backend code with JACK1 one. Set default mode to 'slow' in JackNetDriver and JackNetAdapter. Simplify audio packet order verification. Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. Better recovery of network overload situations, now "resynchronize" by skipping cycles.". Support for BIG_ENDIAN machines in NetJack2. Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. Support for "-h" option in internal clients to print the parameters. In NetJack2, fix a bug when capture or playback only channels are used. Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. Add a resample quality parameter in audioadapter. Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). Use PRIu32 kind of macro in JackAlsaDriver again. Add a resample quality parameter in netadapter.
1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1).
1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend.
This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer...
......
......@@ -1465,14 +1465,8 @@ EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client)
#ifdef __CLIENTDEBUG__
JackLibGlobals::CheckContext();
#endif
JackTimer timer;
JackEngineControl* control = GetEngineControl();
if (control) {
control->ReadFrameTime(&timer);
return timer.CurFrame();
} else {
return 0;
}
return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0;
}
EXPORT float jack_cpu_load(jack_client_t* ext_client)
......
......@@ -73,7 +73,7 @@ class JackActivationCount
return fValue;
}
};
} POST_PACKED_STRUCTURE;
} // end of namespace
......
......@@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define __JackAtomicArrayState__
#include "JackAtomic.h"
#include "JackCompilerDeps.h"
#include <string.h> // for memcpy
namespace Jack
......@@ -67,7 +68,7 @@ struct AtomicArrayCounter
return *this;
}
};
} POST_PACKED_STRUCTURE;
#define Counter1(e) (e).info.fLongVal
#define GetIndex1(e, state) ((e).info.scounter.fByteVal[state])
......@@ -247,7 +248,7 @@ class JackAtomicArrayState
WriteNextStateStopAux(state);
}
};
} POST_PACKED_STRUCTURE;
} // end of namespace
......
......@@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define __JackAtomicState__
#include "JackAtomic.h"
#include "JackCompilerDeps.h"
#include <string.h> // for memcpy
namespace Jack
......@@ -68,7 +69,7 @@ struct AtomicCounter
return *this;
}
};
} POST_PACKED_STRUCTURE;
#define Counter(e) (e).info.fLongVal
#define CurIndex(e) (e).info.scounter.fShortVal1
......@@ -250,11 +251,10 @@ class JackAtomicState
} while (cur_index != next_index);
}
*/
};
} POST_PACKED_STRUCTURE;
} // end of namespace
#endif
......@@ -79,6 +79,22 @@ int JackAudioDriver::Open(jack_nframes_t buffer_size,
return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
}
int JackAudioDriver::Open(bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency)
{
fCaptureChannels = inchannels;
fPlaybackChannels = outchannels;
fWithMonitorPorts = monitor;
return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
}
int JackAudioDriver::Attach()
{
JackPort* port;
......@@ -269,7 +285,7 @@ void JackAudioDriver::ProcessGraphSync()
fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable);
if (ProcessSlaves() < 0)
jack_error("JackAudioDriver::ProcessSync ProcessSlaves error, engine may now behave abnormally!!");
if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0)
if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0)
jack_error("JackAudioDriver::ProcessSync SuspendRefNum error, engine may now behave abnormally!!");
} else { // Graph not finished: do not activate it
jack_error("JackAudioDriver::ProcessSync: error");
......
......@@ -74,6 +74,16 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver
jack_nframes_t capture_latency,
jack_nframes_t playback_latency);
virtual int Open(bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency);
virtual int Process();
virtual int ProcessNull();
......
......@@ -116,7 +116,7 @@ class JackFixedArray
return fCounter;
}
};
} POST_PACKED_STRUCTURE;
/*!
\brief Utility class.
......@@ -151,7 +151,8 @@ class JackFixedArray1 : public JackFixedArray<SIZE>
return true;
}
}
};
} POST_PACKED_STRUCTURE;
/*!
\brief Utility class.
......@@ -226,7 +227,7 @@ class JackFixedMatrix
return false;
}
};
} POST_PACKED_STRUCTURE;
/*!
\brief Utility class.
......@@ -339,7 +340,7 @@ class JackLoopFeedback
return -1;
}
};
} POST_PACKED_STRUCTURE;
/*!
\brief For client timing measurements.
......@@ -356,6 +357,7 @@ struct JackClientTiming
{}
~JackClientTiming()
{}
} POST_PACKED_STRUCTURE;
/*!
......@@ -450,7 +452,7 @@ class SERVER_EXPORT JackConnectionManager
int ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing);
int SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec);
};
} POST_PACKED_STRUCTURE;
} // end of namespace
......
......@@ -38,10 +38,14 @@
#endif
#define DRIVER_PORT_NUM 256
#define PORT_NUM_FOR_CLIENT 256
#ifndef PORT_NUM_FOR_CLIENT
#define PORT_NUM_FOR_CLIENT 512
#endif
#define FIRST_AVAILABLE_PORT 1
#define CONNECTION_NUM_FOR_PORT 256
#define CONNECTION_NUM_FOR_PORT PORT_NUM_FOR_CLIENT
#ifndef CLIENT_NUM
#define CLIENT_NUM 64
......@@ -86,6 +90,7 @@
#define SOCKET_TIME_OUT 5 // in sec
#define DRIVER_OPEN_TIMEOUT 5 // in sec
#define FREEWHEEL_DRIVER_TIMEOUT 10 // in sec
#define DRIVER_TIMEOUT_FACTOR 10
#define NO_PORT 0xFFFE
......
......@@ -43,6 +43,7 @@
#include "JackLockedEngine.h"
#include "JackConstants.h"
#include "JackDriverLoader.h"
#include "JackServerGlobals.h"
using namespace Jack;
......@@ -618,7 +619,9 @@ get_realtime_priority_constraint()
return constraint_ptr;
}
EXPORT jackctl_server_t * jackctl_server_create()
EXPORT jackctl_server_t * jackctl_server_create(
bool (* on_device_acquire)(const char * device_name),
void (* on_device_release)(const char * device_name))
{
struct jackctl_server * server_ptr;
union jackctl_parameter_value value;
......@@ -762,6 +765,9 @@ EXPORT jackctl_server_t * jackctl_server_create()
goto fail_free_parameters;
}
JackServerGlobals::on_device_acquire = on_device_acquire;
JackServerGlobals::on_device_release = on_device_release;
if (!jackctl_drivers_load(server_ptr))
{
goto fail_free_parameters;
......
......@@ -88,7 +88,9 @@ jackctl_wait_signals(
sigset_t signals);
EXPORT jackctl_server_t *
jackctl_server_create();
jackctl_server_create(
bool (* on_device_acquire)(const char * device_name),
void (* on_device_release)(const char * device_name));
EXPORT void
jackctl_server_destroy(
......
......@@ -339,7 +339,7 @@ int JackDriver::SetSampleRate(jack_nframes_t sample_rate)
return 0;
}
bool JackDriver::Init()
bool JackDriver::Initialize()
{
return true;
}
......
......@@ -203,7 +203,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface
virtual JackClientControl* GetClientControl() const;
virtual bool IsRealTime() const;
virtual bool Init(); // To be called by the wrapping thread Init method when the driver is a "blocking" one
virtual bool Initialize(); // To be called by the wrapping thread Init method when the driver is a "blocking" one
};
......
......@@ -54,7 +54,8 @@ namespace Jack
mean += fTable[i];
return mean / MAX_SIZE;
}
};
} POST_PACKED_STRUCTURE;
class JackDelayLockedLoop
{
......@@ -136,7 +137,7 @@ namespace Jack
return fCurrentWakeup;
}
};
} POST_PACKED_STRUCTURE;
class JackAtomicDelayLockedLoop : public JackAtomicState<JackDelayLockedLoop>
{
......@@ -201,7 +202,7 @@ namespace Jack
return res;
}
};
} POST_PACKED_STRUCTURE;
/*
Torben Hohn PI controler from JACK1
......@@ -301,7 +302,6 @@ namespace Jack
}
*/
double GetRatio(int error)
{
double smooth_offset = error;
......
......@@ -44,8 +44,8 @@ class SERVER_EXPORT JackTimer
jack_time_t fCurrentCallback;
jack_time_t fNextWakeUp;
float fSecondOrderIntegrator;
bool fInitialized;
float fFilterCoefficient; /* set once, never altered */
bool fInitialized;
public:
......@@ -67,7 +67,7 @@ class SERVER_EXPORT JackTimer
return fCurrentWakeup;
}
};
} POST_PACKED_STRUCTURE;
/*!
\brief A class using the JackAtomicState to manage jack time.
......
......@@ -41,7 +41,7 @@ int JackFreewheelDriver::Process()
} else {
fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients
if (fEngineControl->fSyncMode) {
if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0) {
if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) {
jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error");
return -1;
}
......
......@@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackSystemDeps.h"
#include "JackLoopbackDriver.h"
#include "JackDriverLoader.h"
#include "JackEngineControl.h"
#include "JackGraphManager.h"
#include "JackError.h"
......@@ -31,8 +32,6 @@ namespace Jack
int JackLoopbackDriver::Process()
{
assert(fCaptureChannels == fPlaybackChannels);
// Loopback copy
for (int i = 0; i < fCaptureChannels; i++) {
memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(float) * fEngineControl->fBufferSize);
......@@ -40,7 +39,7 @@ int JackLoopbackDriver::Process()
fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); // Signal all clients
if (fEngineControl->fSyncMode) {
if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0) {
if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) {
jack_error("JackLoopbackDriver::ProcessSync SuspendRefNum error");
return -1;
}
......@@ -49,3 +48,61 @@ int JackLoopbackDriver::Process()
}
} // end of namespace
#ifdef __cplusplus
extern "C"
{
#endif
SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor()
{
jack_driver_desc_t * desc;
unsigned int i;
desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t));
strcpy(desc->name, "loopback"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
strcpy(desc->desc, "Loopback backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
desc->nparams = 1;
desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
i = 0;
strcpy(desc->params[i].name, "channels");
desc->params[i].character = 'c';
desc->params[i].type = JackDriverParamInt;
desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Maximum number of loopback ports");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
return desc;
}
SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
{
const JSList * node;
const jack_driver_param_t * param;
int channels = 2;
for (node = params; node; node = jack_slist_next (node)) {
param = (const jack_driver_param_t *) node->data;
switch (param->character) {
case 'c':
channels = param->value.ui;
break;
}
}
Jack::JackDriverClientInterface* driver = new Jack::JackLoopbackDriver(engine, table);
if (driver->Open(1, 1, channels, channels, false, "loopback", "loopback", 0, 0) == 0) {
return driver;
} else {
delete driver;
return NULL;
}
}
#ifdef __cplusplus
}
#endif
......@@ -121,13 +121,13 @@ namespace Jack
as a "dummy driver, until Init method returns.
*/
bool JackNetDriver::Init()
bool JackNetDriver::Initialize()
{
jack_log ( "JackNetDriver::Init()" );
jack_log("JackNetDriver::Initialize()");
//new loading, but existing socket, restart the driver
if (fSocket.IsSocket()) {
jack_info( "Restarting driver..." );
jack_info("Restarting driver...");
FreeAll();
}
......
......@@ -50,7 +50,7 @@ namespace Jack
JackGnuPlotMonitor<float>* fNetTimeMon;
#endif
bool Init();
bool Initialize();
void FreeAll();
int AllocPorts();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment