diff --git a/ChangeLog b/ChangeLog index c2361d74..e23d51ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,19 @@ Michael Voigt Jackdmp changes log --------------------------- +2009-03-05 Stephane Letz + + * Support for BIG_ENDIAN machines in NetJack2 for transport data. + * Add auto_connect parameter in netmanager and netadapter. + +2009-03-03 Stephane Letz + + * More robust profiling tools when clients come and go. + +2009-03-01 Stephane Letz + + * Raise default port number to 1024. + 2009-02-27 Stephane Letz * Improve generated gnuplot files for adapting code. diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp index 06f7e0f1..6961a06f 100644 --- a/common/JackAudioAdapter.cpp +++ b/common/JackAudioAdapter.cpp @@ -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(); diff --git a/common/JackAudioAdapter.h b/common/JackAudioAdapter.h index 1a15c2a0..0eb93eed 100644 --- a/common/JackAudioAdapter.h +++ b/common/JackAudioAdapter.h @@ -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(); diff --git a/common/JackConstants.h b/common/JackConstants.h index ce785601..d2af693e 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -34,7 +34,7 @@ #define JACK_CLIENT_NAME_SIZE 64 #ifndef PORT_NUM -#define PORT_NUM 512 +#define PORT_NUM 1024 #endif #define DRIVER_PORT_NUM 256 diff --git a/common/JackEngineProfiling.cpp b/common/JackEngineProfiling.cpp index f9f29727..a0c81afe 100644 --- a/common/JackEngineProfiling.cpp +++ b/common/JackEngineProfiling.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -JackEngineProfiling::JackEngineProfiling():fAudioCycle(0) +JackEngineProfiling::JackEngineProfiling():fAudioCycle(0),fMeasuredClient(0) { jack_info("Engine profiling activated, beware %ld MBytes are needed to record profiling points...", sizeof(fProfileTable) / (1024 * 1024)); @@ -36,66 +36,59 @@ JackEngineProfiling::JackEngineProfiling():fAudioCycle(0) JackEngineProfiling::~JackEngineProfiling() { - // Window monitoring - int max_client = 0; - char buffer[1024]; - char* nameTable[CLIENT_NUM]; FILE* file = fopen("JackEngineProfiling.log", "w"); + char buffer[1024]; jack_info("Write server and clients timing data..."); if (file == NULL) { jack_error("JackEngineProfiling::Save cannot open JackEngineProfiling.log file"); } else { - + + // For each measured point for (int i = 2; i < TIME_POINTS; i++) { - bool header = true; - bool printed = false; - int count = 0; - for (int j = REAL_REFNUM; j < CLIENT_NUM; j++) { - if (fProfileTable[i].fClientTable[j].fRefNum > 0) { - long d1 = long(fProfileTable[i - 1].fCurCycleBegin - fProfileTable[i - 2].fCurCycleBegin); - long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin); - if (d1 > 0 && fProfileTable[i].fClientTable[j].fStatus != NotTriggered) { // Valid cycle - count++; - nameTable[count] = fNameTable[fProfileTable[i].fClientTable[j].fRefNum]; - - // driver delta and end cycle - if (header) { - fprintf(file, "%ld \t %ld \t", d1, d2); - header = false; - } - long d5 = long(fProfileTable[i].fClientTable[j].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin); - long d6 = long(fProfileTable[i].fClientTable[j].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin); - long d7 = long(fProfileTable[i].fClientTable[j].fFinishedAt - fProfileTable[i - 1].fCurCycleBegin); - - // ref, signal, start, end, scheduling, duration, status - fprintf(file, "%d \t %ld \t %ld \t %ld \t %ld \t %ld \t %d \t", - fProfileTable[i].fClientTable[j].fRefNum, - ((d5 > 0) ? d5 : 0), - ((d6 > 0) ? d6 : 0), - ((d7 > 0) ? d7 : 0), - ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0), - ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0), - fProfileTable[i].fClientTable[j].fStatus); - printed = true; - } - } - max_client = (count > max_client) ? count : max_client; - } - if (printed) { - fprintf(file, "\n"); - } else if (fProfileTable[i].fAudioCycle > 0) { // Driver timing only - long d1 = long(fProfileTable[i].fCurCycleBegin - fProfileTable[i - 1].fCurCycleBegin); - long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin); - if (d1 > 0) { // Valid cycle - fprintf(file, "%ld \t %ld \n", d1, d2); + + // Driver timing values + long d1 = long(fProfileTable[i].fCurCycleBegin - fProfileTable[i - 1].fCurCycleBegin); + long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin); + + if (d1 <= 0 || fProfileTable[i].fAudioCycle <= 0) + continue; // Skip non valid cycles + + // Print driver delta and end cycle + fprintf(file, "%ld \t %ld \t", d1, d2); + + // For each measured client + for (unsigned int j = 0; j < fMeasuredClient; j++) { + + int ref = fIntervalTable[j].fRefNum; + + // Is valid client cycle + if (fProfileTable[i].fClientTable[ref].fStatus != NotTriggered) { + + long d5 = long(fProfileTable[i].fClientTable[ref].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin); + long d6 = long(fProfileTable[i].fClientTable[ref].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin); + long d7 = long(fProfileTable[i].fClientTable[ref].fFinishedAt - fProfileTable[i - 1].fCurCycleBegin); + + // Print ref, signal, start, end, scheduling, duration, status + fprintf(file, "%d \t %ld \t %ld \t %ld \t %ld \t %ld \t %d \t", + ref, + ((d5 > 0) ? d5 : 0), + ((d6 > 0) ? d6 : 0), + ((d7 > 0) ? d7 : 0), + ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0), + ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0), + fProfileTable[i].fClientTable[ref].fStatus); + } else { // Print tabs + fprintf(file, "\t \t \t \t \t \t \t"); } } + + // Terminate line + fprintf(file, "\n"); } - fclose(file); } - + // Driver period file = fopen("Timing1.plot", "w"); @@ -145,9 +138,9 @@ JackEngineProfiling::~JackEngineProfiling() fclose(file); } - + // Clients end date - if (max_client > 0) { + if (fMeasuredClient > 0) { file = fopen("Timing3.plot", "w"); if (file == NULL) { jack_error("JackEngineProfiling::Save cannot open Timing3.log file"); @@ -158,21 +151,20 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set title \"Clients end date\"\n"); fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { + for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { - if ((i + 1) == max_client) { + if (i + 1 == fMeasuredClient) { // Last client sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines", - ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } else { sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", - ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } - } else if ((i + 1) == max_client) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + } else if (i + 1 == fMeasuredClient) { // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, fIntervalTable[i].fName); } fprintf(file, buffer); } @@ -187,28 +179,29 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { + for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { - if ((i + 1) == max_client) { + if ((i + 1) == fMeasuredClient) { // Last client sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines", - ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } else { sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", - ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } - } else if ((i + 1) == max_client) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , nameTable[(i + 1)]); + } else if ((i + 1) == fMeasuredClient) { // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , fIntervalTable[i].fName); } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, fIntervalTable[i].fName); } fprintf(file, buffer); } + fclose(file); } } - + // Clients scheduling - if (max_client > 0) { + if (fMeasuredClient > 0) { file = fopen("Timing4.plot", "w"); if (file == NULL) { @@ -221,11 +214,11 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { - if ((i + 1) == max_client) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), nameTable[(i + 1)]); + for (unsigned int i = 0; i < fMeasuredClient; i++) { + if ((i + 1) == fMeasuredClient) // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), fIntervalTable[i].fName); else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), fIntervalTable[i].fName); fprintf(file, buffer); } @@ -239,11 +232,11 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { - if ((i + 1) == max_client) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), nameTable[(i + 1)]); + for (unsigned int i = 0; i < fMeasuredClient; i++) { + if ((i + 1) == fMeasuredClient) // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), fIntervalTable[i].fName); else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), fIntervalTable[i].fName); fprintf(file, buffer); } fclose(file); @@ -251,7 +244,7 @@ JackEngineProfiling::~JackEngineProfiling() } // Clients duration - if (max_client > 0) { + if (fMeasuredClient > 0) { file = fopen("Timing5.plot", "w"); if (file == NULL) { @@ -264,11 +257,11 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { - if ((i + 1) == max_client) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, nameTable[(i + 1)]); + for (unsigned int i = 0; i < fMeasuredClient; i++) { + if ((i + 1) == fMeasuredClient) // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, fIntervalTable[i].fName); else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, fIntervalTable[i].fName); fprintf(file, buffer); } @@ -282,11 +275,11 @@ JackEngineProfiling::~JackEngineProfiling() fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"usec\"\n"); fprintf(file, "plot "); - for (int i = 0; i < max_client; i++) { - if ((i + 1) == max_client) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, nameTable[(i + 1)]); + for (unsigned int i = 0; i < fMeasuredClient; i++) { + if ((i + 1) == fMeasuredClient) // Last client + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, fIntervalTable[i].fName); else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, nameTable[(i + 1)]); + sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, fIntervalTable[i].fName); fprintf(file, buffer); } fclose(file); @@ -294,6 +287,17 @@ JackEngineProfiling::~JackEngineProfiling() } } +bool JackEngineProfiling::CheckClient(const char* name, int cur_point) +{ + for (int i = 0; i < MEASURED_CLIENTS; i++) { + if (strcmp(fIntervalTable[i].fName, name) == 0) { + fIntervalTable[i].fEndInterval = cur_point; + return true; + } + } + return false; +} + void JackEngineProfiling::Profile(JackClientInterface** table, JackGraphManager* manager, jack_time_t period_usecs, @@ -311,8 +315,16 @@ void JackEngineProfiling::Profile(JackClientInterface** table, for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; JackClientTiming* timing = manager->GetClientTiming(i); - if (client && client->GetClientControl()->fActive) { - strcpy(fNameTable[i], client->GetClientControl()->fName); + if (client && client->GetClientControl()->fActive && client->GetClientControl()->fCallback[kRealTimeCallback]) { + + if (!CheckClient(client->GetClientControl()->fName, fAudioCycle)) { + // Keep new measured client + fIntervalTable[fMeasuredClient].fRefNum = i; + strcpy(fIntervalTable[fMeasuredClient].fName, client->GetClientControl()->fName); + fIntervalTable[fMeasuredClient].fBeginInterval = fAudioCycle; + fIntervalTable[fMeasuredClient].fEndInterval = fAudioCycle; + fMeasuredClient++; + } fProfileTable[fAudioCycle].fClientTable[i].fRefNum = i; fProfileTable[fAudioCycle].fClientTable[i].fSignaledAt = timing->fSignaledAt; fProfileTable[fAudioCycle].fClientTable[i].fAwakeAt = timing->fAwakeAt; diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h index 43888e76..71abca1b 100644 --- a/common/JackEngineProfiling.h +++ b/common/JackEngineProfiling.h @@ -31,6 +31,7 @@ namespace Jack #define TIME_POINTS 250000 #define FAILURE_TIME_POINTS 10000 #define FAILURE_WINDOW 10 +#define MEASURED_CLIENTS 32 /*! \brief Timing stucture for a client. @@ -43,6 +44,32 @@ struct JackTimingMeasureClient jack_time_t fAwakeAt; jack_time_t fFinishedAt; jack_client_state_t fStatus; + + JackTimingMeasureClient() + :fRefNum(-1), + fSignaledAt(0), + fAwakeAt(0), + fFinishedAt(0), + fStatus((jack_client_state_t)0) + {} +}; + +/*! +\brief Timing interval in the global table for a given client +*/ + +struct JackTimingClientInterval +{ + int fRefNum; + char fName[JACK_CLIENT_NAME_SIZE + 1]; + int fBeginInterval; + int fEndInterval; + + JackTimingClientInterval() + :fRefNum(-1), + fBeginInterval(-1), + fEndInterval(-1) + {} }; /*! @@ -56,6 +83,13 @@ struct JackTimingMeasure jack_time_t fCurCycleBegin; jack_time_t fPrevCycleEnd; JackTimingMeasureClient fClientTable[CLIENT_NUM]; + + JackTimingMeasure() + :fAudioCycle(0), + fPeriodUsecs(0), + fCurCycleBegin(0), + fPrevCycleEnd(0) + {} }; /*! @@ -71,9 +105,13 @@ class SERVER_EXPORT JackEngineProfiling private: JackTimingMeasure fProfileTable[TIME_POINTS]; - char fNameTable[CLIENT_NUM][JACK_CLIENT_NAME_SIZE + 1]; + JackTimingClientInterval fIntervalTable[MEASURED_CLIENTS]; + unsigned int fAudioCycle; - + unsigned int fMeasuredClient; + + bool CheckClient(const char* name, int cur_point); + public: JackEngineProfiling(); diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 19bfdc8a..6d9b1c1b 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -354,9 +354,8 @@ struct JackNetExtMaster : public JackNetMasterInterface { if (SyncRecv() == SOCKET_ERROR) return 0; - if (DecodeSyncPacket() < 0) - return 0; - + DecodeSyncPacket(); + return DataRecv(); } @@ -373,9 +372,8 @@ struct JackNetExtMaster : public JackNetMasterInterface { fNetMidiCaptureBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_output_buffer)[port_index]); } - if (EncodeSyncPacket() < 0) - return 0; - + EncodeSyncPacket(); + if (SyncSend() == SOCKET_ERROR) return SOCKET_ERROR; @@ -383,15 +381,11 @@ struct JackNetExtMaster : public JackNetMasterInterface { } // Transport - int EncodeTransportData() - { - return 0; - } + void EncodeTransportData() + {} - int DecodeTransportData() - { - return 0; - } + void DecodeTransportData() + {} }; @@ -574,15 +568,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf } // Transport - int EncodeTransportData() - { - return 0; - } + void EncodeTransportData() + {} - int DecodeTransportData() - { - return 0; - } + void DecodeTransportData() + {} bool Init() { @@ -624,17 +614,15 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf if (SyncRecv() == SOCKET_ERROR) return 0; - if (DecodeSyncPacket() < 0) - return 0; - + DecodeSyncPacket(); + return DataRecv(); } int Write() { - if (EncodeSyncPacket() < 0) - return 0; - + EncodeSyncPacket(); + if (SyncSend() == SOCKET_ERROR) return SOCKET_ERROR; diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index a5b85b63..2ce50cbf 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -260,7 +260,7 @@ namespace Jack } //transport--------------------------------------------------------------------------- - int JackNetAdapter::DecodeTransportData() + void JackNetAdapter::DecodeTransportData() { //TODO : we need here to get the actual timebase master to eventually release it from its duty (see JackNetDriver) @@ -288,11 +288,9 @@ namespace Jack break; } } - - return 0; } - int JackNetAdapter::EncodeTransportData() + void JackNetAdapter::EncodeTransportData() { //is there a timebase master change ? int refnum = -1; @@ -326,8 +324,6 @@ namespace Jack if ( fReturnTransportData.fNewState ) jack_info ( "Sending transport state '%s'.", GetTransportState ( fReturnTransportData.fState ) ); fLastTransportState = fReturnTransportData.fState; - - return 0; } //read/write operations--------------------------------------------------------------- @@ -338,17 +334,14 @@ namespace Jack if ( SyncRecv() == SOCKET_ERROR ) return 0; - if ( DecodeSyncPacket() < 0 ) - return 0; - + DecodeSyncPacket(); return DataRecv(); } int JackNetAdapter::Write() { - if ( EncodeSyncPacket() < 0 ) - return 0; - + EncodeSyncPacket(); + if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; @@ -358,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------------------------------------------------------------------------------ @@ -420,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; @@ -494,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; } @@ -508,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 ) diff --git a/common/JackNetAdapter.h b/common/JackNetAdapter.h index 7f120e28..f6b7675b 100644 --- a/common/JackNetAdapter.h +++ b/common/JackNetAdapter.h @@ -48,8 +48,8 @@ namespace Jack JackThread fThread; //transport - int EncodeTransportData(); - int DecodeTransportData(); + void EncodeTransportData(); + void DecodeTransportData(); public: diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 7b17ac90..d34c7db5 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -381,7 +381,7 @@ namespace Jack } //transport--------------------------------------------------------------------------- - int JackNetDriver::DecodeTransportData() + void JackNetDriver::DecodeTransportData() { //is there a new timebase master on the net master ? // - release timebase master only if it's a non-conditional request @@ -397,9 +397,10 @@ namespace Jack jack_info ( "The NetMaster is now the new timebase master." ); } - //is there a tranport state change to handle ? + //is there a transport state change to handle ? if ( fSendTransportData.fNewState && ( fSendTransportData.fState != fEngineControl->fTransport.GetState() ) ) { + switch ( fSendTransportData.fState ) { case JackTransportStopped : @@ -419,11 +420,9 @@ namespace Jack break; } } - - return 0; } - int JackNetDriver::EncodeTransportData() + void JackNetDriver::EncodeTransportData() { //is there a timebase master change ? int refnum; @@ -457,8 +456,6 @@ namespace Jack if ( fReturnTransportData.fNewState ) jack_info ( "Sending '%s'.", GetTransportState ( fReturnTransportData.fState ) ); fLastTransportState = fReturnTransportData.fState; - - return 0; } //driver processes-------------------------------------------------------------------- @@ -486,9 +483,8 @@ namespace Jack //decode sync //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified - if ( DecodeSyncPacket() < 0 ) - return 0; - + DecodeSyncPacket(); + #ifdef JACK_MONITOR fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif @@ -519,9 +515,8 @@ namespace Jack #endif //sync - if ( EncodeSyncPacket() < 0 ) - return 0; - + EncodeSyncPacket(); + //send sync if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index af432084..058489a1 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -57,8 +57,8 @@ namespace Jack int FreePorts(); //transport - int EncodeTransportData(); - int DecodeTransportData(); + void EncodeTransportData(); + void DecodeTransportData(); JackMidiBuffer* GetMidiInputBuffer ( int port_index ); JackMidiBuffer* GetMidiOutputBuffer ( int port_index ); diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 299c4588..27495c18 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -565,39 +565,35 @@ namespace Jack return rx_bytes; } - int JackNetMasterInterface::EncodeSyncPacket() + void JackNetMasterInterface::EncodeSyncPacket() { //this method contains every step of sync packet informations coding //first of all, reset sync packet memset ( fTxData, 0, fPayloadSize ); //then, first step : transport - if ( fParams.fTransportSync ) - { - if ( EncodeTransportData() < 0 ) - return -1; + if (fParams.fTransportSync) { + EncodeTransportData(); + TransportDataHToN( &fSendTransportData, &fSendTransportData); //copy to TxBuffer memcpy ( fTxData, &fSendTransportData, sizeof ( net_transport_data_t ) ); } //then others (freewheel etc.) //... - return 0; } - int JackNetMasterInterface::DecodeSyncPacket() + void JackNetMasterInterface::DecodeSyncPacket() { //this method contains every step of sync packet informations decoding process //first : transport - if ( fParams.fTransportSync ) - { + if (fParams.fTransportSync) { //copy received transport data to transport data structure memcpy ( &fReturnTransportData, fRxData, sizeof ( net_transport_data_t ) ); - if ( DecodeTransportData() < 0 ) - return -1; + TransportDataNToH( &fReturnTransportData, &fReturnTransportData); + DecodeTransportData(); } //then others //... - return 0; } // JackNetSlaveInterface ************************************************************************************************ @@ -955,38 +951,34 @@ namespace Jack } //network sync------------------------------------------------------------------------ - int JackNetSlaveInterface::DecodeSyncPacket() - { - //this method contains every step of sync packet informations decoding process - //first : transport - if ( fParams.fTransportSync ) - { - //copy received transport data to transport data structure - memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) ); - if ( DecodeTransportData() < 0 ) - return -1; - } - //then others - //... - return 0; - } - - int JackNetSlaveInterface::EncodeSyncPacket() + void JackNetSlaveInterface::EncodeSyncPacket() { //this method contains every step of sync packet informations coding //first of all, reset sync packet memset ( fTxData, 0, fPayloadSize ); //then first step : transport - if ( fParams.fTransportSync ) - { - if ( EncodeTransportData() < 0 ) - return -1; + if (fParams.fTransportSync) { + EncodeTransportData(); + TransportDataHToN( &fReturnTransportData, &fReturnTransportData); //copy to TxBuffer memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) ); } //then others //... - return 0; + } + + void JackNetSlaveInterface::DecodeSyncPacket() + { + //this method contains every step of sync packet informations decoding process + //first : transport + if (fParams.fTransportSync) { + //copy received transport data to transport data structure + memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) ); + TransportDataNToH( &fSendTransportData, &fSendTransportData); + DecodeTransportData(); + } + //then others + //... } } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 9d2c95c2..c655a3b0 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -73,12 +73,12 @@ namespace Jack virtual bool Init() = 0; //transport - virtual int EncodeTransportData() = 0; - virtual int DecodeTransportData() = 0; + virtual void EncodeTransportData() = 0; + virtual void DecodeTransportData() = 0; //sync packet - virtual int EncodeSyncPacket() = 0; - virtual int DecodeSyncPacket() = 0; + virtual void EncodeSyncPacket() = 0; + virtual void DecodeSyncPacket() = 0; virtual int SyncRecv() = 0; virtual int SyncSend() = 0; @@ -119,8 +119,8 @@ namespace Jack int DataSend(); //sync packet - int EncodeSyncPacket(); - int DecodeSyncPacket(); + void EncodeSyncPacket(); + void DecodeSyncPacket(); int Send ( size_t size, int flags ); int Recv ( size_t size, int flags ); @@ -163,8 +163,8 @@ namespace Jack int DataSend(); //sync packet - int EncodeSyncPacket(); - int DecodeSyncPacket(); + void EncodeSyncPacket(); + void DecodeSyncPacket(); int Recv ( size_t size, int flags ); int Send ( size_t size, int flags ); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index b935d252..5f723b99 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -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() { @@ -245,7 +266,7 @@ namespace Jack } //transport--------------------------------------------------------------------------- - int JackNetMaster::EncodeTransportData() + void JackNetMaster::EncodeTransportData() { //is there a new timebase master ? //TODO : check if any timebase callback has been called (and if it's conditional or not) and set correct value... @@ -260,11 +281,9 @@ namespace Jack if ( fSendTransportData.fNewState ) jack_info ( "Sending '%s' to '%s'.", GetTransportState ( fSendTransportData.fState ), fParams.fName ); fLastTransportState = fSendTransportData.fState; + } - return 0; - } - - int JackNetMaster::DecodeTransportData() + void JackNetMaster::DecodeTransportData() { //is there timebase master change ? if ( fReturnTransportData.fTimebaseMaster != NO_CHANGE ) @@ -322,7 +341,6 @@ namespace Jack break; } } - return 0; } void JackNetMaster::SetTimebaseCallback ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg ) @@ -385,9 +403,8 @@ namespace Jack if (IsSynched()) { // only send if connection is "synched" //encode the first packet - if ( EncodeSyncPacket() < 0 ) - return 0; - + EncodeSyncPacket(); + //send sync if ( SyncSend() == SOCKET_ERROR ) return SOCKET_ERROR; @@ -418,9 +435,8 @@ namespace Jack #endif //decode sync - if ( DecodeSyncPacket() < 0 ) - return 0; - + DecodeSyncPacket(); + //receive data res = DataRecv(); if ( ( res == 0 ) || ( res == SOCKET_ERROR ) ) @@ -444,6 +460,7 @@ namespace Jack fSocket.SetPort ( DEFAULT_PORT ); fGlobalID = 0; fRunning = true; + fAutoConnect = false; const JSList* node; const jack_driver_param_t* param; @@ -458,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; } } @@ -618,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; @@ -679,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; @@ -697,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; } diff --git a/common/JackNetManager.h b/common/JackNetManager.h index 9d748d34..6e05759f 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -53,29 +53,28 @@ namespace Jack //sync and transport int fLastTransportState; - net_transport_data_t fSendTransportData; - net_transport_data_t fReturnTransportData; - + //monitoring #ifdef JACK_MONITOR jack_time_t fPeriodUsecs; JackGnuPlotMonitor* fNetTimeMon; #endif - bool Init(); + bool Init(bool auto_connect); int AllocPorts(); void FreePorts(); void Exit(); //transport - int EncodeTransportData(); - int DecodeTransportData(); + void EncodeTransportData(); + void DecodeTransportData(); 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(); @@ -103,6 +102,7 @@ namespace Jack master_list_t fMasterList; uint32_t fGlobalID; bool fRunning; + bool fAutoConnect; void Run(); JackNetMaster* MasterInit ( session_params_t& params ); @@ -112,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(); }; } diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 50010287..b35af904 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -377,6 +377,15 @@ namespace Jack jack_info ( "**********************************************" ); } + SERVER_EXPORT void NetTransportDataDisplay ( net_transport_data_t* data ) + { + jack_info ( "********************Network Transport********************" ); + jack_info ( "Transport new state : %u", data->fNewState ); + jack_info ( "Transport timebase master : %u", data->fTimebaseMaster ); + jack_info ( "Transport cycle state : %u", data->fState ); + jack_info ( "**********************************************" ); + } + SERVER_EXPORT void MidiBufferHToN ( JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer ) { dst_buffer->magic = htonl(src_buffer->magic); @@ -398,6 +407,56 @@ namespace Jack dst_buffer->lost_events = ntohl(src_buffer->lost_events); dst_buffer->mix_index = ntohl(src_buffer->mix_index); } + + SERVER_EXPORT void TransportDataHToN ( net_transport_data_t* src_params, net_transport_data_t* dst_params ) + { + dst_params->fNewState = htonl(src_params->fNewState); + dst_params->fTimebaseMaster = htonl(src_params->fTimebaseMaster); + dst_params->fState = htonl(src_params->fState); + dst_params->fPosition.unique_1 = htonll(src_params->fPosition.unique_1); + dst_params->fPosition.usecs = htonl(src_params->fPosition.usecs); + dst_params->fPosition.frame_rate = htonl(src_params->fPosition.frame_rate); + dst_params->fPosition.frame = htonl(src_params->fPosition.frame); + dst_params->fPosition.bar = htonl(src_params->fPosition.bar); + dst_params->fPosition.beat = htonl(src_params->fPosition.beat); + dst_params->fPosition.tick = htonl(src_params->fPosition.tick); + dst_params->fPosition.bar_start_tick = htonll((uint64_t)src_params->fPosition.bar_start_tick); + dst_params->fPosition.beats_per_bar = htonl(src_params->fPosition.beats_per_bar); + dst_params->fPosition.beat_type = htonl(src_params->fPosition.beat_type); + dst_params->fPosition.ticks_per_beat = htonll((uint64_t)src_params->fPosition.ticks_per_beat); + dst_params->fPosition.beats_per_minute = htonll((uint64_t)src_params->fPosition.beats_per_minute); + dst_params->fPosition.frame_time = htonll((uint64_t)src_params->fPosition.frame_time); + dst_params->fPosition.next_time = htonll((uint64_t)src_params->fPosition.next_time); + dst_params->fPosition.bbt_offset = htonl(src_params->fPosition.bbt_offset); + dst_params->fPosition.audio_frames_per_video_frame = htonl(src_params->fPosition.audio_frames_per_video_frame); + dst_params->fPosition.video_offset = htonl(src_params->fPosition.video_offset); + dst_params->fPosition.unique_2 = htonll(src_params->fPosition.unique_2); + } + + SERVER_EXPORT void TransportDataNToH ( net_transport_data_t* src_params, net_transport_data_t* dst_params ) + { + dst_params->fNewState = ntohl(src_params->fNewState); + dst_params->fTimebaseMaster = ntohl(src_params->fTimebaseMaster); + dst_params->fState = ntohl(src_params->fState); + dst_params->fPosition.unique_1 = ntohll(src_params->fPosition.unique_1); + dst_params->fPosition.usecs = ntohl(src_params->fPosition.usecs); + dst_params->fPosition.frame_rate = ntohl(src_params->fPosition.frame_rate); + dst_params->fPosition.frame = ntohl(src_params->fPosition.frame); + dst_params->fPosition.bar = ntohl(src_params->fPosition.bar); + dst_params->fPosition.beat = ntohl(src_params->fPosition.beat); + dst_params->fPosition.tick = ntohl(src_params->fPosition.tick); + dst_params->fPosition.bar_start_tick = ntohll((uint64_t)src_params->fPosition.bar_start_tick); + dst_params->fPosition.beats_per_bar = ntohl(src_params->fPosition.beats_per_bar); + dst_params->fPosition.beat_type = ntohl(src_params->fPosition.beat_type); + dst_params->fPosition.ticks_per_beat = ntohll((uint64_t)src_params->fPosition.ticks_per_beat); + dst_params->fPosition.beats_per_minute = ntohll((uint64_t)src_params->fPosition.beats_per_minute); + dst_params->fPosition.frame_time = ntohll((uint64_t)src_params->fPosition.frame_time); + dst_params->fPosition.next_time = ntohll((uint64_t)src_params->fPosition.next_time); + dst_params->fPosition.bbt_offset = ntohl(src_params->fPosition.bbt_offset); + dst_params->fPosition.audio_frames_per_video_frame = ntohl(src_params->fPosition.audio_frames_per_video_frame); + dst_params->fPosition.video_offset = ntohl(src_params->fPosition.video_offset); + dst_params->fPosition.unique_2 = ntohll(src_params->fPosition.unique_2); + } // Utility ******************************************************************************************************* diff --git a/common/JackNetTool.h b/common/JackNetTool.h index e7c0e8d6..cb6f494f 100644 --- a/common/JackNetTool.h +++ b/common/JackNetTool.h @@ -29,6 +29,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. using namespace std; +#ifndef htonll +#ifdef __BIG_ENDIAN__ +#define htonll(x) (x) +#define ntohll(x) (x) +#else +#define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl(x >> 32)) +#define ntohll(x) ((((uint64_t)ntohl(x)) << 32) + ntohl(x >> 32)) +#endif +#endif + namespace Jack { typedef struct _session_params session_params_t; @@ -282,6 +292,8 @@ namespace Jack SERVER_EXPORT void PacketHeaderNToH ( packet_header_t* src_header, packet_header_t* dst_header ); SERVER_EXPORT void MidiBufferHToN ( JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer ); SERVER_EXPORT void MidiBufferNToH ( JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer ); + SERVER_EXPORT void TransportDataHToN ( net_transport_data_t* src_params, net_transport_data_t* dst_params ); + SERVER_EXPORT void TransportDataNToH ( net_transport_data_t* src_params, net_transport_data_t* dst_params ); //display session parameters SERVER_EXPORT void SessionParamsDisplay ( session_params_t* params ); //display packet header @@ -292,4 +304,5 @@ namespace Jack SERVER_EXPORT int SetPacketType ( session_params_t* params, sync_packet_type_t packet_type ); //transport utility SERVER_EXPORT const char* GetTransportState ( int transport_state ); + SERVER_EXPORT void NetTransportDataDisplay ( net_transport_data_t* data ); } diff --git a/common/JackProfiler.cpp b/common/JackProfiler.cpp index f4fa904b..b74abc13 100644 --- a/common/JackProfiler.cpp +++ b/common/JackProfiler.cpp @@ -218,7 +218,7 @@ extern "C" strcpy(desc->params[i].name, "cpu-load"); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = FALSE; strcpy(desc->params[i].short_desc, "Show DSP CPU load"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -226,7 +226,7 @@ extern "C" strcpy(desc->params[i].name, "driver-period"); desc->params[i].character = 'p'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = FALSE; strcpy(desc->params[i].short_desc, "Show driver period"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -234,7 +234,7 @@ extern "C" strcpy(desc->params[i].name, "driver-end-time"); desc->params[i].character = 'e'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = FALSE; strcpy(desc->params[i].short_desc, "Show driver end time"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index f70aaaac..46a2871a 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -223,34 +223,7 @@ void JackOSSDriver::DisplayDeviceInfo() if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); } } - /* - TODO - - ai_in.dev = fInFD; - jack_log("JackOSSDriver::DisplayDeviceInfo input fInFD = %d", ai_in.dev); - if (ioctl(fInFD, SNDCTL_AUDIOINFO, &ai_in) != -1) { - jack_info("Using audio engine %d = %s for input", ai_in.dev, ai_in.name); - if (ai_in.iformats & AFMT_S24_NE) - jack_info("Available input format : AFMT_S24_NE"); - if (ai_in.iformats & AFMT_S16_NE) - jack_info("Available input format : AFMT_S16_NE"); - if (ai_in.iformats & AFMT_S32_NE) - jack_info("Available input format : AFMT_S32_NE"); - } - - ai_out.dev = fOutFD; - jack_log("JackOSSDriver::DisplayDeviceInfo output fOutFD = %d", ai_out.dev); - if (ioctl(fOutFD, SNDCTL_AUDIOINFO, &ai_out) != -1) { - jack_info("Using audio engine %d = %s for output", ai_out.dev, ai_out.name); - if (ai_out.oformats & AFMT_S24_NE) - jack_info("Available output format : AFMT_S24_NE"); - if (ai_out.oformats & AFMT_S16_NE) - jack_info("Available output format : AFMT_S16_NE"); - if (ai_out.oformats & AFMT_S32_NE) - jack_info("Available output format : AFMT_S32_NE"); - } - */ - + if (ai_in.rate_source != ai_out.rate_source) { jack_info("Warning : input and output are not necessarily driven by the same clock!"); } @@ -541,7 +514,7 @@ int JackOSSDriver::OpenAux() // In duplex mode, check that input and output use the same buffer size /* - // 10/02/09 : desactivated for now, needs more check (only needed when *same* device is used for input and output ??) + 10/02/09 : desactivated for now, needs more check (only needed when *same* device is used for input and output ??) if ((fRWMode & kRead) && (fRWMode & kWrite) && (fInputBufferSize != fOutputBufferSize)) { jack_error("JackOSSDriver::OpenAux input and output buffer size are not the same!!"); @@ -583,32 +556,6 @@ int JackOSSDriver::Read() } ssize_t count; -/* - // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html - if (fFirstCycle) { - - fFirstCycle = false; - memset(fOutputBuffer, 0, fOutputBufferSize); - - // Prefill ouput buffer - for (int i = 0; i < fNperiods; i++) { - count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); - if (count < fOutputBufferSize) { - jack_error("JackOSSDriver::Write error bytes written = %ld", count); - return -1; - } - } - - int delay; - if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { - jack_error("JackOSSDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); - return -1; - } - - delay /= fSampleSize * fPlaybackChannels; - jack_info("JackOSSDriver::Write output latency frames = %ld", delay); - } -*/ #ifdef JACK_MONITOR gCycleTable.fTable[gCycleCount].fBeforeRead = GetMicroSeconds(); diff --git a/windows/README b/windows/README index ab94a3a3..f7cbebb7 100644 --- a/windows/README +++ b/windows/README @@ -1,5 +1,5 @@ ------------------------------- -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'. diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index 437b8fd0..ee1c96ca 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -66,8 +66,8 @@ <_>..\Release\bin\jack_metro.exeinstovernewer0 <_>..\Release\bin\jack_unload.exeinstovernewer0 <_>..\Release\bin\jackd.exeinstovernewer0 -<_>..\Release\bin\libjack.dllinstovernewer0 -<_>..\Release\bin\libjackserver.dllinstovernewer0 +<_>..\Release\bin\libjack.dllsysovernewer0 +<_>..\Release\bin\libjackserver.dllsysovernewer0 <_>..\Release\bin\libsamplerate-0.dllinstovernewer0 <_>..\Release\bin\portaudio_x86.dllinstovernewer0 <_>..\Release\bin\jack\jack_net.dllinstjackovernewer0 diff --git a/windows/Setup/src/README b/windows/Setup/src/README index 589d874d..eef08432 100644 --- a/windows/Setup/src/README +++ b/windows/Setup/src/README @@ -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) diff --git a/wscript b/wscript index cb44a74a..c4d28c9e 100644 --- a/wscript +++ b/wscript @@ -65,9 +65,9 @@ def set_options(opt): opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation') opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') - opt.add_option('--ports', default=512, type="int", dest="ports", help='Maximum number of ports') + opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') - opt.add_option('--ports', default=512, type="int", dest="ports", help='Maximum number of ports') + opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') opt.sub_options('dbus') def configure(conf):