Commit a979d06e authored by sletz's avatar sletz
Browse files

Add auto_connect parameter in netmanager and netadapter.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3401 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 6000d23d
......@@ -25,7 +25,8 @@ Michael Voigt
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>
......
......@@ -69,6 +69,24 @@ namespace Jack
}
//JackAudioAdapter *********************************************************
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;
break;
}
}
}
JackAudioAdapter::~JackAudioAdapter()
{
// When called, Close has already been used for the client, thus ports are already unregistered.
......@@ -87,6 +105,27 @@ 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++) {
jack_connect(fJackClient,jack_port_name(fCapturePortList[i]), ports[i]);
}
free(ports);
}
ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput);
if (ports != NULL) {
for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) {
jack_connect(fJackClient, ports[i], jack_port_name(fPlaybackPortList[i]));
}
free(ports);
}
}
void JackAudioAdapter::Reset()
{
......@@ -126,6 +165,9 @@ namespace Jack
goto fail;
if ( jack_activate ( fJackClient ) < 0 )
goto fail;
if (fAutoConnect)
ConnectPorts();
// Ring buffer are now allocated..
return fAudioAdapter->Open();
......
......@@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define __JackAudioAdapter__
#include "JackAudioAdapterInterface.h"
#include "driver_interface.h"
namespace Jack
{
......@@ -42,15 +43,15 @@ namespace Jack
jack_client_t* fJackClient;
JackAudioAdapterInterface* fAudioAdapter;
bool fAutoConnect;
void FreePorts();
void ConnectPorts();
void Reset();
public:
JackAudioAdapter ( jack_client_t* jack_client, JackAudioAdapterInterface* audio_io ) :
fJackClient ( jack_client ), fAudioAdapter ( audio_io )
{}
JackAudioAdapter(jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params = NULL, bool system = false);
~JackAudioAdapter();
int Open();
......
......@@ -351,48 +351,21 @@ namespace Jack
//process-----------------------------------------------------------------------------
int JackNetAdapter::Process()
{
bool failure = false;
int port_index;
//read data from the network
//in case of fatal network error, stop the process
if ( Read() == SOCKET_ERROR )
if (Read() == SOCKET_ERROR)
return SOCKET_ERROR;
//get the resample factor,
jack_time_t time1, time2;
ResampleFactor ( time1, time2 );
//resample input data,
for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
{
fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 );
if ( fCaptureRingBuffer[port_index]->WriteResample ( fSoftCaptureBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize )
failure = true;
}
//and output data,
for ( port_index = 0; port_index < fPlaybackChannels; port_index++ )
{
fPlaybackRingBuffer[port_index]->SetRatio ( time2, time1 );
if ( fPlaybackRingBuffer[port_index]->ReadResample ( fSoftPlaybackBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize )
failure = true;
}
PushAndPull(fSoftCaptureBuffer, fSoftPlaybackBuffer, fAdaptedBufferSize);
//then write data to network
//in case of failure, stop process
if ( Write() == SOCKET_ERROR )
if (Write() == SOCKET_ERROR)
return SOCKET_ERROR;
//if there was any ringbuffer failure during resampling, reset
if ( failure )
{
jack_error ( "JackNetAdapter::Execute ringbuffer failure...reset." );
ResetRingBuffers();
}
return 0;
}
} // namespace Jack
//loader------------------------------------------------------------------------------
......@@ -413,7 +386,7 @@ extern "C"
strcpy(desc->name, "netadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
strcpy(desc->desc, "netjack net <==> audio 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 ) );
int i = 0;
......@@ -487,6 +460,14 @@ extern "C"
desc->params[i].value.ui = 0;
strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
i++;
strcpy ( desc->params[i].name, "auto_connect" );
desc->params[i].character = 'c';
desc->params[i].type = JackDriverParamBool;
desc->params[i].value.i = false;
strcpy ( desc->params[i].short_desc, "Auto connect netmaster to system ports" );
strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
return desc;
}
......@@ -501,7 +482,7 @@ extern "C"
try {
adapter = new Jack::JackAudioAdapter ( jack_client, new Jack::JackNetAdapter ( jack_client, buffer_size, sample_rate, params ) );
adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackNetAdapter(jack_client, buffer_size, sample_rate, params), params, false);
assert ( adapter );
if ( adapter->Open() == 0 )
......
......@@ -26,7 +26,7 @@ namespace Jack
{
//JackNetMaster******************************************************************************************************
JackNetMaster::JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip )
JackNetMaster::JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip)
: JackNetMasterInterface ( params, socket, multicast_ip )
{
jack_log ( "JackNetMaster::JackNetMaster" );
......@@ -107,7 +107,7 @@ namespace Jack
#endif
}
//init--------------------------------------------------------------------------------
bool JackNetMaster::Init()
bool JackNetMaster::Init(bool auto_connect)
{
//network init
if ( !JackNetMasterInterface::Init() )
......@@ -141,9 +141,10 @@ namespace Jack
jack_error ( "Can't activate jack client." );
goto fail;
}
if (auto_connect)
ConnectPorts();
jack_info ( "New NetMaster started." );
return true;
fail:
......@@ -156,27 +157,26 @@ namespace Jack
//jack ports--------------------------------------------------------------------------
int JackNetMaster::AllocPorts()
{
jack_log ( "JackNetMaster::AllocPorts" );
uint i;
char name[24];
jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient );
unsigned long port_flags;
jack_log ( "JackNetMaster::AllocPorts" );
//audio
port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
for ( i = 0; i < fParams.fSendAudioChannels; i++ )
{
sprintf ( name, "to_slave_%d", i+1 );
if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL )
return -1;
//port latency
jack_port_set_latency ( fAudioCapturePorts[i], 0 );
}
port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
for ( i = 0; i < fParams.fReturnAudioChannels; i++ )
{
sprintf ( name, "from_slave_%d", i+1 );
if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL )
if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL )
return -1;
//port latency
switch ( fParams.fNetworkMode )
......@@ -192,21 +192,21 @@ namespace Jack
break;
}
}
//midi
port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
for ( i = 0; i < fParams.fSendMidiChannels; i++ )
{
sprintf ( name, "midi_to_slave_%d", i+1 );
if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL )
return -1;
//port latency
jack_port_set_latency ( fMidiCapturePorts[i], 0 );
}
port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
for ( i = 0; i < fParams.fReturnMidiChannels; i++ )
{
sprintf ( name, "midi_from_slave_%d", i+1 );
if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL )
if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL )
return -1;
//port latency
switch ( fParams.fNetworkMode )
......@@ -224,6 +224,27 @@ namespace Jack
}
return 0;
}
void JackNetMaster::ConnectPorts()
{
const char **ports;
ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput);
if (ports != NULL) {
for (unsigned int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) {
jack_connect(fJackClient, ports[i], jack_port_name(fAudioCapturePorts[i]));
}
free(ports);
}
ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
if (ports != NULL) {
for (unsigned int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) {
jack_connect(fJackClient, jack_port_name(fAudioPlaybackPorts[i]), ports[i]);
}
free(ports);
}
}
void JackNetMaster::FreePorts()
{
......@@ -439,6 +460,7 @@ namespace Jack
fSocket.SetPort ( DEFAULT_PORT );
fGlobalID = 0;
fRunning = true;
fAutoConnect = false;
const JSList* node;
const jack_driver_param_t* param;
......@@ -453,8 +475,14 @@ namespace Jack
else
jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP);
break;
case 'p':
fSocket.SetPort ( param->value.ui );
break;
case 'c':
fAutoConnect = param->value.i;
break;
}
}
......@@ -613,8 +641,8 @@ namespace Jack
SetSlaveName ( params );
//create a new master and add it to the list
JackNetMaster* master = new JackNetMaster ( fSocket, params, fMulticastIP );
if ( master->Init() )
JackNetMaster* master = new JackNetMaster(fSocket, params, fMulticastIP);
if ( master->Init(fAutoConnect) )
{
fMasterList.push_back ( master );
return master;
......@@ -674,7 +702,7 @@ extern "C"
strcpy ( desc->name, "netmanager" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
strcpy ( desc->desc, "netjack multi-cast master component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
desc->nparams = 2;
desc->nparams = 3;
desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
int i = 0;
......@@ -692,6 +720,14 @@ extern "C"
desc->params[i].value.i = DEFAULT_PORT;
strcpy ( desc->params[i].short_desc, "UDP port" );
strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
i++;
strcpy ( desc->params[i].name, "auto_connect" );
desc->params[i].character = 'c';
desc->params[i].type = JackDriverParamBool;
desc->params[i].value.i = false;
strcpy ( desc->params[i].short_desc, "Auto connect netmaster to system ports" );
strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
return desc;
}
......
......@@ -53,14 +53,14 @@ namespace Jack
//sync and transport
int fLastTransportState;
//monitoring
#ifdef JACK_MONITOR
jack_time_t fPeriodUsecs;
JackGnuPlotMonitor<float>* fNetTimeMon;
#endif
bool Init();
bool Init(bool auto_connect);
int AllocPorts();
void FreePorts();
void Exit();
......@@ -71,9 +71,10 @@ namespace Jack
int Process();
void TimebaseCallback ( jack_position_t* pos );
void ConnectPorts();
public:
JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip );
JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip);
~JackNetMaster ();
bool IsSlaveReadyToRoll();
......@@ -101,6 +102,7 @@ namespace Jack
master_list_t fMasterList;
uint32_t fGlobalID;
bool fRunning;
bool fAutoConnect;
void Run();
JackNetMaster* MasterInit ( session_params_t& params );
......@@ -110,7 +112,7 @@ namespace Jack
int SyncCallback ( jack_transport_state_t state, jack_position_t* pos );
public:
JackNetMasterManager ( jack_client_t* jack_client, const JSList* params );
JackNetMasterManager ( jack_client_t* jack_client, const JSList* params);
~JackNetMasterManager();
};
}
......
-------------------------------
Jackmp on windows
Jackmp on Windows
-------------------------------
This folder contains all the windows specific sources.
......@@ -34,11 +34,11 @@ You can make a small installer ('setup.exe') with CreateInstallFree, a little fr
A binary version of qjackctl is also included.
-------------------------------
Running Jack on windows
Running Jack on Windows
-------------------------------
You can use two drivers : PortAudio and NetDriver.
The PortAudio backend allow the use of many soundcards, using ASIO or WMME drivers (any ASIO driver can be seen by PortAudio).
The PortAudio backend allow the use of many soundcards, using ASIO, DirectSound or WMME drivers (any ASIO driver can be seen by PortAudio).
The NetDriver allow you to use NetJack2 on windows. Thus you can easily exchange midi and audio streams bitween computers (Linux, MacOSX or Windows).
In both cases, you have to use the minimalist :
'jackd -R -d ...'
......@@ -46,7 +46,11 @@ In both cases, you have to use the minimalist :
'jackd -R -S -d portaudio -l'
Other options still stay the same.
You can also pick a binary of Qjackctl, but this is still in development.
You can also pick a binary of Qjackctl, but this is still in development.
-------------------------------
Running Jack on windows
-------------------------------
More information at : 'http://www.grame.fr/~letz/jackdmp.html'.
......
......@@ -28,7 +28,7 @@ It is compiled from the latest CVS version which is using QT4 framework. To uses
- quit qjackctl.exe and start is again, it should now launch the jack server. Quitting the qjackctl.exe will now close the jack server.
Starting the jack server with another audio device installed on the machine (like an ASIO card) can now be done directly in qjackctl.
A ">" button at the right of the interface button allows to list the name of all available devices, driven either by "MME", "Direct Sound", or "ASIO".
A ">" button at the right of the interface button allows to list the name of all available devices, driven either by "MME", "DirectSound", or "ASIO".
Alternatively using the following command allows to display the names of available devices:
- jackd -d portaudio -l to display the entire list of available audio devices. (jackd -d portaudio -h will display all portaudio driver features)
......
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